diff options
| author | Alexei Starovoitov <ast@plumgrid.com> | 2015-09-16 02:05:43 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-09-18 00:09:07 -0400 |
| commit | 27b29f63058d26c6c1742f1993338280d5a41dc6 (patch) | |
| tree | 4a74088c6a959041fd267fcf03466ca7eea355e1 /samples | |
| parent | 045efa82ff563cd4e656ca1c2e354fa5bf6bbda4 (diff) | |
bpf: add bpf_redirect() helper
Existing bpf_clone_redirect() helper clones skb before redirecting
it to RX or TX of destination netdev.
Introduce bpf_redirect() helper that does that without cloning.
Benchmarked with two hosts using 10G ixgbe NICs.
One host is doing line rate pktgen.
Another host is configured as:
$ tc qdisc add dev $dev ingress
$ tc filter add dev $dev root pref 10 u32 match u32 0 0 flowid 1:2 \
action bpf run object-file tcbpf1_kern.o section clone_redirect_xmit drop
so it receives the packet on $dev and immediately xmits it on $dev + 1
The section 'clone_redirect_xmit' in tcbpf1_kern.o file has the program
that does bpf_clone_redirect() and performance is 2.0 Mpps
$ tc filter add dev $dev root pref 10 u32 match u32 0 0 flowid 1:2 \
action bpf run object-file tcbpf1_kern.o section redirect_xmit drop
which is using bpf_redirect() - 2.4 Mpps
and using cls_bpf with integrated actions as:
$ tc filter add dev $dev root pref 10 \
bpf run object-file tcbpf1_kern.o section redirect_xmit integ_act classid 1
performance is 2.5 Mpps
To summarize:
u32+act_bpf using clone_redirect - 2.0 Mpps
u32+act_bpf using redirect - 2.4 Mpps
cls_bpf using redirect - 2.5 Mpps
For comparison linux bridge in this setup is doing 2.1 Mpps
and ixgbe rx + drop in ip_rcv - 7.8 Mpps
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: John Fastabend <john.r.fastabend@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
| -rw-r--r-- | samples/bpf/bpf_helpers.h | 4 | ||||
| -rw-r--r-- | samples/bpf/tcbpf1_kern.c | 24 |
2 files changed, 27 insertions, 1 deletions
diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h index 3a44d3a272af..21aa1b44c30c 100644 --- a/samples/bpf/bpf_helpers.h +++ b/samples/bpf/bpf_helpers.h | |||
| @@ -33,6 +33,10 @@ static int (*bpf_get_current_comm)(void *buf, int buf_size) = | |||
| 33 | (void *) BPF_FUNC_get_current_comm; | 33 | (void *) BPF_FUNC_get_current_comm; |
| 34 | static int (*bpf_perf_event_read)(void *map, int index) = | 34 | static int (*bpf_perf_event_read)(void *map, int index) = |
| 35 | (void *) BPF_FUNC_perf_event_read; | 35 | (void *) BPF_FUNC_perf_event_read; |
| 36 | static int (*bpf_clone_redirect)(void *ctx, int ifindex, int flags) = | ||
| 37 | (void *) BPF_FUNC_clone_redirect; | ||
| 38 | static int (*bpf_redirect)(int ifindex, int flags) = | ||
| 39 | (void *) BPF_FUNC_redirect; | ||
| 36 | 40 | ||
| 37 | /* llvm builtin functions that eBPF C program may use to | 41 | /* llvm builtin functions that eBPF C program may use to |
| 38 | * emit BPF_LD_ABS and BPF_LD_IND instructions | 42 | * emit BPF_LD_ABS and BPF_LD_IND instructions |
diff --git a/samples/bpf/tcbpf1_kern.c b/samples/bpf/tcbpf1_kern.c index 9bfb2eb34563..fa051b3d53ee 100644 --- a/samples/bpf/tcbpf1_kern.c +++ b/samples/bpf/tcbpf1_kern.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #include <uapi/linux/in.h> | 5 | #include <uapi/linux/in.h> |
| 6 | #include <uapi/linux/tcp.h> | 6 | #include <uapi/linux/tcp.h> |
| 7 | #include <uapi/linux/filter.h> | 7 | #include <uapi/linux/filter.h> |
| 8 | 8 | #include <uapi/linux/pkt_cls.h> | |
| 9 | #include "bpf_helpers.h" | 9 | #include "bpf_helpers.h" |
| 10 | 10 | ||
| 11 | /* compiler workaround */ | 11 | /* compiler workaround */ |
| @@ -64,4 +64,26 @@ int bpf_prog1(struct __sk_buff *skb) | |||
| 64 | 64 | ||
| 65 | return 0; | 65 | return 0; |
| 66 | } | 66 | } |
| 67 | SEC("redirect_xmit") | ||
| 68 | int _redirect_xmit(struct __sk_buff *skb) | ||
| 69 | { | ||
| 70 | return bpf_redirect(skb->ifindex + 1, 0); | ||
| 71 | } | ||
| 72 | SEC("redirect_recv") | ||
| 73 | int _redirect_recv(struct __sk_buff *skb) | ||
| 74 | { | ||
| 75 | return bpf_redirect(skb->ifindex + 1, 1); | ||
| 76 | } | ||
| 77 | SEC("clone_redirect_xmit") | ||
| 78 | int _clone_redirect_xmit(struct __sk_buff *skb) | ||
| 79 | { | ||
| 80 | bpf_clone_redirect(skb, skb->ifindex + 1, 0); | ||
| 81 | return TC_ACT_SHOT; | ||
| 82 | } | ||
| 83 | SEC("clone_redirect_recv") | ||
| 84 | int _clone_redirect_recv(struct __sk_buff *skb) | ||
| 85 | { | ||
| 86 | bpf_clone_redirect(skb, skb->ifindex + 1, 1); | ||
| 87 | return TC_ACT_SHOT; | ||
| 88 | } | ||
| 67 | char _license[] SEC("license") = "GPL"; | 89 | char _license[] SEC("license") = "GPL"; |
