bridge-vlan: add support for defining aliases for vlan ids
authorFelix Fietkau <nbd@nbd.name>
Fri, 20 Nov 2020 17:58:10 +0000 (18:58 +0100)
committerFelix Fietkau <nbd@nbd.name>
Fri, 20 Nov 2020 18:01:17 +0000 (19:01 +0100)
When defining a bridge-vlan like this:

config bridge-vlan
option device 'switch0'
option vlan '1'
option ports 'lan1 lan2 lan3 lan4'
option alias 'lan'

You can use switch0.lan instead of switch0.1 to refer to the VLAN.
This ensures that the VLAN ID can be kept in a single place in the config

Signed-off-by: Felix Fietkau <nbd@nbd.name>
bridge.c
config.c
device.c
device.h
vlan.c

index 44d6af6b00c3b69ab423e4932bfc44667f2435e8..b70d626009e9fd84249f8b5334f83edd6dd8354c 100644 (file)
--- a/bridge.c
+++ b/bridge.c
@@ -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);
 }
index 563dedc4a8b722d3ca4aa2ca967b3d50dbca8629..d91830c8a931917239a3502a4f256674cfad2627 100644 (file)
--- a/config.c
+++ b/config.c
@@ -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);
 }
 
index e484c0970b14c07777b0a7f05f26cc8093d4fc31..3e2b5e9da4265e9abd78f9139bec56bb27c0de03 100644 (file)
--- a/device.c
+++ b/device.c
@@ -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);
+               }
        }
 }
 
index 243fdadd8ac5483f0cd5c4715b2824bfacd57921..b2b18ab0cfa63c4069c4b495d33a29f5169e8bfb 100644 (file)
--- a/device.h
+++ b/device.h
@@ -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;
diff --git a/vlan.c b/vlan.c
index e2384612e157564bc6d321e60d916c6e4d4f2ff5..82b2d66821a2c9800c2a7718bec5dee483ca047b 100644 (file)
--- a/vlan.c
+++ b/vlan.c
@@ -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;