diff options
author | Felix Fietkau <nbd@nbd.name> | 2021-07-23 11:04:45 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2021-07-23 11:04:47 +0200 |
commit | 85f01c44a950be8518ce5a7d251b5bba219348cf (patch) | |
tree | 5b415838ce2606394aee5a37e61728a8290117ff /bridge.c | |
parent | 7f24a063475e1e2be4e0c516a5b62c3fae5ec542 (diff) | |
download | netifd-85f01c44a950be8518ce5a7d251b5bba219348cf.tar.gz |
bridge: check bridge port vlan membership on link-up events
When changing to a dfs channel, hostapd can bring down wlan interfaces and
reset their bridge membership. If that happens, the port loses its vlan
membership settings and needs to be reconfigured by netifd.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'bridge.c')
-rw-r--r-- | bridge.c | 27 |
1 files changed, 22 insertions, 5 deletions
@@ -122,17 +122,13 @@ struct bridge_member { struct vlist_node node; struct bridge_state *bst; struct device_user dev; + struct uloop_timeout check_timer; uint16_t pvid; bool present; bool active; char name[]; }; -struct bridge_vlan_hotplug_port { - struct list_head list; - struct bridge_vlan_port port; -}; - static void bridge_reset_primary(struct bridge_state *bst) { @@ -477,6 +473,7 @@ restart: device_lock(); device_remove_user(&bm->dev); + uloop_timeout_cancel(&bm->check_timer); /* * When reloading the config and moving a device from one bridge to @@ -505,6 +502,22 @@ bridge_check_retry(struct bridge_state *bst) } static void +bridge_member_check_cb(struct uloop_timeout *t) +{ + struct bridge_member *bm; + struct bridge_state *bst; + + bm = container_of(t, struct bridge_member, check_timer); + bst = bm->bst; + + if (!system_bridge_vlan_check(&bst->dev, bm->dev.dev->ifname)) + return; + + bridge_disable_member(bm, true); + bridge_enable_member(bm); +} + +static void bridge_member_cb(struct device_user *dep, enum device_event ev) { struct bridge_member *bm = container_of(dep, struct bridge_member, dev); @@ -521,6 +534,9 @@ bridge_member_cb(struct device_user *dep, enum device_event ev) if (bst->n_present == 1) device_set_present(&bst->dev, true); fallthrough; + case DEV_EVENT_LINK_UP: + uloop_timeout_set(&bm->check_timer, 1000); + break; case DEV_EVENT_AUTH_UP: if (!bst->dev.active) break; @@ -634,6 +650,7 @@ bridge_create_member(struct bridge_state *bst, const char *name, bm->bst = bst; bm->dev.cb = bridge_member_cb; bm->dev.hotplug = hotplug; + bm->check_timer.cb = bridge_member_check_cb; strcpy(bm->name, name); bm->dev.dev = dev; vlist_add(&bst->members, &bm->node, bm->name); |