diff options
Diffstat (limited to 'src/config.c')
-rw-r--r-- | src/config.c | 43 |
1 files changed, 16 insertions, 27 deletions
diff --git a/src/config.c b/src/config.c index 68aacd8..f4a0dcf 100644 --- a/src/config.c +++ b/src/config.c @@ -12,13 +12,15 @@ #include <uci.h> #include <uci_blob.h> #include <libubox/utils.h> +#include <libubox/avl.h> +#include <libubox/avl-cmp.h> #include "odhcpd.h" static struct blob_buf b; static int reload_pipe[2]; struct list_head leases = LIST_HEAD_INIT(leases); -struct list_head interfaces = LIST_HEAD_INIT(interfaces); +AVL_TREE(interfaces, avl_strcmp, false, NULL); struct config config = {.legacy = false, .main_dhcpv4 = false, .dhcp_cb = NULL, .dhcp_statefile = NULL, .log_level = LOG_INFO}; @@ -206,15 +208,6 @@ static void free_lease(struct lease *l) free(l); } -static struct interface* get_interface(const char *name) -{ - struct interface *c; - list_for_each_entry(c, &interfaces, head) - if (!strcmp(c->name, name)) - return c; - return NULL; -} - static void set_interface_defaults(struct interface *iface) { iface->learn_routes = 1; @@ -244,8 +237,7 @@ static void clean_interface(struct interface *iface) static void close_interface(struct interface *iface) { - if (iface->head.next) - list_del(&iface->head); + avl_delete(&interfaces, &iface->avl); router_setup_interface(iface, false); dhcpv6_setup_interface(iface, false); @@ -409,6 +401,7 @@ err: int config_parse_interface(void *data, size_t len, const char *name, bool overwrite) { + struct interface *iface; struct blob_attr *tb[IFACE_ATTR_MAX], *c; bool get_addrs = false; @@ -420,19 +413,19 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr if (!name) return -1; - struct interface *iface = get_interface(name); + iface = avl_find_element(&interfaces, name, iface, avl); if (!iface) { - char *iface_name; + char *new_name; - iface = calloc_a(sizeof(*iface), &iface_name, strlen(name) + 1); + iface = calloc_a(sizeof(*iface), &new_name, strlen(name) + 1); if (!iface) return -1; - iface->name = strcpy(iface_name, name); - + iface->name = strcpy(new_name, name); + iface->avl.key = iface->name; set_interface_defaults(iface); - list_add(&iface->head, &interfaces); + avl_insert(&interfaces, &iface->avl); get_addrs = overwrite = true; } @@ -785,16 +778,15 @@ static int set_interface(struct uci_section *s) void odhcpd_reload(void) { struct uci_context *uci = uci_alloc_context(); + struct interface *master = NULL, *i, *tmp; while (!list_empty(&leases)) free_lease(list_first_entry(&leases, struct lease, head)); - struct interface *master = NULL, *i, *n; - if (!uci) return; - list_for_each_entry(i, &interfaces, head) + avl_for_each_element(&interfaces, i, avl) clean_interface(i); struct uci_package *dhcp = NULL; @@ -829,7 +821,7 @@ void odhcpd_reload(void) bool any_dhcpv6_slave = false, any_ra_slave = false, any_ndp_slave = false; /* Test for */ - list_for_each_entry(i, &interfaces, head) { + avl_for_each_element(&interfaces, i, avl) { if (i->master) continue; @@ -844,7 +836,7 @@ void odhcpd_reload(void) } /* Evaluate hybrid mode for master */ - list_for_each_entry(i, &interfaces, head) { + avl_for_each_element(&interfaces, i, avl) { if (!i->master) continue; @@ -877,7 +869,7 @@ void odhcpd_reload(void) } - list_for_each_entry_safe(i, n, &interfaces, head) { + avl_for_each_element_safe(&interfaces, i, avl, tmp) { if (i->inuse) { /* Resolve hybrid mode */ if (i->dhcpv6 == MODE_HYBRID) @@ -944,8 +936,5 @@ void odhcpd_run(void) odhcpd_reload(); uloop_run(); - - while (!list_empty(&interfaces)) - close_interface(list_first_entry(&interfaces, struct interface, head)); } |