dhcpv4: rename iface->dhcpv4_local -> iface->dhcpv4_own_ip
authorDavid Härdeman <[email protected]>
Wed, 19 Nov 2025 23:29:18 +0000 (00:29 +0100)
committerÁlvaro Fernández Rojas <[email protected]>
Thu, 27 Nov 2025 07:24:09 +0000 (08:24 +0100)
"local" isn't very informative, the local what?

In addition, use a struct odhpd_ipaddr instead of a struct in_addr, the
former can already store the prefix_len, broadcast and netmask address,
this will allow the separate iface->dhcpv4_bcast and iface->dhcpv4_mask
members to be removed (see subsequent patches).

Signed-off-by: David Härdeman <[email protected]>
Link: https://github.com/openwrt/odhcpd/pull/320
Signed-off-by: Álvaro Fernández Rojas <[email protected]>
src/dhcpv4.c
src/odhcpd.c
src/odhcpd.h

index f489232a8468a37f1daef01da75a4424a5467b1b..49d3c785297b1715e814b8c9bb23ecc875ea317f 100644 (file)
@@ -78,26 +78,30 @@ static bool addr_is_fr_ip(struct interface *iface, struct in_addr *addr)
        return false;
 }
 
-static bool leases_require_fr(struct interface *iface, struct odhcpd_ipaddr *addr,
-                             uint32_t mask)
+static bool leases_require_fr(struct interface *iface, struct odhcpd_ipaddr *oaddr)
 {
        struct dhcpv4_lease *lease = NULL;
        struct odhcpd_ref_ip *fr_ip = NULL;
 
        avl_for_each_element(&iface->dhcpv4_leases, lease, iface_avl) {
-               if ((lease->accept_fr_nonce || iface->dhcpv4_forcereconf) &&
-                   !lease->fr_ip &&
-                   ((lease->ipv4.s_addr & mask) == (addr->addr.in.s_addr & mask))) {
-                       if (!fr_ip) {
-                               fr_ip = calloc(1, sizeof(*fr_ip));
-                               if (!fr_ip)
-                                       break;
+               if (!lease->accept_fr_nonce && !iface->dhcpv4_forcereconf)
+                       continue;
 
-                               list_add(&fr_ip->head, &iface->dhcpv4_fr_ips);
-                               fr_ip->addr = *addr;
-                       }
-                       inc_ref_cnt_ip(&lease->fr_ip, fr_ip);
+               if (lease->fr_ip)
+                       continue;
+
+               if ((lease->ipv4.s_addr & oaddr->netmask) != (oaddr->addr.in.s_addr & oaddr->netmask))
+                       continue;
+
+               if (!fr_ip) {
+                       fr_ip = calloc(1, sizeof(*fr_ip));
+                       if (!fr_ip)
+                               break;
+
+                       list_add(&fr_ip->head, &iface->dhcpv4_fr_ips);
+                       fr_ip->addr = *oaddr;
                }
+               inc_ref_cnt_ip(&lease->fr_ip, fr_ip);
        }
 
        return fr_ip ? true : false;
@@ -818,7 +822,7 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len,
                .flags = req->flags,
                .ciaddr = { INADDR_ANY },
                .yiaddr = { INADDR_ANY },
-               .siaddr = iface->dhcpv4_local,
+               .siaddr = iface->dhcpv4_own_ip.addr.in,
                .giaddr = req->giaddr,
                .chaddr = { 0 },
                .sname = { 0 },
@@ -833,7 +837,7 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len,
        struct dhcpv4_option_u32 reply_serverid = {
                .code = DHCPV4_OPT_SERVERID,
                .len = sizeof(struct in_addr),
-               .data = iface->dhcpv4_local.s_addr,
+               .data = iface->dhcpv4_own_ip.addr.in.s_addr,
        };
        struct dhcpv4_option reply_clientid = {
                .code = DHCPV4_OPT_CLIENTID,
@@ -978,7 +982,7 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len,
                                req_msg = opt->data[0];
                        break;
                case DHCPV4_OPT_SERVERID:
-                       if (opt->len == 4 && memcmp(opt->data, &iface->dhcpv4_local, 4))
+                       if (opt->len == 4 && memcmp(opt->data, &iface->dhcpv4_own_ip, 4))
                                return;
                        break;
                case DHCPV4_OPT_REQOPTS:
@@ -1094,8 +1098,8 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len,
                                reply_router.len = iface->dhcpv4_router_cnt * sizeof(*iface->dhcpv4_router);
                                iov[IOV_ROUTER_ADDR].iov_base = iface->dhcpv4_router;
                        } else {
-                               reply_router.len = sizeof(iface->dhcpv4_local);
-                               iov[IOV_ROUTER_ADDR].iov_base = &iface->dhcpv4_local;
+                               reply_router.len = sizeof(iface->dhcpv4_own_ip.addr.in);
+                               iov[IOV_ROUTER_ADDR].iov_base = &iface->dhcpv4_own_ip.addr.in;
                        }
                        iov[IOV_ROUTER_ADDR].iov_len = reply_router.len;
                        break;
@@ -1106,8 +1110,8 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len,
                                reply_dnsserver.len = iface->dhcpv4_dns_cnt * sizeof(*iface->dhcpv4_dns);
                                iov[IOV_DNSSERVER_ADDR].iov_base = iface->dhcpv4_dns;
                        } else {
-                               reply_dnsserver.len = sizeof(iface->dhcpv4_local);
-                               iov[IOV_DNSSERVER_ADDR].iov_base = &iface->dhcpv4_local;
+                               reply_dnsserver.len = sizeof(iface->dhcpv4_own_ip);
+                               iov[IOV_DNSSERVER_ADDR].iov_base = &iface->dhcpv4_own_ip;
                        }
                        iov[IOV_DNSSERVER_ADDR].iov_len = reply_dnsserver.len;
                        break;
@@ -1355,7 +1359,7 @@ static bool dhcpv4_setup_addresses(struct interface *iface)
 
        iface->dhcpv4_start_ip.s_addr = INADDR_ANY;
        iface->dhcpv4_end_ip.s_addr = INADDR_ANY;
-       iface->dhcpv4_local.s_addr = INADDR_ANY;
+       iface->dhcpv4_own_ip = (struct odhcpd_ipaddr){ .addr.in.s_addr = INADDR_ANY };
        iface->dhcpv4_bcast.s_addr = INADDR_ANY;
        iface->dhcpv4_mask.s_addr = INADDR_ANY;
 
@@ -1363,7 +1367,7 @@ static bool dhcpv4_setup_addresses(struct interface *iface)
                if (!iface->oaddrs4_cnt)
                        goto error;
 
-               iface->dhcpv4_local.s_addr = iface->oaddrs4[0].addr.in.s_addr;
+               iface->dhcpv4_own_ip = iface->oaddrs4[0];
                iface->dhcpv4_bcast = iface->oaddrs4[0].broadcast;
                iface->dhcpv4_mask.s_addr = iface->oaddrs4[0].netmask;
 
@@ -1422,7 +1426,7 @@ static bool dhcpv4_setup_addresses(struct interface *iface)
 
                iface->dhcpv4_start_ip.s_addr = (oaddr->addr.in.s_addr & oaddr->netmask) | htonl(pool_start);
                iface->dhcpv4_end_ip.s_addr = (oaddr->addr.in.s_addr & oaddr->netmask) | htonl(pool_end);
-               iface->dhcpv4_local.s_addr = oaddr->addr.in.s_addr;
+               iface->dhcpv4_own_ip = *oaddr;
                iface->dhcpv4_bcast = oaddr->broadcast;
                iface->dhcpv4_mask.s_addr = oaddr->netmask;
 
@@ -1564,26 +1568,23 @@ error:
 
 static void dhcpv4_addrlist_change(struct interface *iface)
 {
-       struct odhcpd_ipaddr ip;
+       struct odhcpd_ipaddr ip = iface->dhcpv4_own_ip;
        struct odhcpd_ref_ip *a;
        struct dhcpv4_lease *lease;
-       uint32_t mask = iface->dhcpv4_mask.s_addr;
-
-       memset(&ip, 0, sizeof(ip));
-       ip.addr.in = iface->dhcpv4_local;
-       ip.prefix_len = odhcpd_netmask2bitlen(false, &iface->dhcpv4_mask);
-       ip.broadcast = iface->dhcpv4_bcast;
 
        dhcpv4_setup_addresses(iface);
 
-       if ((ip.addr.in.s_addr & mask) ==
-           (iface->dhcpv4_local.s_addr & iface->dhcpv4_mask.s_addr))
+       if ((ip.addr.in.s_addr & ip.netmask) ==
+           (iface->dhcpv4_own_ip.addr.in.s_addr & iface->dhcpv4_own_ip.netmask))
+               return;
+
+       if (ip.addr.in.s_addr && !leases_require_fr(iface, &ip))
                return;
 
-       if (ip.addr.in.s_addr && !leases_require_fr(iface, &ip, mask))
+       if (iface->dhcpv4_own_ip.addr.in.s_addr == INADDR_ANY)
                return;
 
-       if (iface->dhcpv4_local.s_addr == INADDR_ANY || list_empty(&iface->dhcpv4_fr_ips))
+       if (list_empty(&iface->dhcpv4_fr_ips))
                return;
 
        a = list_first_entry(&iface->dhcpv4_fr_ips, struct odhcpd_ref_ip, head);
index f9e07feed8685005f7e65816a19969a0daf88562..a731263910dcb1f59be67662c5b6e2ea9db2feaa 100644 (file)
@@ -756,25 +756,6 @@ int odhcpd_parse_addr6_prefix(const char *str, struct in6_addr *addr, uint8_t *p
        return 0;
 }
 
-
-int odhcpd_netmask2bitlen(bool inet6, void *mask)
-{
-       int bits;
-       struct in_addr *v4;
-       struct in6_addr *v6;
-
-       if (inet6)
-               for (bits = 0, v6 = mask;
-                    bits < 128 && (v6->s6_addr[bits / 8] << (bits % 8)) & 128;
-                    bits++);
-       else
-               for (bits = 0, v4 = mask;
-                    bits < 32 && (ntohl(v4->s_addr) << bits) & 0x80000000;
-                    bits++);
-
-       return bits;
-}
-
 bool odhcpd_valid_hostname(const char *name)
 {
 #define MAX_LABEL      63
index 1da50ddede22ba210d00c63913c26c82c3122e5e..735bd6fefea0bd6d9d09550c411ae27811c9a712 100644 (file)
@@ -446,7 +446,7 @@ struct interface {
        uint32_t dhcpv4_pool_end;       // Offset to last dynamic address
        struct in_addr dhcpv4_start_ip;
        struct in_addr dhcpv4_end_ip;
-       struct in_addr dhcpv4_local;
+       struct odhcpd_ipaddr dhcpv4_own_ip;
        struct in_addr dhcpv4_bcast;
        struct in_addr dhcpv4_mask;
        struct in_addr *dhcpv4_router;
@@ -566,7 +566,6 @@ typedef void (*odhcpd_enum_addr6_cb_t)(struct dhcpv6_lease *lease,
 void odhcpd_enum_addr6(struct interface *iface, struct dhcpv6_lease *lease,
                       time_t now, odhcpd_enum_addr6_cb_t func, void *arg);
 int odhcpd_parse_addr6_prefix(const char *str, struct in6_addr *addr, uint8_t *prefix);
-int odhcpd_netmask2bitlen(bool v6, void *mask);
 bool odhcpd_valid_hostname(const char *name);
 
 int config_parse_interface(void *data, size_t len, const char *iname, bool overwrite);