Skip to content

Commit 47d5b6d

Browse files
lunndavem330
authored andcommitted
net: bridge: Add/del switchdev object on host join/leave
When the host joins or leaves a multicast group, use switchdev to add an object to the hardware to forward traffic for the group to the host. Signed-off-by: Andrew Lunn <[email protected]> Acked-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2a26028 commit 47d5b6d

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

include/net/switchdev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ enum switchdev_obj_id {
7676
SWITCHDEV_OBJ_ID_UNDEFINED,
7777
SWITCHDEV_OBJ_ID_PORT_VLAN,
7878
SWITCHDEV_OBJ_ID_PORT_MDB,
79+
SWITCHDEV_OBJ_ID_HOST_MDB,
7980
};
8081

8182
struct switchdev_obj {

net/bridge/br_mdb.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,46 @@ static void br_mdb_complete(struct net_device *dev, int err, void *priv)
292292
kfree(priv);
293293
}
294294

295+
static void br_mdb_switchdev_host_port(struct net_device *dev,
296+
struct net_device *lower_dev,
297+
struct br_mdb_entry *entry, int type)
298+
{
299+
struct switchdev_obj_port_mdb mdb = {
300+
.obj = {
301+
.id = SWITCHDEV_OBJ_ID_HOST_MDB,
302+
.flags = SWITCHDEV_F_DEFER,
303+
},
304+
.vid = entry->vid,
305+
};
306+
307+
if (entry->addr.proto == htons(ETH_P_IP))
308+
ip_eth_mc_map(entry->addr.u.ip4, mdb.addr);
309+
#if IS_ENABLED(CONFIG_IPV6)
310+
else
311+
ipv6_eth_mc_map(&entry->addr.u.ip6, mdb.addr);
312+
#endif
313+
314+
mdb.obj.orig_dev = dev;
315+
switch (type) {
316+
case RTM_NEWMDB:
317+
switchdev_port_obj_add(lower_dev, &mdb.obj);
318+
break;
319+
case RTM_DELMDB:
320+
switchdev_port_obj_del(lower_dev, &mdb.obj);
321+
break;
322+
}
323+
}
324+
325+
static void br_mdb_switchdev_host(struct net_device *dev,
326+
struct br_mdb_entry *entry, int type)
327+
{
328+
struct net_device *lower_dev;
329+
struct list_head *iter;
330+
331+
netdev_for_each_lower_dev(dev, lower_dev, iter)
332+
br_mdb_switchdev_host_port(dev, lower_dev, entry, type);
333+
}
334+
295335
static void __br_mdb_notify(struct net_device *dev, struct net_bridge_port *p,
296336
struct br_mdb_entry *entry, int type)
297337
{
@@ -331,6 +371,9 @@ static void __br_mdb_notify(struct net_device *dev, struct net_bridge_port *p,
331371
switchdev_port_obj_del(port_dev, &mdb.obj);
332372
}
333373

374+
if (!p)
375+
br_mdb_switchdev_host(dev, entry, type);
376+
334377
skb = nlmsg_new(rtnl_mdb_nlmsg_size(), GFP_ATOMIC);
335378
if (!skb)
336379
goto errout;

net/switchdev/switchdev.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,8 @@ static size_t switchdev_obj_size(const struct switchdev_obj *obj)
345345
return sizeof(struct switchdev_obj_port_vlan);
346346
case SWITCHDEV_OBJ_ID_PORT_MDB:
347347
return sizeof(struct switchdev_obj_port_mdb);
348+
case SWITCHDEV_OBJ_ID_HOST_MDB:
349+
return sizeof(struct switchdev_obj_port_mdb);
348350
default:
349351
BUG();
350352
}

0 commit comments

Comments
 (0)