On 7.11.2017 01:26, Andrew Lunn wrote: > 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 <and...@lunn.ch> > --- > include/net/switchdev.h | 1 + > net/bridge/br_mdb.c | 39 +++++++++++++++++++++++++++++++++++++++ > net/switchdev/switchdev.c | 2 ++ > 3 files changed, 42 insertions(+) >
One minor nit below, functionally looks good. Acked-by: Nikolay Aleksandrov <niko...@cumulusnetworks.com> > diff --git a/include/net/switchdev.h b/include/net/switchdev.h > index d756fbe46625..39bc855d7fee 100644 > --- a/include/net/switchdev.h > +++ b/include/net/switchdev.h > @@ -76,6 +76,7 @@ enum switchdev_obj_id { > SWITCHDEV_OBJ_ID_UNDEFINED, > SWITCHDEV_OBJ_ID_PORT_VLAN, > SWITCHDEV_OBJ_ID_PORT_MDB, > + SWITCHDEV_OBJ_ID_HOST_MDB, > }; > > struct switchdev_obj { > diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c > index 702408d2a93c..2a3daa11f60b 100644 > --- a/net/bridge/br_mdb.c > +++ b/net/bridge/br_mdb.c > @@ -292,6 +292,42 @@ static void br_mdb_complete(struct net_device *dev, int > err, void *priv) > kfree(priv); > } > > +static void br_mdb_switchdev_host_port(struct net_device *dev, > + struct net_device *lower_dev, > + struct br_mdb_entry *entry, int type) > +{ > + struct switchdev_obj_port_mdb mdb = { > + .obj = { > + .id = SWITCHDEV_OBJ_ID_HOST_MDB, > + .flags = SWITCHDEV_F_DEFER, > + }, > + .vid = entry->vid, > + }; > + > + 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 = dev; > + if (type == RTM_NEWMDB) > + switchdev_port_obj_add(lower_dev, &mdb.obj); > + if (type == RTM_DELMDB) > + switchdev_port_obj_del(lower_dev, &mdb.obj); nit: type can be only one of these, could you make that explicit (e.g. switch) ? > +} > + > +static void br_mdb_switchdev_host(struct net_device *dev, > + struct br_mdb_entry *entry, int type) > +{ > + struct net_device *lower_dev; > + struct list_head *iter; > + > + netdev_for_each_lower_dev(dev, lower_dev, iter) > + br_mdb_switchdev_host_port(dev, lower_dev, entry, type); > +} > + > static void __br_mdb_notify(struct net_device *dev, struct net_bridge_port > *p, > struct br_mdb_entry *entry, int type) > { > @@ -331,6 +367,9 @@ static void __br_mdb_notify(struct net_device *dev, > struct net_bridge_port *p, > switchdev_port_obj_del(port_dev, &mdb.obj); > } > > + if (!p) > + br_mdb_switchdev_host(dev, entry, type); > + > 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 0531b41d1f2d..74b9d916a58b 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_port_vlan); > case SWITCHDEV_OBJ_ID_PORT_MDB: > return sizeof(struct switchdev_obj_port_mdb); > + case SWITCHDEV_OBJ_ID_HOST_MDB: > + return sizeof(struct switchdev_obj_port_mdb); > default: > BUG(); > } >