On 03/10/17 10:58, Jiri Pirko wrote: > From: Yotam Gigi <[email protected]> > > In order to allow the ipmr module to do partial multicast forwarding > according to the device parent ID, add the device parent ID field to the > VIF struct. This way, the forwarding path can use the parent ID field > without invoking switchdev calls, which requires the RTNL lock. > > When a new VIF is added, set the device parent ID field in it by invoking > the switchdev_port_attr_get call. > > Signed-off-by: Yotam Gigi <[email protected]> > Reviewed-by: Ido Schimmel <[email protected]> > Signed-off-by: Jiri Pirko <[email protected]> > --- > v1->v2: > - Set the vif->dev_parent_id.len field > - Remove the vif->dev_parent_id_valid field and use len instead > - Set the vif->dev_parent_id to invalid if the device does not support the > switchdev PARENT_ID attribute > --- > include/linux/mroute.h | 1 + > net/ipv4/ipmr.c | 11 +++++++++++ > 2 files changed, 12 insertions(+) > > diff --git a/include/linux/mroute.h b/include/linux/mroute.h > index b072a84..8242d05 100644 > --- a/include/linux/mroute.h > +++ b/include/linux/mroute.h > @@ -57,6 +57,7 @@ static inline bool ipmr_rule_default(const struct fib_rule > *rule) > > struct vif_device { > struct net_device *dev; /* Device we are using > */ > + struct netdev_phys_item_id dev_parent_id; /* Device parent ID > */ > unsigned long bytes_in,bytes_out; > unsigned long pkt_in,pkt_out; /* Statistics > */ > unsigned long rate_limit; /* Traffic shaping (NI) > */ > diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c > index a844738..1b161ad 100644 > --- a/net/ipv4/ipmr.c > +++ b/net/ipv4/ipmr.c > @@ -67,6 +67,7 @@ > #include <net/fib_rules.h> > #include <linux/netconf.h> > #include <net/nexthop.h> > +#include <net/switchdev.h> > > struct ipmr_rule { > struct fib_rule common; > @@ -868,6 +869,9 @@ static int vif_add(struct net *net, struct mr_table *mrt, > struct vifctl *vifc, int mrtsock) > { > int vifi = vifc->vifc_vifi; > + struct switchdev_attr attr = { > + .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID, > + }; > struct vif_device *v = &mrt->vif_table[vifi]; > struct net_device *dev; > struct in_device *in_dev; > @@ -942,6 +946,13 @@ static int vif_add(struct net *net, struct mr_table *mrt, > > /* Fill in the VIF structures */ > > + attr.orig_dev = dev; > + if (!switchdev_port_attr_get(dev, &attr)) { > + memcpy(v->dev_parent_id.id, attr.u.ppid.id, attr.u.ppid.id_len); > + v->dev_parent_id.id_len = attr.u.ppid.id_len; > + } else { > + v->dev_parent_id.id_len = 0; > + } > v->rate_limit = vifc->vifc_rate_limit; > v->local = vifc->vifc_lcl_addr.s_addr; > v->remote = vifc->vifc_rmt_addr.s_addr; >
Looks good, thanks! Signed-off-by: Nikolay Aleksandrov <[email protected]>
