On 11/03, Daniel Borkmann wrote: > ndo_get_peer_dev is used in tcx BPF fast path, therefore make use of > indirect call wrapper and therefore optimize the bpf_redirect_peer() > internal handling a bit. Add a small skb_get_peer_dev() wrapper which > utilizes the INDIRECT_CALL_1() macro instead of open coding. > > Co-developed-by: Nikolay Aleksandrov <razor@xxxxxxxxxxxxx> > Signed-off-by: Nikolay Aleksandrov <razor@xxxxxxxxxxxxx> > Signed-off-by: Daniel Borkmann <daniel@xxxxxxxxxxxxx> > --- > drivers/net/netkit.c | 3 ++- > include/net/netkit.h | 6 ++++++ > net/core/filter.c | 18 +++++++++++++----- > 3 files changed, 21 insertions(+), 6 deletions(-) > > diff --git a/drivers/net/netkit.c b/drivers/net/netkit.c > index dc51c23b40f0..934c71a73b5c 100644 > --- a/drivers/net/netkit.c > +++ b/drivers/net/netkit.c > @@ -7,6 +7,7 @@ > #include <linux/filter.h> > #include <linux/netfilter_netdev.h> > #include <linux/bpf_mprog.h> > +#include <linux/indirect_call_wrapper.h> > > #include <net/netkit.h> > #include <net/dst.h> > @@ -177,7 +178,7 @@ static void netkit_set_headroom(struct net_device *dev, int headroom) > rcu_read_unlock(); > } > > -static struct net_device *netkit_peer_dev(struct net_device *dev) > +INDIRECT_CALLABLE_SCOPE struct net_device *netkit_peer_dev(struct net_device *dev) > { > return rcu_dereference(netkit_priv(dev)->peer); > } > diff --git a/include/net/netkit.h b/include/net/netkit.h > index 0ba2e6b847ca..9ec0163739f4 100644 > --- a/include/net/netkit.h > +++ b/include/net/netkit.h > @@ -10,6 +10,7 @@ int netkit_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog); > int netkit_link_attach(const union bpf_attr *attr, struct bpf_prog *prog); > int netkit_prog_detach(const union bpf_attr *attr, struct bpf_prog *prog); > int netkit_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr); > +INDIRECT_CALLABLE_DECLARE(struct net_device *netkit_peer_dev(struct net_device *dev)); > #else > static inline int netkit_prog_attach(const union bpf_attr *attr, > struct bpf_prog *prog) > @@ -34,5 +35,10 @@ static inline int netkit_prog_query(const union bpf_attr *attr, > { > return -EINVAL; > } > + > +static inline struct net_device *netkit_peer_dev(struct net_device *dev) > +{ > + return NULL; > +} > #endif /* CONFIG_NETKIT */ > #endif /* __NET_NETKIT_H */ > diff --git a/net/core/filter.c b/net/core/filter.c > index 7aca28b7d0fd..dbf92b272022 100644 > --- a/net/core/filter.c > +++ b/net/core/filter.c > @@ -81,6 +81,7 @@ > #include <net/xdp.h> > #include <net/mptcp.h> > #include <net/netfilter/nf_conntrack_bpf.h> > +#include <net/netkit.h> > #include <linux/un.h> > > #include "dev.h" > @@ -2468,6 +2469,16 @@ static const struct bpf_func_proto bpf_clone_redirect_proto = { > DEFINE_PER_CPU(struct bpf_redirect_info, bpf_redirect_info); > EXPORT_PER_CPU_SYMBOL_GPL(bpf_redirect_info); > > +static struct net_device *skb_get_peer_dev(struct net_device *dev) > +{ > + const struct net_device_ops *ops = dev->netdev_ops; > + > + if (likely(ops->ndo_get_peer_dev)) > + return INDIRECT_CALL_1(ops->ndo_get_peer_dev, > + netkit_peer_dev, dev); nit: why not put both netkit and veth here under INDIRECT_CALL_2 ? Presumably should help with the veth deployments as well?