From b0d0906883021baca9ef6e80ba0480ac3e2a4b7a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 17 Jun 2021 10:39:26 +0200 Subject: [PATCH] bridge: fix setting pvid for updated vlans defer adding back changed vlans until config processing is done Signed-off-by: Felix Fietkau --- bridge.c | 19 ++++++++++++++++++- device.c | 3 +++ device.h | 2 ++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/bridge.c b/bridge.c index ecb9b03..f3e2fed 100644 --- a/bridge.c +++ b/bridge.c @@ -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) diff --git a/device.c b/device.c index 26254cc..9bad507 100644 --- a/device.c +++ b/device.c @@ -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); } } } diff --git a/device.h b/device.h index c6fc02b..db6dc33 100644 --- a/device.h +++ b/device.h @@ -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; -- 2.30.2