dhcp: rework assignment free logic
authorHans Dedecker <dedeckeh@gmail.com>
Mon, 18 Feb 2019 17:22:24 +0000 (18:22 +0100)
committerHans Dedecker <dedeckeh@gmail.com>
Tue, 19 Feb 2019 08:04:47 +0000 (09:04 +0100)
Replace the separate dhcpv4/dhcpv6 assignment free functions by
the function free_assignment which calls the dhcp specific
free function via a callback

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
src/config.c
src/dhcpv4.c
src/dhcpv6-ia.c
src/odhcpd.h

index 3a97e6598e4c625bba9b047b63ef6d5aec1afc09..e928536af794bc38036913df0d642b02e2e4232f 100644 (file)
@@ -789,11 +789,7 @@ static void lease_delete_assignments(struct lease *l, bool v6)
 
        list_for_each_entry_safe(a, tmp, &l->assignments, lease_list) {
                if (a->flags & flag)
-#ifdef DHCPV4_SUPPORT
-                       v6 ? dhcpv6_ia_free_assignment(a) : dhcpv4_free_assignment(a);
-#else
-                       dhcpv6_ia_free_assignment(a);
-#endif
+                       free_assignment(a);
        }
 }
 
@@ -871,14 +867,8 @@ static void lease_delete(struct lease *l)
 {
        struct dhcp_assignment *a;
 
-       list_for_each_entry(a, &l->assignments, lease_list) {
-               if (a->flags & OAF_DHCPV6)
-                       dhcpv6_ia_free_assignment(a);
-#ifdef DHCPV4_SUPPORT
-               else if (a->flags & OAF_DHCPV4)
-                       dhcpv4_free_assignment(a);
-#endif
-       }
+       list_for_each_entry(a, &l->assignments, lease_list)
+               free_assignment(a);
 
        free_lease(l);
 }
index 252003b064c2804104f548a51c4ee5318954fccc..ba64142e9746f0d9986383edbed28a422ae49f2f 100644 (file)
@@ -158,7 +158,7 @@ int dhcpv4_setup_interface(struct interface *iface, bool enable)
                odhcpd_register(&iface->dhcpv4_event);
        } else if (iface->dhcpv4_assignments.next) {
                while (!list_empty(&iface->dhcpv4_assignments))
-                       dhcpv4_free_assignment(list_first_entry(&iface->dhcpv4_assignments,
+                       free_assignment(list_first_entry(&iface->dhcpv4_assignments,
                                                        struct dhcp_assignment, head));
        }
 
@@ -345,7 +345,7 @@ static void valid_until_cb(struct uloop_timeout *event)
                struct dhcp_assignment *a, *n;
                list_for_each_entry_safe(a, n, &iface->dhcpv4_assignments, head) {
                        if (!INFINITE_VALID(a->valid_until) && a->valid_until < now)
-                               dhcpv4_free_assignment(a);
+                               free_assignment(a);
                }
        }
        uloop_timeout_set(event, 1000);
@@ -418,19 +418,10 @@ static char *dhcpv4_msg_to_string(uint8_t reqmsg)
        }
 }
 
-void dhcpv4_free_assignment(struct dhcp_assignment *a)
+static void dhcpv4_free_assignment(struct dhcp_assignment *a)
 {
-       if (a->head.next)
-               list_del(&a->head);
-
-       if (a->lease_list.next)
-               list_del(&a->lease_list);
-
        if (a->fr_ip)
                dhcpv4_fr_stop(a);
-
-       free(a->hostname);
-       free(a);
 }
 
 static void dhcpv4_put(struct dhcpv4_message *msg, uint8_t **cookie,
@@ -999,7 +990,7 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg msg, const uint8_t *mac,
        time_t now = odhcpd_time();
 
        if (l && a && a->lease != l) {
-               dhcpv4_free_assignment(a);
+               free_assignment(a);
                a = NULL;
        }
 
@@ -1024,6 +1015,7 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg msg, const uint8_t *mac,
                                /* Set valid time to 0 for static lease indicating */
                                /* infinite lifetime otherwise current time        */
                                a->valid_until = l ? 0 : now;
+                               a->dhcp_free_cb = dhcpv4_free_assignment;
                                a->iface = iface;
                                a->flags = OAF_DHCPV4;
                                a->addr = l ? l->ipaddr : INADDR_ANY;
@@ -1096,7 +1088,7 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg msg, const uint8_t *mac,
                        }
                } else if (!assigned && a) {
                        /* Cleanup failed assignment */
-                       dhcpv4_free_assignment(a);
+                       free_assignment(a);
                        a = NULL;
                }
 
index 4cc6fab8a226272bae4681edef71655258221189..9db6a54a9adf07137a1dcb3de9e42ca1785f643f 100644 (file)
@@ -67,7 +67,7 @@ int dhcpv6_ia_setup_interface(struct interface *iface, bool enable)
 
                while (!list_empty(&iface->ia_assignments)) {
                        c = list_first_entry(&iface->ia_assignments, struct dhcp_assignment, head);
-                       dhcpv6_ia_free_assignment(c);
+                       free_assignment(c);
                }
        }
 
