odhcpd: add support for "ignore"
authorDavid Härdeman <[email protected]>
Sun, 9 Nov 2025 17:36:03 +0000 (18:36 +0100)
committerÁlvaro Fernández Rojas <[email protected]>
Tue, 11 Nov 2025 07:43:07 +0000 (08:43 +0100)
This is inspired by @Kasoo's work in PR #234, but slightly different.

The "ip" option now takes "ignore" as a value , but it'll only disable
DHCPv4 for a matching client.

Similarly, the "hostid" option now also understands "ignore", which will
disable DHCPv6 for a matching client.

Of course, this is all based on client-reported MAC
addresses/DUIDs/client IDs/etc, so it's not actually a security feature.

Closes: https://github.com/openwrt/odhcpd/pull/234
Closes: https://github.com/openwrt/odhcpd/issues/198
Signed-off-by: David Härdeman <[email protected]>
Link: https://github.com/openwrt/odhcpd/pull/303
Signed-off-by: Álvaro Fernández Rojas <[email protected]>
README.md
src/config.c
src/dhcpv4.c
src/dhcpv6-ia.c
src/odhcpd.h

index b81055507d7c328521fb174aecd6eca26b946dd1..1b468f9aba5d25eb868dffb5b72372beb6129027 100644 (file)
--- a/README.md
+++ b/README.md
@@ -128,10 +128,10 @@ and may also receive information from ubus
 ### Sections of type host (static leases)
 | Option               | Type  |Default| Description |
 | :-------------------- | :---- | :---- | :---------- |
-| ip                   |string |(none) | IPv4 host address |
+| ip                   |string |(none) | IPv4 host address or `ignore` to ignore any DHCPv4 request from this host |
 | mac                  |list\|string|(none) | HexadecimalMACaddress(es) |
 | duid                 |list\|string|(none) | Hexadecimal DUID(s), or DUID%IAID(s) |
-| hostid               |string |(none) | IPv6hostidentifier |
+| hostid               |string |(none) | IPv6 tokenised IID or `ignore` to ignore any DHCPv6 request from this host |
 | name                 |string |(none) | Hostname |
 | leasetime            |string |(none) | DHCPv4/v6leasetime |
 
index a1979a79222f165a2420e881fa5956d6edcdcbe1..6130b5f72400cd20e08eeb41ab485c6e8b8a1120 100644 (file)
@@ -670,15 +670,26 @@ int config_set_lease_cfg_from_blobmsg(struct blob_attr *ba)
                        goto err;
        }
 
-       if ((c = tb[LEASE_CFG_ATTR_IP]))
-               if (inet_pton(AF_INET, blobmsg_get_string(c), &lease_cfg->ipaddr) < 0)
+       if ((c = tb[LEASE_CFG_ATTR_IP])) {
+               const char *ip = blobmsg_get_string(c);
+
+               if (!strcmp(ip, "ignore"))
+                       lease_cfg->ignore4 = true;
+               else if (inet_pton(AF_INET, blobmsg_get_string(c), &lease_cfg->ipaddr) < 0)
                        goto err;
+       }
 
        if ((c = tb[LEASE_CFG_ATTR_HOSTID])) {
-               errno = 0;
-               lease_cfg->hostid = strtoull(blobmsg_get_string(c), NULL, 16);
-               if (errno)
-                       goto err;
+               const char *iid = blobmsg_get_string(c);
+
+               if (!strcmp(iid, "ignore")) {
+                       lease_cfg->ignore6 = true;
+               } else {
+                       errno = 0;
+                       lease_cfg->hostid = strtoull(blobmsg_get_string(c), NULL, 16);
+                       if (errno)
+                               goto err;
+               }
        } else {
                uint32_t i4a = ntohl(lease_cfg->ipaddr) & 0xff;
                lease_cfg->hostid = ((i4a / 100) << 8) | (((i4a % 100) / 10) << 4) | (i4a % 10);
index 61ec82d457840a9e48b6e437397d3ed0fd72dddc..49fc76c43b5055cc2561f0b862268d13a1f57270 100644 (file)
@@ -534,6 +534,9 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg req_msg, const uint8_t *re
        if (!lease_cfg)
                lease_cfg = config_find_lease_cfg_by_mac(req_mac);
 
+       if (lease_cfg && lease_cfg->ignore4)
+               return NULL;
+
        /*
         * If we found a static lease cfg, but no old assignment for this
         * hwaddr, we need to clear out any old assignments given to other
index f5a22d2f0a56dedb4793e542e9a6e6c4ca758a05..de9abd915e497fe34d27fc88a89b50b57961426e 100644 (file)
@@ -993,6 +993,9 @@ ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *ifac
                if (!lease_cfg)
                        lease_cfg = config_find_lease_cfg_by_mac(mac);
 
+               if (lease_cfg && lease_cfg->ignore6)
+                       return -1;
+
                /* Parse request hint for IA-PD */
                if (is_pd) {
                        uint8_t *sdata;
index 354c52934dffa84d5e01879514a58392d29e132c..04aa7ce5a0c6344901243badbcd1f980feeee258 100644 (file)
@@ -302,6 +302,8 @@ struct lease_cfg {
        struct duid *duids;
        uint32_t leasetime;             // duration of granted leases, UINT32_MAX = inf
        char *hostname;
+       bool ignore4;
+       bool ignore6;
 };
 
 // DNR - RFC9463