From afbd7dd2a0f26f603ee21685ede2bba14a41a34a Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Mon, 18 Feb 2019 18:22:24 +0100 Subject: [PATCH] dhcp: rework assignment free logic 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 --- src/config.c | 16 +++------------- src/dhcpv4.c | 20 ++++++-------------- src/dhcpv6-ia.c | 21 +++++++-------------- src/odhcpd.h | 18 ++++++++++++++++-- 4 files changed, 32 insertions(+), 43 deletions(-) diff --git a/src/config.c b/src/config.c index 3a97e65..e928536 100644 --- a/src/config.c +++ b/src/config.c @@ -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); } diff --git a/src/dhcpv4.c b/src/dhcpv4.c index 252003b..ba64142 100644 --- a/src/dhcpv4.c +++ b/src/dhcpv4.c @@ -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; } diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c index 4cc6fab..9db6a54 100644 --- a/src/dhcpv6-ia.c +++ b/src/dhcpv6-ia.c @@ -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 || diff --git a/src/odhcpd.h b/src/odhcpd.h index e346e97..38ee020 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -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 -- 2.25.1