@@ -201,25 +201,17 @@ static int send_reconf(struct dhcp_assignment *assign)
        return odhcpd_send(iface->dhcpv6_event.uloop.fd, &assign->peer, &iov, 1, iface);
 }
 
-void dhcpv6_ia_free_assignment(struct dhcp_assignment *a)
+static void dhcpv6_ia_free_assignment(struct dhcp_assignment *a)
 {
        if (a->managed_sock.fd.registered) {
                ustream_free(&a->managed_sock.stream);
                close(a->managed_sock.fd.fd);
        }
 
-       if (a->head.next)
-               list_del(&a->head);
-
-       if (a->lease_list.next)
-               list_del(&a->lease_list);
-
        if (a->reconf_cnt)
                stop_reconf(a);
 
        free(a->managed);
-       free(a->hostname);
-       free(a);
 }
 
 void dhcpv6_ia_enum_addrs(struct interface *iface, struct dhcp_assignment *c,
@@ -534,7 +526,7 @@ static void managed_handle_pd_data(struct ustream *s, _unused int bytes_new)
        }
 
        if (first && c->managed_size == 0)
-               dhcpv6_ia_free_assignment(c);
+               free_assignment(c);
        else if (first && !(c->flags & OAF_STATIC))
                c->valid_until = now + 150;
 }
@@ -786,7 +778,7 @@ static void valid_until_cb(struct uloop_timeout *event)
                        if (!INFINITE_VALID(a->valid_until) && a->valid_until < now) {
                                if ((a->length < 128 && a->clid_len > 0) ||
                                                (a->length == 128 && a->clid_len == 0))
-                                       dhcpv6_ia_free_assignment(a);
+                                       free_assignment(a);
 
                        }
                }
@@ -1231,7 +1223,7 @@ ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *ifac
                }
 
                if (l && a && a->lease != l) {
-                       dhcpv6_ia_free_assignment(a);
+                       free_assignment(a);
                        a = NULL;
                }
 
@@ -1261,6 +1253,7 @@ ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *ifac
                                                /* Set valid time to 0 for static lease indicating */
                                                /* infinite lifetime otherwise current time        */
                                                a->valid_until = l ? 0 : now;
+                                               a->dhcp_free_cb = dhcpv6_ia_free_assignment;
                                                a->iface = iface;
                                                a->flags = OAF_DHCPV6;
 
@@ -1365,7 +1358,7 @@ ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *ifac
                                apply_lease(iface, a, true);
                        } else if (!assigned && a && a->managed_size == 0) {
                                /* Cleanup failed assignment */
-                               dhcpv6_ia_free_assignment(a);
+                               free_assignment(a);
                                a = NULL;
                        }
                } else if (hdr->msg_type == DHCPV6_MSG_RENEW ||
index e346e97e19481e82d68d944b5db7ecdcc355e999..38ee020b7e13f6466cfea408d4a46cf3652ea2f1 100644 (file)
@@ -160,6 +160,8 @@ struct dhcp_assignment {
        struct list_head head;
        struct list_head lease_list;
 
+       void (*dhcp_free_cb)(struct dhcp_assignment *a);
+
        struct interface *iface;
        struct lease *lease;
 
@@ -302,6 +304,20 @@ extern struct avl_tree interfaces;
 #define RA_MANAGED_MFLAG       1
 #define RA_MANAGED_NO_AFLAG    2
 
+inline static void free_assignment(struct dhcp_assignment *a)
+{
+       if (a->head.next)
+               list_del(&a->head);
+
+       if (a->lease_list.next)
+               list_del(&a->lease_list);
+
+       if (a->dhcp_free_cb)
+               a->dhcp_free_cb(a);
+
+       free(a->hostname);
+       free(a);
+}
 
 // Exported main functions
 int odhcpd_register(struct odhcpd_event *event);
@@ -354,7 +370,6 @@ int dhcpv6_ia_setup_interface(struct interface *iface, bool enable);
 void dhcpv6_ia_enum_addrs(struct interface *iface, struct dhcp_assignment *c, time_t now,
                                dhcpv6_binding_cb_handler_t func, void *arg);
 void dhcpv6_ia_write_statefile(void);
-void dhcpv6_ia_free_assignment(struct dhcp_assignment *c);
 
 int netlink_add_netevent_handler(struct netevent_handler *hdlr);
 ssize_t netlink_get_interface_addrs(const int ifindex, bool v6,
@@ -376,7 +391,6 @@ int dhcpv6_init(void);
 int ndp_init(void);
 #ifdef DHCPV4_SUPPORT
 int dhcpv4_init(void);
-void dhcpv4_free_assignment(struct dhcp_assignment *a);
 
 int dhcpv4_setup_interface(struct interface *iface, bool enable);
 #endif