X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=config.c;h=99adda1a0a66943e668aafdd87313c7fe4c8f85f;hp=66cee8463b812fd8d82c5b141cac2700331ad515;hb=c1692fdcf48ad32217354d5206af31115e562306;hpb=aa76c9ee78146f97512f96524d3abb94210040a5 diff --git a/config.c b/config.c index 66cee84..99adda1 100644 --- a/config.c +++ b/config.c @@ -2,12 +2,19 @@ #include #include +#include +#include +#include + #include "netifd.h" #include "interface.h" struct uci_context *uci_ctx; +struct uci_package *uci_network; +bool config_init = false; -static void config_parse_interface(struct uci_section *s) +static void +config_parse_interface(struct uci_section *s) { struct interface *iface; const char *type; @@ -24,7 +31,99 @@ static void config_parse_interface(struct uci_section *s) interface_attach_bridge(iface, s); } -void config_init_interfaces(const char *name) +enum { + SDEV_NAME, + SDEV_TYPE, + SDEV_MTU, + SDEV_MACADDR, + SDEV_TXQUEUELEN, + __SDEV_MAX, +}; + +struct uci_parse_option dev_opts[__SDEV_MAX] = { + [SDEV_NAME] = { "name", UCI_TYPE_STRING }, + [SDEV_TYPE] = { "type", UCI_TYPE_STRING }, + [SDEV_MTU] = { "mtu", UCI_TYPE_STRING }, + [SDEV_MACADDR] = { "macaddr", UCI_TYPE_STRING }, + [SDEV_TXQUEUELEN] = { "txqueuelen", UCI_TYPE_STRING }, +}; + +static bool +add_int_option(struct uci_option *o, unsigned int *dest) +{ + char *error = NULL; + int val; + + if (!o) + return false; + + val = strtoul(o->v.string, &error, 0); + if (error && *error) + return false; + + *dest = val; + return true; +} + +static void +config_init_device_settings(struct device *dev, struct uci_option **opts) +{ + struct ether_addr *ea; + + dev->flags = 0; + + if (add_int_option(opts[SDEV_MTU], &dev->mtu)) + dev->flags |= DEV_OPT_MTU; + + if (add_int_option(opts[SDEV_TXQUEUELEN], &dev->txqueuelen)) + dev->flags |= DEV_OPT_TXQUEUELEN; + + if (opts[SDEV_MACADDR]) { + ea = ether_aton(opts[SDEV_MACADDR]->v.string); + if (ea) { + memcpy(dev->macaddr, ea, sizeof(dev->macaddr)); + dev->flags |= DEV_OPT_MACADDR; + } + } +} + +void +config_init_devices(void) +{ + struct uci_element *e; + struct device *dev; + struct uci_option *opts[__SDEV_MAX]; + + uci_foreach_element(&uci_network->sections, e) { + struct uci_section *s = uci_to_section(e); + + if (strcmp(s->type, "device") != 0) + continue; + + uci_parse_section(s, dev_opts, __SDEV_MAX, opts); + if (!opts[SDEV_NAME]) + continue; + + dev = NULL; + if (opts[SDEV_TYPE]) { + const char *type = opts[SDEV_TYPE]->v.string; + + if (!strcmp(type, "bridge")) + dev = bridge_create(opts[SDEV_NAME]->v.string, s); + } else { + dev = get_device(opts[SDEV_NAME]->v.string, true); + } + + if (!dev) + continue; + + config_init_device_settings(dev, opts); + dev->config_hash = uci_hash_options(opts, __SDEV_MAX); + } +} + +void +config_init_interfaces(const char *name) { struct uci_context *ctx; struct uci_package *p = NULL; @@ -40,6 +139,11 @@ void config_init_interfaces(const char *name) return; } + uci_network = p; + config_init = true; + + config_init_devices(); + uci_foreach_element(&p->sections, e) { struct uci_section *s = uci_to_section(e); @@ -49,4 +153,7 @@ void config_init_interfaces(const char *name) if (!strcmp(s->type, "interface")) config_parse_interface(s); } + config_init = false; + + start_pending_interfaces(); }