summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2020-11-20 18:58:10 +0100
committerFelix Fietkau <nbd@nbd.name>2020-11-20 19:01:17 +0100
commit4544f026bb0996adb6d95224031f0ba35cb8c046 (patch)
tree0ed33ee832d2ef7037b0bf15ea884c688b2db3c7
parent5e18d5b9ccb189efb914733e7b74073f5c75e0df (diff)
downloadnetifd-4544f026bb0996adb6d95224031f0ba35cb8c046.tar.gz
bridge-vlan: add support for defining aliases for vlan ids
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>
-rw-r--r--bridge.c1
-rw-r--r--config.c6
-rw-r--r--device.c14
-rw-r--r--device.h2
-rw-r--r--vlan.c22
5 files changed, 35 insertions, 10 deletions
diff --git a/bridge.c b/bridge.c
index 44d6af6..b70d626 100644
--- 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);
}
diff --git a/config.c b/config.c
index 563dedc..d91830c 100644
--- 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);
}
diff --git a/device.c b/device.c
index e484c09..3e2b5e9 100644
--- 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);
+ }
}
}
diff --git a/device.h b/device.h
index 243fdad..b2b18ab 100644
--- 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 e238461..82b2d66 100644
--- 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;