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);
}
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,
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);
}
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;
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);
+ }
}
}
#include <libubox/avl.h>
#include <libubox/safe_list.h>
+#include <libubox/kvlist.h>
#include <netinet/in.h>
struct device;
struct safe_list aliases;
struct vlist_tree vlans;
+ struct kvlist vlan_aliases;
char ifname[IFNAMSIZ + 1];
int ifindex;
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",
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) {
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)
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;