On 4/23/20 6:55 AM, Maor Gottlieb wrote: > Add new ndo to get the xmit slave of master device. > Caller should call dev_put() when it no longer works with > slave netdevice. description needs to be updated. > User can ask to get the xmit slave assume all the slaves can > transmit by set all_slaves arg to true. > > Signed-off-by: Maor Gottlieb <maorg@xxxxxxxxxxxx> > --- > include/linux/netdevice.h | 6 ++++++ > net/core/dev.c | 22 ++++++++++++++++++++++ > 2 files changed, 28 insertions(+) > > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h > index 130a668049ab..d1206f08e099 100644 > --- a/include/linux/netdevice.h > +++ b/include/linux/netdevice.h > @@ -1389,6 +1389,9 @@ struct net_device_ops { > struct netlink_ext_ack *extack); > int (*ndo_del_slave)(struct net_device *dev, > struct net_device *slave_dev); > + struct net_device* (*ndo_get_xmit_slave)(struct net_device *dev, > + struct sk_buff *skb, > + bool all_slaves); documentation above struct net_device_ops { }; needs to be updated. > netdev_features_t (*ndo_fix_features)(struct net_device *dev, > netdev_features_t features); > int (*ndo_set_features)(struct net_device *dev, > @@ -2731,6 +2734,9 @@ void netdev_freemem(struct net_device *dev); > void synchronize_net(void); > int init_dummy_netdev(struct net_device *dev); > > +struct net_device *netdev_get_xmit_slave(struct net_device *dev, > + struct sk_buff *skb, > + bool all_slaves); > struct net_device *dev_get_by_index(struct net *net, int ifindex); > struct net_device *__dev_get_by_index(struct net *net, int ifindex); > struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex); > diff --git a/net/core/dev.c b/net/core/dev.c > index 9c9e763bfe0e..e6c10980abfd 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -7785,6 +7785,28 @@ void netdev_bonding_info_change(struct net_device *dev, > } > EXPORT_SYMBOL(netdev_bonding_info_change); > > +/** > + * netdev_get_xmit_slave - Get the xmit slave of master device > + * @skb: The packet > + * @all_slaves: assume all the slaves are active > + * > + * The reference counters are not incremented so the caller must be > + * careful with locks. The caller must hold RCU lock. > + * %NULL is returned if no slave is found. > + */ > + > +struct net_device *netdev_get_xmit_slave(struct net_device *dev, > + struct sk_buff *skb, > + bool all_slaves) > +{ > + const struct net_device_ops *ops = dev->netdev_ops; > + > + if (!ops->ndo_get_xmit_slave) > + return NULL; > + return ops->ndo_get_xmit_slave(dev, skb, all_slaves); > +} > +EXPORT_SYMBOL(netdev_get_xmit_slave); > + > static void netdev_adjacent_add_links(struct net_device *dev) > { > struct netdev_adjacent *iter; >