diff options
-rw-r--r-- | config.c | 106 | ||||
-rw-r--r-- | config/network | 18 | ||||
-rw-r--r-- | device.h | 16 |
3 files changed, 136 insertions, 4 deletions
@@ -2,13 +2,19 @@ #include <stdlib.h> #include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <net/ethernet.h> + #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; @@ -25,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; @@ -41,7 +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); diff --git a/config/network b/config/network index 35276ab..00c5b51 100644 --- a/config/network +++ b/config/network @@ -6,9 +6,23 @@ config interface loopback option ipaddr 127.0.0.1 option netmask 255.0.0.0 -config interface lan - option ifname 'eth0.1 eth0.2' +config device + option name br-lan option type bridge + option ifname "eth0.1 eth0.2" + option mtu 1500 + +config interface lan + option ifname 'br-lan' option proto static option ipaddr 192.168.1.1 option netmask 255.255.255.0 + + +config interface lan2 + option ifname eth0.3 + option type bridge + option proto static + option ipaddr 192.168.1.1 + option netmask 255.255.255.0 + @@ -16,6 +16,12 @@ struct device_type { void (*free)(struct device *); }; +enum { + DEV_OPT_MTU = (1 << 0), + DEV_OPT_MACADDR = (1 << 1), + DEV_OPT_TXQUEUELEN = (1 << 2) +}; + /* * link layer device. typically represents a linux network device. * can be used to support VLANs as well @@ -36,6 +42,15 @@ struct device { device_state_cb set_state; const struct device_hotplug_ops *hotplug_ops; + + /* settings */ + unsigned int flags; + + unsigned int mtu; + unsigned int txqueuelen; + uint8_t macaddr[6]; + + uint32_t config_hash; }; /* events broadcasted to all users of a device */ @@ -80,5 +95,6 @@ void release_device(struct device *dev); int check_device_state(struct device *dev); struct device *get_vlan_device_chain(const char *ifname, bool create); +struct device *bridge_create(const char *name, struct uci_section *s); #endif |