[prev in list] [next in list] [prev in thread] [next in thread] 

List:       git-commits-head
Subject:    net: dsa: include fdb entries pointing to bridge in the host fdb list
From:       Linux Kernel Mailing List <linux-kernel () vger ! kernel ! org>
Date:       2021-06-30 23:50:31
Message-ID: git-mailbomb-linux-master-81a619f787593daf6224068c6dc8022ece591844 () kernel ! org
[Download RAW message or body]

Commit:     81a619f787593daf6224068c6dc8022ece591844
Parent:     10fae4ac89ce5c2ead6c6c35fd09651b5f97ae05
Refname:    refs/heads/master
Web:        https://git.kernel.org/torvalds/c/81a619f787593daf6224068c6dc8022ece591844
Author:     Vladimir Oltean <vladimir.oltean@nxp.com>
AuthorDate: Tue Jun 29 17:06:56 2021 +0300
Committer:  David S. Miller <davem@davemloft.net>
CommitDate: Tue Jun 29 10:46:23 2021 -0700

    net: dsa: include fdb entries pointing to bridge in the host fdb list
    
    The bridge supports a legacy way of adding local (non-forwarded) FDB
    entries, which works on an individual port basis:
    
    bridge fdb add dev swp0 00:01:02:03:04:05 master local
    
    As well as a new way, added by Roopa Prabhu in commit 3741873b4f73
    ("bridge: allow adding of fdb entries pointing to the bridge device"):
    
    bridge fdb add dev br0 00:01:02:03:04:05 self local
    
    The two commands are functionally equivalent, except that the first one
    produces an entry with fdb->dst == swp0, and the other an entry with
    fdb->dst == NULL. The confusing part, though, is that even if fdb->dst
    is swp0 for the 'local on port' entry, that destination is not used.
    
    Nonetheless, the idea is that the bridge has reference counting for
    local entries, and local entries pointing towards the bridge are still
    'as local' as local entries for a port.
    
    The bridge adds the MAC addresses of the interfaces automatically as
    FDB entries with is_local=1. For the MAC address of the ports, fdb->dst
    will be equal to the port, and for the MAC address of the bridge,
    fdb->dst will point towards the bridge (i.e. be NULL). Therefore, if the
    MAC address of the bridge is not inherited from either of the physical
    ports, then we must explicitly catch local FDB entries emitted towards
    the br0, otherwise we'll miss the MAC address of the bridge (and, of
    course, any entry with 'bridge add dev br0 ... self local').
    
    Co-developed-by: Tobias Waldekranz <tobias@waldekranz.com>
    Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
    Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
---
 net/dsa/slave.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index d006bd04f84a4..a7b5d2a41472c 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -2415,7 +2415,11 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
 			struct net_device *br_dev;
 			struct dsa_slave_priv *p;
 
-			br_dev = netdev_master_upper_dev_get_rcu(dev);
+			if (netif_is_bridge_master(dev))
+				br_dev = dev;
+			else
+				br_dev = netdev_master_upper_dev_get_rcu(dev);
+
 			if (!br_dev)
 				return NOTIFY_DONE;
 
@@ -2443,8 +2447,13 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
 			 * LAG we don't want to send traffic to the CPU, the
 			 * other ports bridged with the LAG should be able to
 			 * autonomously forward towards it.
+			 * On the other hand, if the address is local
+			 * (therefore not learned) then we want to trap it to
+			 * the CPU regardless of whether the interface it
+			 * belongs to is offloaded or not.
 			 */
-			if (dsa_tree_offloads_bridge_port(dp->ds->dst, dev))
+			if (dsa_tree_offloads_bridge_port(dp->ds->dst, dev) &&
+			    !fdb_info->is_local)
 				return NOTIFY_DONE;
 		}
 
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic