[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210224114350.2791260-6-olteanv@gmail.com>
Date: Wed, 24 Feb 2021 13:43:38 +0200
From: Vladimir Oltean <olteanv@...il.com>
To: netdev@...r.kernel.org
Cc: Andrew Lunn <andrew@...n.ch>,
Florian Fainelli <f.fainelli@...il.com>,
Vivien Didelot <vivien.didelot@...il.com>,
Jiri Pirko <jiri@...nulli.us>,
Ido Schimmel <idosch@...sch.org>,
DENG Qingfang <dqfext@...il.com>,
Tobias Waldekranz <tobias@...dekranz.com>,
George McCollister <george.mccollister@...il.com>,
Vlad Yasevich <vyasevich@...il.com>,
Roopa Prabhu <roopa@...dia.com>,
Nikolay Aleksandrov <nikolay@...dia.com>
Subject: [RFC PATCH v2 net-next 05/17] net: bridge: implement unicast filtering for the bridge device
From: Vladimir Oltean <vladimir.oltean@....com>
The bridge device currently goes into promiscuous mode when it has an
upper with a different MAC address than itself. But it could do better:
it could sync the MAC addresses of its uppers to the software FDB, as
local entries pointing to the bridge itself. This is compatible with
switchdev, since drivers are now instructed to trap these MAC addresses
to the CPU.
Note that the dev_uc_add API does not propagate VLAN ID, so this only
works for VLAN-unaware bridges.
Signed-off-by: Vladimir Oltean <vladimir.oltean@....com>
---
net/bridge/br_device.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 3f2f06b4dd27..a7d9d35e70d0 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -179,8 +179,25 @@ static int br_dev_open(struct net_device *dev)
return 0;
}
-static void br_dev_set_multicast_list(struct net_device *dev)
+static int br_dev_sync_uc(struct net_device *dev, const unsigned char *addr)
{
+ struct net_bridge *br = netdev_priv(dev);
+
+ return br_fdb_insert(br, NULL, addr, 0);
+}
+
+static int br_dev_unsync_uc(struct net_device *dev, const unsigned char *addr)
+{
+ struct net_bridge *br = netdev_priv(dev);
+
+ br_fdb_find_delete_local(br, NULL, addr, 0);
+
+ return 0;
+}
+
+static void br_dev_set_rx_mode(struct net_device *dev)
+{
+ __dev_uc_sync(dev, br_dev_sync_uc, br_dev_unsync_uc);
}
static void br_dev_change_rx_flags(struct net_device *dev, int change)
@@ -399,7 +416,7 @@ static const struct net_device_ops br_netdev_ops = {
.ndo_start_xmit = br_dev_xmit,
.ndo_get_stats64 = dev_get_tstats64,
.ndo_set_mac_address = br_set_mac_address,
- .ndo_set_rx_mode = br_dev_set_multicast_list,
+ .ndo_set_rx_mode = br_dev_set_rx_mode,
.ndo_change_rx_flags = br_dev_change_rx_flags,
.ndo_change_mtu = br_change_mtu,
.ndo_do_ioctl = br_dev_ioctl,
@@ -436,7 +453,7 @@ void br_dev_setup(struct net_device *dev)
dev->needs_free_netdev = true;
dev->ethtool_ops = &br_ethtool_ops;
SET_NETDEV_DEVTYPE(dev, &br_type);
- dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE;
+ dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE | IFF_UNICAST_FLT;
dev->features = COMMON_FEATURES | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
--
2.25.1
Powered by blists - more mailing lists