summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;