All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] net: bridge: sync fdb to new unicast-filtering ports
@ 2021-07-02 12:07 ` Wolfgang Bumiller
  0 siblings, 0 replies; 6+ messages in thread
From: Wolfgang Bumiller @ 2021-07-02 12:07 UTC (permalink / raw)
  To: netdev
  Cc: bridge, Jakub Kicinski, David S. Miller, Nikolay Aleksandrov,
	Roopa Prabhu, Vlad Yasevich, Michael S. Tsirkin,
	Thomas Lamprecht

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@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



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Bridge] [PATCH v3] net: bridge: sync fdb to new unicast-filtering ports
@ 2021-07-02 12:07 ` Wolfgang Bumiller
  0 siblings, 0 replies; 6+ messages in thread
From: Wolfgang Bumiller @ 2021-07-02 12:07 UTC (permalink / raw)
  To: netdev
  Cc: Vlad Yasevich, Michael S. Tsirkin, bridge, Thomas Lamprecht,
	Nikolay Aleksandrov, Roopa Prabhu, Jakub Kicinski,
	David S. Miller

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@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



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] net: bridge: sync fdb to new unicast-filtering ports
  2021-07-02 12:07 ` [Bridge] " Wolfgang Bumiller
@ 2021-07-02 15:25   ` Nikolay Aleksandrov
  -1 siblings, 0 replies; 6+ messages in thread
From: Nikolay Aleksandrov @ 2021-07-02 15:25 UTC (permalink / raw)
  To: Wolfgang Bumiller, netdev
  Cc: bridge, Jakub Kicinski, David S. Miller, Roopa Prabhu,
	Vlad Yasevich, Michael S. Tsirkin, Thomas Lamprecht

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@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@nvidia.com>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Bridge] [PATCH v3] net: bridge: sync fdb to new unicast-filtering ports
@ 2021-07-02 15:25   ` Nikolay Aleksandrov
  0 siblings, 0 replies; 6+ messages in thread
From: Nikolay Aleksandrov @ 2021-07-02 15:25 UTC (permalink / raw)
  To: Wolfgang Bumiller, netdev
  Cc: Vlad Yasevich, Michael S. Tsirkin, bridge, Thomas Lamprecht,
	Roopa Prabhu, Jakub Kicinski, David S. Miller

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@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@nvidia.com>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] net: bridge: sync fdb to new unicast-filtering ports
  2021-07-02 12:07 ` [Bridge] " Wolfgang Bumiller
@ 2021-07-02 20:40   ` patchwork-bot+netdevbpf
  -1 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2021-07-02 20:40 UTC (permalink / raw)
  To: Wolfgang Bumiller
  Cc: netdev, bridge, kuba, davem, nikolay, roopa, vyasevic, mst, t.lamprecht

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



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Bridge] [PATCH v3] net: bridge: sync fdb to new unicast-filtering ports
@ 2021-07-02 20:40   ` patchwork-bot+netdevbpf
  0 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2021-07-02 20:40 UTC (permalink / raw)
  To: Wolfgang Bumiller
  Cc: vyasevic, mst, netdev, bridge, t.lamprecht, nikolay, roopa, kuba, davem

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



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-07-02 20:40 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-02 12:07 [PATCH v3] net: bridge: sync fdb to new unicast-filtering ports Wolfgang Bumiller
2021-07-02 12:07 ` [Bridge] " Wolfgang Bumiller
2021-07-02 15:25 ` Nikolay Aleksandrov
2021-07-02 15:25   ` [Bridge] " Nikolay Aleksandrov
2021-07-02 20:40 ` patchwork-bot+netdevbpf
2021-07-02 20:40   ` [Bridge] " patchwork-bot+netdevbpf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.