xdp: make generic xdp redirect use tracepoint trace_xdp_redirect
authorJesper Dangaard Brouer <brouer@redhat.com>
Thu, 24 Aug 2017 10:33:08 +0000 (12:33 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 24 Aug 2017 18:59:36 +0000 (11:59 -0700)
If the xdp_do_generic_redirect() call fails, it trigger the
trace_xdp_exception tracepoint.  It seems better to use the same
tracepoint trace_xdp_redirect, as the native xdp_do_redirect{,_map} does.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/filter.h
net/core/dev.c
net/core/filter.c

index 7015116331af9192cf7f72085849c3990f5a76f9..d29e58fde364f01168c059f85faac389622a3fc3 100644 (file)
@@ -718,7 +718,8 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
  * because we only track one map and force a flush when the map changes.
  * This does not appear to be a real limitation for existing software.
  */
-int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb);
+int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb,
+                           struct bpf_prog *prog);
 int xdp_do_redirect(struct net_device *dev,
                    struct xdp_buff *xdp,
                    struct bpf_prog *prog);
index 40b28e417072e20df866a6988f048d5262a4b445..270b547548213438c6cde035205758c08105ba9a 100644 (file)
@@ -3953,7 +3953,8 @@ int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb)
                if (act != XDP_PASS) {
                        switch (act) {
                        case XDP_REDIRECT:
-                               err = xdp_do_generic_redirect(skb->dev, skb);
+                               err = xdp_do_generic_redirect(skb->dev, skb,
+                                                             xdp_prog);
                                if (err)
                                        goto out_redir;
                        /* fallthru to submit skb */
@@ -3966,7 +3967,6 @@ int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb)
        }
        return XDP_PASS;
 out_redir:
-       trace_xdp_exception(skb->dev, xdp_prog, XDP_REDIRECT);
        kfree_skb(skb);
        return XDP_DROP;
 }
index a5e5f31b41b955098d9adf5b00b5a0eda4f832e3..a046803310338c2de9f17a5017d7d4730c4eb31e 100644 (file)
@@ -2553,26 +2553,37 @@ out:
 }
 EXPORT_SYMBOL_GPL(xdp_do_redirect);
 
-int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb)
+int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb,
+                           struct bpf_prog *xdp_prog)
 {
        struct redirect_info *ri = this_cpu_ptr(&redirect_info);
-       unsigned int len;
        u32 index = ri->ifindex;
+       struct net_device *fwd;
+       unsigned int len;
+       int err = 0;
 
-       dev = dev_get_by_index_rcu(dev_net(dev), index);
+       fwd = dev_get_by_index_rcu(dev_net(dev), index);
        ri->ifindex = 0;
-       if (unlikely(!dev)) {
-               return -EINVAL;
+       if (unlikely(!fwd)) {
+               err = -EINVAL;
+               goto out;
        }
 
-       if (unlikely(!(dev->flags & IFF_UP)))
-               return -ENETDOWN;
-       len = dev->mtu + dev->hard_header_len + VLAN_HLEN;
-       if (skb->len > len)
-               return -E2BIG;
+       if (unlikely(!(fwd->flags & IFF_UP))) {
+               err = -ENETDOWN;
+               goto out;
+       }
 
-       skb->dev = dev;
-       return 0;
+       len = fwd->mtu + fwd->hard_header_len + VLAN_HLEN;
+       if (skb->len > len) {
+               err = -EMSGSIZE;
+               goto out;
+       }
+
+       skb->dev = fwd;
+out:
+       trace_xdp_redirect(dev, fwd, xdp_prog, XDP_REDIRECT, err);
+       return err;
 }
 EXPORT_SYMBOL_GPL(xdp_do_generic_redirect);