Skip to content

Commit

Permalink
net: export some generic xdp helpers
Browse files Browse the repository at this point in the history
This patch tries to export some generic xdp helpers to drivers. This
can let driver to do XDP for a specific skb. This is useful for the
case when the packet is hard to be processed at page level directly
(e.g jumbo/GSO frame).

With this patch, there's no need for driver to forbid the XDP set when
configuration is not suitable. Instead, it can defer the XDP for
packets that is hard to be processed directly after skb is created.

Signed-off-by: Jason Wang <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
jasowang authored and davem330 committed Aug 14, 2017
1 parent 66ccbc9 commit 7c49747
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 6 deletions.
2 changes: 2 additions & 0 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -3243,6 +3243,8 @@ static inline void dev_consume_skb_any(struct sk_buff *skb)
__dev_kfree_skb_any(skb, SKB_REASON_CONSUMED);
}

void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog);
int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb);
int netif_rx(struct sk_buff *skb);
int netif_rx_ni(struct sk_buff *skb);
int netif_receive_skb(struct sk_buff *skb);
Expand Down
14 changes: 8 additions & 6 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -3919,7 +3919,7 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
/* When doing generic XDP we have to bypass the qdisc layer and the
* network taps in order to match in-driver-XDP behavior.
*/
static void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog)
void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog)
{
struct net_device *dev = skb->dev;
struct netdev_queue *txq;
Expand All @@ -3940,13 +3940,12 @@ static void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog)
kfree_skb(skb);
}
}
EXPORT_SYMBOL_GPL(generic_xdp_tx);

static struct static_key generic_xdp_needed __read_mostly;

static int do_xdp_generic(struct sk_buff *skb)
int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb)
{
struct bpf_prog *xdp_prog = rcu_dereference(skb->dev->xdp_prog);

if (xdp_prog) {
u32 act = netif_receive_generic_xdp(skb, xdp_prog);
int err;
Expand All @@ -3971,6 +3970,7 @@ static int do_xdp_generic(struct sk_buff *skb)
kfree_skb(skb);
return XDP_DROP;
}
EXPORT_SYMBOL_GPL(do_xdp_generic);

static int netif_rx_internal(struct sk_buff *skb)
{
Expand All @@ -3981,7 +3981,8 @@ static int netif_rx_internal(struct sk_buff *skb)
trace_netif_rx(skb);

if (static_key_false(&generic_xdp_needed)) {
int ret = do_xdp_generic(skb);
int ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog),
skb);

/* Consider XDP consuming the packet a success from
* the netdev point of view we do not want to count
Expand Down Expand Up @@ -4502,7 +4503,8 @@ static int netif_receive_skb_internal(struct sk_buff *skb)
rcu_read_lock();

if (static_key_false(&generic_xdp_needed)) {
int ret = do_xdp_generic(skb);
int ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog),
skb);

if (ret != XDP_PASS) {
rcu_read_unlock();
Expand Down

0 comments on commit 7c49747

Please sign in to comment.