#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;
static struct uci_package *uci_network;
bool config_init = false;
+static struct blob_buf b;
+
static void uci_attr_to_blob(struct blob_buf *b, const char *str,
const char *name, enum blobmsg_type type)
static void
config_parse_interface(struct uci_section *s)
{
- struct blob_buf b = {};
-
DPRINTF("Create interface '%s'\n", s->e.name);
blob_buf_init(&b, 0);
alloc_interface(s->e.name, s, b.head);
}
-enum {
- SDEV_NAME,
- SDEV_TYPE,
- SDEV_MTU,
- SDEV_MACADDR,
- SDEV_TXQUEUELEN,
- __SDEV_MAX,
-};
-
-static const 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);
+ blob_buf_init(&b, 0);
+ uci_to_blob(&b, s, &device_attr_list);
+ device_create(b.head, s);
}
}
#include <stdio.h>
#include <assert.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/ethernet.h>
+
#include "netifd.h"
#include "system.h"
+#include "config.h"
static struct avl_tree devices;
+enum {
+ DEV_ATTR_NAME,
+ DEV_ATTR_TYPE,
+ DEV_ATTR_MTU,
+ DEV_ATTR_MACADDR,
+ DEV_ATTR_TXQUEUELEN,
+ __DEV_ATTR_MAX,
+};
+
+static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = {
+ [DEV_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING },
+ [DEV_ATTR_TYPE] = { "type", BLOBMSG_TYPE_STRING },
+ [DEV_ATTR_MTU] = { "mtu", BLOBMSG_TYPE_INT32 },
+ [DEV_ATTR_MACADDR] = { "macaddr", BLOBMSG_TYPE_STRING },
+ [DEV_ATTR_TXQUEUELEN] = { "txqueuelen", BLOBMSG_TYPE_INT32 },
+};
+
+const struct config_param_list device_attr_list = {
+ .n_params = __DEV_ATTR_MAX,
+ .params = dev_attrs,
+};
+
+static void
+device_init_settings(struct device *dev, struct blob_attr **tb)
+{
+ struct blob_attr *cur;
+ struct ether_addr *ea;
+
+ dev->flags = 0;
+
+ if ((cur = tb[DEV_ATTR_MTU])) {
+ dev->mtu = blobmsg_get_u32(cur);
+ dev->flags |= DEV_OPT_MTU;
+ }
+
+ if ((cur = tb[DEV_ATTR_TXQUEUELEN])) {
+ dev->txqueuelen = blobmsg_get_u32(cur);
+ dev->flags |= DEV_OPT_TXQUEUELEN;
+ }
+
+ if ((cur = tb[DEV_ATTR_MACADDR])) {
+ ea = ether_aton(blob_data(cur));
+ if (ea) {
+ memcpy(dev->macaddr, ea, sizeof(dev->macaddr));
+ dev->flags |= DEV_OPT_MACADDR;
+ }
+ }
+}
+
+struct device *
+device_create(struct blob_attr *attr, struct uci_section *s)
+{
+ struct blob_attr *tb[__DEV_ATTR_MAX];
+ struct blob_attr *cur;
+ struct device *dev = NULL;
+ const char *name;
+
+ blobmsg_parse(dev_attrs, __DEV_ATTR_MAX, tb, blob_data(attr), blob_len(attr));
+ if (!tb[DEV_ATTR_NAME])
+ return NULL;
+
+ name = blobmsg_data(tb[DEV_ATTR_NAME]);
+ if ((cur = tb[DEV_ATTR_TYPE])) {
+ if (!strcmp(blobmsg_data(cur), "bridge"))
+ dev = bridge_create(name, s);
+ } else {
+ dev = get_device(name, true);
+ }
+
+ if (!dev)
+ return NULL;
+
+ device_init_settings(dev, tb);
+
+ return dev;
+}
+
+
static void __init dev_init(void)
{
avl_init(&devices, avl_strcmp, false, NULL);