Wolfgang Bumiller
2021-Jul-02 12:07 UTC
[Bridge] [PATCH v3] net: bridge: sync fdb to new unicast-filtering ports
Since commit 2796d0c648c9 ("bridge: Automatically manage port promiscuous mode.") bridges with `vlan_filtering 1` and only 1 auto-port don't set IFF_PROMISC for unicast-filtering-capable ports. Normally on port changes `br_manage_promisc` is called to update the promisc flags and unicast filters if necessary, but it cannot distinguish between *new* ports and ones losing their promisc flag, and new ports end up not receiving the MAC address list. Fix this by calling `br_fdb_sync_static` in `br_add_if` after the port promisc flags are updated and the unicast filter was supposed to have been filled. Fixes: 2796d0c648c9 ("bridge: Automatically manage port promiscuous mode.") Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com> --- Changes to v2: * Added 'fdb_synced' boolean to only unsync on error if it was actually synced. `br_fdb_sync_static()` already unrolls changes if it encounters an error in the middle, so only a successful call will trigger the unsync. I opted for the explicit error handling as I felt that avoiding the error cleanup by moving the code down might be more easily missed in future changes (I just felt safer this way), plus, it's closer to the call which would normally be responsible for doing this which felt more natural to me. I hope this is fine, otherwise I can still move it :-) net/bridge/br_if.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index f7d2f472ae24..6e4a32354a13 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -562,7 +562,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, struct net_bridge_port *p; int err = 0; unsigned br_hr, dev_hr; - bool changed_addr; + bool changed_addr, fdb_synced = false; /* Don't allow bridging non-ethernet like devices. */ if ((dev->flags & IFF_LOOPBACK) || @@ -652,6 +652,19 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, list_add_rcu(&p->list, &br->port_list); nbp_update_port_count(br); + if (!br_promisc_port(p) && (p->dev->priv_flags & IFF_UNICAST_FLT)) { + /* When updating the port count we also update all ports' + * promiscuous mode. + * A port leaving promiscuous mode normally gets the bridge's + * fdb synced to the unicast filter (if supported), however, + * `br_port_clear_promisc` does not distinguish between + * non-promiscuous ports and *new* ports, so we need to + * sync explicitly here. + */ + fdb_synced = br_fdb_sync_static(br, p) == 0; + if (!fdb_synced) + netdev_err(dev, "failed to sync bridge static fdb addresses to this port\n"); + } netdev_update_features(br->dev); @@ -701,6 +714,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, return 0; err7: + if (fdb_synced) + br_fdb_unsync_static(br, p); list_del_rcu(&p->list); br_fdb_delete_by_port(br, p, 0, 1); nbp_update_port_count(br); -- 2.32.0
Nikolay Aleksandrov
2021-Jul-02 15:25 UTC
[Bridge] [PATCH v3] net: bridge: sync fdb to new unicast-filtering ports
On 02/07/2021 15:07, Wolfgang Bumiller wrote:> Since commit 2796d0c648c9 ("bridge: Automatically manage > port promiscuous mode.") > bridges with `vlan_filtering 1` and only 1 auto-port don't > set IFF_PROMISC for unicast-filtering-capable ports. > > Normally on port changes `br_manage_promisc` is called to > update the promisc flags and unicast filters if necessary, > but it cannot distinguish between *new* ports and ones > losing their promisc flag, and new ports end up not > receiving the MAC address list. > > Fix this by calling `br_fdb_sync_static` in `br_add_if` > after the port promisc flags are updated and the unicast > filter was supposed to have been filled. > > Fixes: 2796d0c648c9 ("bridge: Automatically manage port promiscuous mode.") > Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com> > --- > Changes to v2: > * Added 'fdb_synced' boolean to only unsync on error if it was > actually synced. > `br_fdb_sync_static()` already unrolls changes if it encounters an > error in the middle, so only a successful call will trigger the > unsync. > I opted for the explicit error handling as I felt that avoiding the > error cleanup by moving the code down might be more easily missed in > future changes (I just felt safer this way), plus, it's closer to > the call which would normally be responsible for doing this which > felt more natural to me. > > I hope this is fine, otherwise I can still move it :-) > > net/bridge/br_if.c | 17 ++++++++++++++++- > 1 file changed, 16 insertions(+), 1 deletion(-) >Looks good to me, thanks! Acked-by: Nikolay Aleksandrov <nikolay at nvidia.com>
patchwork-bot+netdevbpf at kernel.org
2021-Jul-02 20:40 UTC
[Bridge] [PATCH v3] net: bridge: sync fdb to new unicast-filtering ports
Hello: This patch was applied to netdev/net.git (refs/heads/master): On Fri, 2 Jul 2021 14:07:36 +0200 you wrote:> Since commit 2796d0c648c9 ("bridge: Automatically manage > port promiscuous mode.") > bridges with `vlan_filtering 1` and only 1 auto-port don't > set IFF_PROMISC for unicast-filtering-capable ports. > > Normally on port changes `br_manage_promisc` is called to > update the promisc flags and unicast filters if necessary, > but it cannot distinguish between *new* ports and ones > losing their promisc flag, and new ports end up not > receiving the MAC address list. > > [...]Here is the summary with links: - [v3] net: bridge: sync fdb to new unicast-filtering ports https://git.kernel.org/netdev/net/c/a019abd80220 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html