summaryrefslogtreecommitdiffhomepage
path: root/src/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c43
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));
}