dhcpv4: fix DHCP address space logic
authorHans Dedecker <dedeckeh@gmail.com>
Thu, 21 Jun 2018 14:36:29 +0000 (16:36 +0200)
committerHans Dedecker <dedeckeh@gmail.com>
Thu, 21 Jun 2018 15:33:30 +0000 (17:33 +0200)
Don't use an IPv4 address which belongs to the force renew IP address
list as candidate for the DHCP address space calculation logic as
such addresses are installed by the forced renew logic to safeguard
IP connectivity during the forced renew message exchanges and thus
cannot be used to calculate the DHCP address space

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
src/dhcpv4.c

index 9b8186f948ad70a3a7a514339f42ba72f92499d0..8c9e9bafe9e88dc716efc4b30bd6ed4461816ca9 100644 (file)
@@ -38,6 +38,7 @@
 static void dhcpv4_netevent_cb(unsigned long event, struct netevent_handler_info *info);
 static int setup_dhcpv4_addresses(struct interface *iface);
 static void update_static_assignments(struct interface *iface);
+static bool addr_is_fr_ip(struct interface *iface, struct in_addr *addr);
 static void valid_until_cb(struct uloop_timeout *event);
 static void handle_addrlist_change(struct interface *iface);
 static void free_dhcpv4_assignment(struct dhcpv4_assignment *a);
@@ -243,6 +244,9 @@ static int setup_dhcpv4_addresses(struct interface *iface)
                struct in_addr *addr = &iface->addr4[i].addr.in;
                struct in_addr mask;
 
+               if (addr_is_fr_ip(iface, addr))
+                       continue;
+
                odhcpd_bitlen2netmask(false, iface->addr4[i].prefix, &mask);
                if ((start & ntohl(~mask.s_addr)) == start &&
                            (end & ntohl(~mask.s_addr)) == end) {
@@ -369,6 +373,18 @@ static void decr_ref_cnt_ip(struct odhcpd_ref_ip **ptr, struct interface *iface)
        *ptr = NULL;
 }
 
+static bool addr_is_fr_ip(struct interface *iface, struct in_addr *addr)
+{
+       struct odhcpd_ref_ip *p;
+
+       list_for_each_entry(p, &iface->dhcpv4_fr_ips, head) {
+               if (addr->s_addr == p->addr.addr.in.s_addr)
+                       return true;
+       }
+
+       return false;
+}
+
 static bool leases_require_fr(struct interface *iface, struct odhcpd_ipaddr *addr,
                                uint32_t mask)
 {