diff options
author | Felix Fietkau <nbd@nbd.name> | 2021-06-17 10:39:26 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2021-06-17 10:39:28 +0200 |
commit | b0d0906883021baca9ef6e80ba0480ac3e2a4b7a (patch) | |
tree | fffc8f111c2f1c6eb2c54265b8b044569b961df2 | |
parent | f12b073c0cc3b1ee8d652a342505ae0b14856c18 (diff) | |
download | netifd-b0d0906883021baca9ef6e80ba0480ac3e2a4b7a.tar.gz |
bridge: fix setting pvid for updated vlans
defer adding back changed vlans until config processing is done
Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r-- | bridge.c | 19 | ||||
-rw-r--r-- | device.c | 3 | ||||
-rw-r--r-- | device.h | 2 |
3 files changed, 23 insertions, 1 deletions
@@ -79,6 +79,7 @@ static const struct uci_blob_param_list bridge_attr_list = { static struct device *bridge_create(const char *name, struct device_type *devtype, struct blob_attr *attr); static void bridge_config_init(struct device *dev); +static void bridge_dev_vlan_update(struct device *dev); static void bridge_free(struct device *dev); static void bridge_dump_info(struct device *dev, struct blob_buf *b); static enum dev_change_type @@ -93,6 +94,7 @@ static struct device_type bridge_device_type = { .create = bridge_create, .config_init = bridge_config_init, + .vlan_update = bridge_dev_vlan_update, .reload = bridge_reload, .free = bridge_free, .dump_info = bridge_dump_info, @@ -1185,7 +1187,7 @@ bridge_vlan_update(struct vlist_tree *tree, struct vlist_node *node_new, list_splice_init(&vlan_old->hotplug_ports, &vlan_new->hotplug_ports); if (node_new) - bridge_set_vlan_state(bst, vlan_new, true); + vlan_new->pending = true; bst->dev.config_pending = true; @@ -1193,6 +1195,21 @@ out: bridge_vlan_free(vlan_old); } +static void +bridge_dev_vlan_update(struct device *dev) +{ + struct bridge_state *bst = container_of(dev, struct bridge_state, dev); + struct bridge_vlan *vlan; + + vlist_for_each_element(&dev->vlans, vlan, node) { + if (!vlan->pending) + continue; + + vlan->pending = false; + bridge_set_vlan_state(bst, vlan, true); + } +} + static struct device * bridge_create(const char *name, struct device_type *devtype, struct blob_attr *attr) @@ -129,6 +129,9 @@ void device_vlan_update(bool done) vlist_update(&dev->vlans); } else { vlist_flush(&dev->vlans); + + if (dev->type->vlan_update) + dev->type->vlan_update(dev); } } } @@ -83,6 +83,7 @@ struct device_type { struct blob_attr *attr); void (*config_init)(struct device *); enum dev_change_type (*reload)(struct device *, struct blob_attr *); + void (*vlan_update)(struct device *); void (*dump_info)(struct device *, struct blob_buf *buf); void (*dump_stats)(struct device *, struct blob_buf *buf); int (*check_state)(struct device *); @@ -277,6 +278,7 @@ struct bridge_vlan { uint16_t vid; bool local; + bool pending; }; extern const struct uci_blob_param_list device_attr_list; |