summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-01-10 21:50:21 (GMT)
committerDavid S. Miller <davem@davemloft.net>2016-01-10 21:50:21 (GMT)
commitd3517f19f2c41f1b4e9b6a763c0cea3f7d72b589 (patch)
tree0477eec356f1e7c9422c1fa3ea66da92bc31defb /net
parentc9c99311b55d4765cae35c652cb637747cc637b7 (diff)
parent4f5590f8cd736768170818d1b7ea0075972e2701 (diff)
downloadlinux-d3517f19f2c41f1b4e9b6a763c0cea3f7d72b589.tar.xz
Merge branch 'mlxsw-layer2-multicast'
Jiri Pirko says: ==================== mlxsw: Adding layer 2 multicast Elad says: This patchset add Linux hardware reflection for L2 multicast offload and add MC support in mlxsw. For every bridge MDB entry insertion, either by IGMP snooping or by static insertion/removal, a switchdev ops is been called. In mlxsw, a new multicast group (MID) is been created and ports are assigned. When all ports are removed, the multicast group is been deleted. --- v1->v2: - GFP_ATOMIC->GFP_KERNEL change in patch 7/8 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_mdb.c23
-rw-r--r--net/switchdev/switchdev.c2
2 files changed, 25 insertions, 0 deletions
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index cd8deea..30e105f 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -7,6 +7,7 @@
#include <linux/if_ether.h>
#include <net/ip.h>
#include <net/netlink.h>
+#include <net/switchdev.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ipv6.h>
#include <net/addrconf.h>
@@ -210,10 +211,32 @@ static inline size_t rtnl_mdb_nlmsg_size(void)
static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry,
int type)
{
+ struct switchdev_obj_port_mdb mdb = {
+ .obj = {
+ .id = SWITCHDEV_OBJ_ID_PORT_MDB,
+ .flags = SWITCHDEV_F_DEFER,
+ },
+ .vid = entry->vid,
+ };
+ struct net_device *port_dev;
struct net *net = dev_net(dev);
struct sk_buff *skb;
int err = -ENOBUFS;
+ port_dev = __dev_get_by_index(net, entry->ifindex);
+ if (entry->addr.proto == htons(ETH_P_IP))
+ ip_eth_mc_map(entry->addr.u.ip4, mdb.addr);
+#if IS_ENABLED(CONFIG_IPV6)
+ else
+ ipv6_eth_mc_map(&entry->addr.u.ip6, mdb.addr);
+#endif
+
+ mdb.obj.orig_dev = port_dev;
+ if (port_dev && type == RTM_NEWMDB)
+ switchdev_port_obj_add(port_dev, &mdb.obj);
+ else if (port_dev && type == RTM_DELMDB)
+ switchdev_port_obj_del(port_dev, &mdb.obj);
+
skb = nlmsg_new(rtnl_mdb_nlmsg_size(), GFP_ATOMIC);
if (!skb)
goto errout;
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index df790d3..ebc661d 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -345,6 +345,8 @@ static size_t switchdev_obj_size(const struct switchdev_obj *obj)
return sizeof(struct switchdev_obj_ipv4_fib);
case SWITCHDEV_OBJ_ID_PORT_FDB:
return sizeof(struct switchdev_obj_port_fdb);
+ case SWITCHDEV_OBJ_ID_PORT_MDB:
+ return sizeof(struct switchdev_obj_port_mdb);
default:
BUG();
}