aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2017-08-11 19:41:17 +0800
committerDavid S. Miller <davem@davemloft.net>2017-08-13 19:56:07 -0700
commit7c4974786f4794178f04e96318fc3b2f2850cbc6 (patch)
tree3cef8e46105d414a0601ceb204a4fca0f66f3166 /net/core/dev.c
parenttap: use build_skb() for small packet (diff)
downloadlinux-dev-7c4974786f4794178f04e96318fc3b2f2850cbc6.tar.xz
linux-dev-7c4974786f4794178f04e96318fc3b2f2850cbc6.zip
net: export some generic xdp helpers
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 <jasowang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 1024d3741d12..40b28e417072 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -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;
@@ -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;
@@ -3971,6 +3970,7 @@ out_redir:
kfree_skb(skb);
return XDP_DROP;
}
+EXPORT_SYMBOL_GPL(do_xdp_generic);
static int netif_rx_internal(struct sk_buff *skb)
{
@@ -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
@@ -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();