diff options
| author | David Härdeman | 2025-10-25 22:49:22 +0000 |
|---|---|---|
| committer | Álvaro Fernández Rojas | 2025-11-06 07:24:51 +0000 |
| commit | 4f20351c3713f42dd540922e88579ec61ca76d94 (patch) | |
| tree | f853903c3f5158d1ff2f0c6abb3805724ce290ee | |
| parent | 869e2231bbc93b5f3b7425d7214392b167d8b962 (diff) | |
| download | odhcpd-4f20351c3713f42dd540922e88579ec61ca76d94.tar.gz | |
odhcpd: remove the "filter_class" option
The "filter_class" option was first introduced as part of the effort to support
the Homenet Control Protocol (HNCP, RFC7368, RFC7788). At first it was
hardcoded to filter out the user class "HOMENET", and later it was made
configurable, but there appears to be no other use-cases than Homenet. There's
also legacy comments in the odhcpd code pointing at filtering out homenet user
classes (the comments are misleading since "filter_class" is not set by
default).
Homenet is effectively dead. The "hnetd" daemon last saw any code changes in
2018, doesn't compile with current versions of GCC, and was removed from
OpenWrt altogether in 2025 [1].
The OpenWrt wiki also notes [2] that HNCP is effectively dead, and that the
upstream website [3] is gone.
Searching for the Homenet Control Protocol mostly returns results pointing
either:
a) at the standards
b) at the OpenWrt/hnetd project
c) at various posts stating that it is dead
The IETF working group for Homenet is no more, and Éric Vyncke (Area Director
for the Internet Area of the IETF) mentioned wanting to avoid Homenet pitfalls
[4] (page 11) in the future of IPv6 autoconfig.
The current implementation is also contrary to the spirit of the RFCs
introducing the option (RFC3004 - DHCPv4; RFC8415, §21.15 - DHCPv6) where it is
described (example from RFC8415) as follows:
The information contained in the data area of this option is
contained in one or more opaque fields that represent the user class
or classes of which the client is a member. A server selects
configuration information for the client based on the classes
identified in this option. For example, the User Class option can be
used to configure all clients of people in the accounting department
with a different printer than clients of people in the marketing
department.
I.e., it's meant to be used in a manner similar to "tags" in dnsmasq.
Finally, the option has been undocumented for the whole existance of odhcpd.
So, remove this option.
[1] https://github.com/openwrt/routing/commit/85b868b3413a29da0bd6ecd3518c2d34a6ffb788
[2] https://openwrt.org/docs/guide-user/network/zeroconfig/hncp_configuration
[3] https://web.archive.org/web/20180831161552/http://homewrt.org/start
[4] https://ripe87.ripe.net/wp-content/uploads/presentations/102-20231130-RIPE-87-IPv6-from-IETF.pdf
Signed-off-by: David Härdeman <david@hardeman.nu>
Link: https://github.com/openwrt/odhcpd/pull/294
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | src/config.c | 8 | ||||
| -rw-r--r-- | src/dhcpv4.c | 10 | ||||
| -rw-r--r-- | src/dhcpv6.c | 7 | ||||
| -rw-r--r-- | src/odhcpd.h | 2 |
5 files changed, 0 insertions, 28 deletions
@@ -121,7 +121,6 @@ and may also receive information from ubus | ntp |list |`<local address>`| NTP servers to announce accepts IPv4 and IPv6 | | ra_management |string | - | TBD | | upstream |list | - | TBD | -| filter_class |string | - | TBD | | pd_manager |string | - | TBD | | pd_cer |string | - | TBD | | ra_advrouter |bool | - | TBD | diff --git a/src/config.c b/src/config.c index 070aeaa..aaf5652 100644 --- a/src/config.c +++ b/src/config.c @@ -104,7 +104,6 @@ enum { IFACE_ATTR_DNR, IFACE_ATTR_DNS_SERVICE, IFACE_ATTR_DOMAIN, - IFACE_ATTR_FILTER_CLASS, IFACE_ATTR_DHCPV4_FORCERECONF, IFACE_ATTR_DHCPV6_RAW, IFACE_ATTR_DHCPV6_ASSIGNALL, @@ -159,7 +158,6 @@ static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = { [IFACE_ATTR_DNR] = { .name = "dnr", .type = BLOBMSG_TYPE_ARRAY }, [IFACE_ATTR_DNS_SERVICE] = { .name = "dns_service", .type = BLOBMSG_TYPE_BOOL }, [IFACE_ATTR_DOMAIN] = { .name = "domain", .type = BLOBMSG_TYPE_ARRAY }, - [IFACE_ATTR_FILTER_CLASS] = { .name = "filter_class", .type = BLOBMSG_TYPE_STRING }, [IFACE_ATTR_DHCPV4_FORCERECONF] = { .name = "dhcpv4_forcereconf", .type = BLOBMSG_TYPE_BOOL }, [IFACE_ATTR_DHCPV6_RAW] = { .name = "dhcpv6_raw", .type = BLOBMSG_TYPE_STRING }, [IFACE_ATTR_DHCPV6_ASSIGNALL] = { .name ="dhcpv6_assignall", .type = BLOBMSG_TYPE_BOOL }, @@ -348,7 +346,6 @@ static void clean_interface(struct interface *iface) free(iface->dhcpv4_router); free(iface->dhcpv4_dns); free(iface->dhcpv6_raw); - free(iface->filter_class); free(iface->dhcpv4_ntp); free(iface->dhcpv6_ntp); free(iface->dhcpv6_sntp); @@ -1386,11 +1383,6 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr } } - if ((c = tb[IFACE_ATTR_FILTER_CLASS])) { - iface->filter_class = realloc(iface->filter_class, blobmsg_data_len(c) + 1); - memcpy(iface->filter_class, blobmsg_get_string(c), blobmsg_data_len(c) + 1); - } - if ((c = tb[IFACE_ATTR_DHCPV4_FORCERECONF])) iface->dhcpv4_forcereconf = blobmsg_get_bool(c); diff --git a/src/dhcpv4.c b/src/dhcpv4.c index d5177c6..b64b1c3 100644 --- a/src/dhcpv4.c +++ b/src/dhcpv4.c @@ -927,16 +927,6 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len, req_opts_len = opt->len; } break; - case DHCPV4_OPT_USER_CLASS: - if (iface->filter_class) { - uint8_t *c = opt->data, *cend = &opt->data[opt->len]; - for (; c < cend && &c[*c] < cend; c = &c[1 + *c]) { - size_t elen = strlen(iface->filter_class); - if (*c == elen && !memcmp(&c[1], iface->filter_class, elen)) - return; // Ignore from homenet - } - } - break; case DHCPV4_OPT_LEASETIME: if (opt->len == 4) { memcpy(&req_leasetime, opt->data, 4); diff --git a/src/dhcpv6.c b/src/dhcpv6.c index ab55ff6..8b6cf6b 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -680,13 +680,6 @@ static void handle_client_request(void *addr, void *data, size_t len, if (olen != ntohs(dest.serverid_length) || memcmp(odata, &dest.serverid_buf, olen)) return; /* Not for us */ - } else if (iface->filter_class && otype == DHCPV6_OPT_USER_CLASS) { - uint8_t *c = odata, *cend = &odata[olen]; - for (; &c[2] <= cend && &c[2 + (c[0] << 8) + c[1]] <= cend; c = &c[2 + (c[0] << 8) + c[1]]) { - size_t elen = strlen(iface->filter_class); - if (((((size_t)c[0]) << 8) | c[1]) == elen && !memcmp(&c[2], iface->filter_class, elen)) - return; /* Ignore from homenet */ - } } else if (otype == DHCPV6_OPT_IA_PD) { #ifdef EXT_CER_ID iov[IOV_CERID].iov_len = sizeof(cerid); diff --git a/src/odhcpd.h b/src/odhcpd.h index 2682e44..01c8d0f 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -450,8 +450,6 @@ struct interface { char *upstream; size_t upstream_len; - char *filter_class; - // NTP struct in_addr *dhcpv4_ntp; size_t dhcpv4_ntp_cnt; |