summaryrefslogtreecommitdiff
path: root/bridge.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2021-06-02 17:59:03 +0200
committerFelix Fietkau <nbd@nbd.name>2021-06-02 17:59:52 +0200
commit61a71e5e49c3be8b0846c63bee001ab34c4f4da7 (patch)
tree1125d33a57994d3f2297d948b036902aecd3670e /bridge.c
parent899c2a4520526d43113f73cf673f20e2486a40fb (diff)
downloadnetifd-61a71e5e49c3be8b0846c63bee001ab34c4f4da7.tar.gz
bridge: dynamically create vlans for hotplug members
This makes it possible to use dynamic tags without changing the configuration Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'bridge.c')
-rw-r--r--bridge.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/bridge.c b/bridge.c
index 4db6e15..b336463 100644
--- a/bridge.c
+++ b/bridge.c
@@ -452,6 +452,7 @@ bridge_free_member(struct bridge_member *bm)
vlist_for_each_element(&bst->dev.vlans, vlan, node) {
struct bridge_vlan_hotplug_port *port, *tmp;
+ bool free_port = false;
list_for_each_entry_safe(port, tmp, &vlan->hotplug_ports, list) {
if (strcmp(port->port.ifname, ifname) != 0)
@@ -459,7 +460,14 @@ bridge_free_member(struct bridge_member *bm)
list_del(&port->list);
free(port);
+ free_port = true;
}
+
+ if (!free_port || !list_empty(&vlan->hotplug_ports) ||
+ vlan->n_ports || vlan->node.version != -1)
+ continue;
+
+ vlist_delete(&bst->dev.vlans, &vlan->node);
}
device_lock();
@@ -677,6 +685,25 @@ bridge_add_member(struct bridge_state *bst, const char *name)
bridge_create_member(bst, name, dev, false);
}
+static struct bridge_vlan *
+bridge_hotplug_get_vlan(struct bridge_state *bst, unsigned int vid)
+{
+ struct bridge_vlan *vlan;
+
+ vlan = vlist_find(&bst->dev.vlans, &vid, vlan, node);
+ if (vlan)
+ return vlan;
+
+ vlan = calloc(1, sizeof(*vlan));
+ vlan->vid = vid;
+ vlan->local = true;
+ vlan->node.version = -1;
+ INIT_LIST_HEAD(&vlan->hotplug_ports);
+ vlist_add(&bst->dev.vlans, &vlan->node, &vlan->vid);
+
+ return vlan;
+}
+
static void
bridge_hotplug_create_member_vlans(struct bridge_state *bst, struct blob_attr *vlans, const char *ifname)
{
@@ -701,7 +728,7 @@ bridge_hotplug_create_member_vlans(struct bridge_state *bst, struct blob_attr *v
if (!vid || vid > 4095)
continue;
- vlan = vlist_find(&bst->dev.vlans, &vid, vlan, node);
+ vlan = bridge_hotplug_get_vlan(bst, vid);
if (!vlan)
continue;