diff options
-rw-r--r-- | bridge.c | 1 | ||||
-rw-r--r-- | config.c | 6 | ||||
-rw-r--r-- | device.c | 14 | ||||
-rw-r--r-- | device.h | 2 | ||||
-rw-r--r-- | vlan.c | 22 |
5 files changed, 35 insertions, 10 deletions
@@ -761,6 +761,7 @@ bridge_free(struct device *dev) bst = container_of(dev, struct bridge_state, dev); vlist_flush_all(&bst->members); vlist_flush_all(&dev->vlans); + kvlist_free(&dev->vlan_aliases); free(bst->config_data); free(bst); } @@ -279,15 +279,18 @@ config_parse_vlan(struct device *dev, struct uci_section *s) BRVLAN_ATTR_VID, BRVLAN_ATTR_LOCAL, BRVLAN_ATTR_PORTS, + BRVLAN_ATTR_ALIAS, __BRVLAN_ATTR_MAX, }; static const struct blobmsg_policy vlan_attrs[__BRVLAN_ATTR_MAX] = { [BRVLAN_ATTR_VID] = { "vlan", BLOBMSG_TYPE_INT32 }, [BRVLAN_ATTR_LOCAL] = { "local", BLOBMSG_TYPE_BOOL }, [BRVLAN_ATTR_PORTS] = { "ports", BLOBMSG_TYPE_ARRAY }, + [BRVLAN_ATTR_ALIAS] = { "alias", BLOBMSG_TYPE_ARRAY }, }; static const struct uci_blob_param_info vlan_attr_info[__BRVLAN_ATTR_MAX] = { [BRVLAN_ATTR_PORTS] = { .type = BLOBMSG_TYPE_STRING }, + [BRVLAN_ATTR_ALIAS] = { .type = BLOBMSG_TYPE_STRING }, }; static const struct uci_blob_param_list vlan_attr_list = { .n_params = __BRVLAN_ATTR_MAX, @@ -363,6 +366,9 @@ config_parse_vlan(struct device *dev, struct uci_section *s) port++; } + blobmsg_for_each_attr(cur, tb[BRVLAN_ATTR_ALIAS], rem) + kvlist_set(&dev->vlan_aliases, blobmsg_get_string(cur), &vid); + vlist_add(&dev->vlans, &vlan->node, &vlan->vid); } @@ -109,6 +109,11 @@ void device_unlock(void) device_free_unused(NULL); } +static int device_vlan_len(struct kvlist *kv, const void *data) +{ + return sizeof(unsigned int); +} + void device_vlan_update(bool done) { struct device *dev; @@ -117,10 +122,15 @@ void device_vlan_update(bool done) if (!dev->vlans.update) continue; - if (!done) + if (!done) { + if (dev->vlan_aliases.get_len) + kvlist_free(&dev->vlan_aliases); + else + kvlist_init(&dev->vlan_aliases, device_vlan_len); vlist_update(&dev->vlans); - else + } else { vlist_flush(&dev->vlans); + } } } @@ -16,6 +16,7 @@ #include <libubox/avl.h> #include <libubox/safe_list.h> +#include <libubox/kvlist.h> #include <netinet/in.h> struct device; @@ -186,6 +187,7 @@ struct device { struct safe_list aliases; struct vlist_tree vlans; + struct kvlist vlan_aliases; char ifname[IFNAMSIZ + 1]; int ifindex; @@ -161,7 +161,7 @@ vlan_config_init(struct device *dev) vlan_hotplug_check(vldev, vldev->dep.dev); } -static struct device *get_vlan_device(struct device *dev, int id, bool create) +static struct device *get_vlan_device(struct device *dev, char *id_str, bool create) { static struct device_type vlan_type = { .name = "VLAN", @@ -172,6 +172,17 @@ static struct device *get_vlan_device(struct device *dev, int id, bool create) struct vlan_device *vldev; struct device_user *dep; char name[IFNAMSIZ + 1]; + char *err = NULL; + int id, *alias_id; + + id = strtoul(id_str, &err, 10); + if (err && *err) { + alias_id = kvlist_get(&dev->vlan_aliases, id_str); + if (!alias_id) + return NULL; + + id = *alias_id; + } /* look for an existing interface before creating a new one */ list_for_each_entry(dep, &dev->users.list, list.list) { @@ -238,8 +249,7 @@ out: struct device *get_vlan_device_chain(const char *ifname, bool create) { struct device *dev = NULL; - char *buf, *s, *next, *err = NULL; - int id; + char *buf, *s, *next; buf = strdup(ifname); if (!buf) @@ -252,11 +262,7 @@ struct device *get_vlan_device_chain(const char *ifname, bool create) do { next = split_vlan(s); - id = strtoul(s, &err, 10); - if (err && *err) - goto error; - - dev = get_vlan_device(dev, id, create); + dev = get_vlan_device(dev, s, create); if (!dev) goto error; |