lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190115194130.19896-11-f.fainelli@gmail.com>
Date:   Tue, 15 Jan 2019 11:41:26 -0800
From:   Florian Fainelli <f.fainelli@...il.com>
To:     netdev@...r.kernel.org
Cc:     Florian Fainelli <f.fainelli@...il.com>, andrew@...n.ch,
        vivien.didelot@...il.com, davem@...emloft.net, idosch@...lanox.com,
        jiri@...lanox.com, ilias.apalodimas@...aro.org,
        ivan.khoronzhuk@...aro.org, roopa@...ulusnetworks.com,
        nikolay@...ulusnetworks.com
Subject: [RFC net-next 10/14] net: vlan: Propagate MC addresses with VID through switchdev

The VLAN real device could be an Ethernet switch port and that switch
might have VLAN filtering globally enabled (because of a bridge
requesting VLAN filtering on the switch on another port) and so when
programming multicast addresses, we need the multicast filter
programming to be aware of the correct VLAN ID as well.

Ethernet drivers that do not implement switchdev_port_{add,del}
operations and do not specifically check for SWITCHDEV_OBJ_ID_HOST_MDB
are not affected by that change.

Signed-off-by: Florian Fainelli <f.fainelli@...il.com>
---
 net/8021q/vlan_dev.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index b2d9c8f27cd7..ea2ef9d78dcb 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -312,6 +312,43 @@ static int vlan_dev_open(struct net_device *dev)
 	return err;
 }
 
+static int vlan_dev_sync_unsync_mc_addr(struct net_device *dev,
+                                        const unsigned char *addr,
+                                        bool add)
+{
+	struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
+	struct switchdev_obj_port_mdb mdb = {
+		.obj = {
+			.orig_dev = dev,
+			.id = SWITCHDEV_OBJ_ID_HOST_MDB,
+			.flags = SWITCHDEV_F_DEFER,
+		},
+		.vid = vlan_dev_vlan_id(dev),
+	};
+	int ret = -EOPNOTSUPP;
+
+	ether_addr_copy(mdb.addr, addr);
+        if (add)
+		ret = switchdev_port_obj_add(real_dev, &mdb.obj, NULL);
+        else
+		ret = switchdev_port_obj_del(real_dev, &mdb.obj);
+
+	return ret;
+}
+
+static int vlan_dev_sync_mc_addr(struct net_device *dev,
+                                 const unsigned char *addr)
+{
+	return vlan_dev_sync_unsync_mc_addr(dev, addr, true);
+}
+
+static int vlan_dev_unsync_mc_addr(struct net_device *dev,
+                                   const unsigned char *addr)
+{
+	return vlan_dev_sync_unsync_mc_addr(dev, addr, false);
+}
+
+
 static int vlan_dev_stop(struct net_device *dev)
 {
 	struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
@@ -319,6 +356,7 @@ static int vlan_dev_stop(struct net_device *dev)
 
 	dev_mc_unsync(real_dev, dev);
 	dev_uc_unsync(real_dev, dev);
+	__hw_addr_unsync_dev(&dev->mc, dev, vlan_dev_unsync_mc_addr);
 	if (dev->flags & IFF_ALLMULTI)
 		dev_set_allmulti(real_dev, -1);
 	if (dev->flags & IFF_PROMISC)
@@ -483,6 +521,8 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
 
 static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
 {
+	__hw_addr_sync_dev(&vlan_dev->mc, vlan_dev, vlan_dev_sync_mc_addr,
+			   vlan_dev_unsync_mc_addr);
 	dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
 	dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
 }
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