aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorBrenden Blanco <bblanco@plumgrid.com>2016-07-19 15:16:51 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-20 00:46:32 -0400
commit86af8b4191d20bb17e868d3167f4cf52ca9331d0 (patch)
treec87d8d918254983fe7625ac6edaf0bf6309eb564 /samples
parent47a38e155037f417c5740e24ccae6482aedf4b68 (diff)
Add sample for adding simple drop program to link
Add a sample program that only drops packets at the BPF_PROG_TYPE_XDP_RX hook of a link. With the drop-only program, observed single core rate is ~20Mpps. Other tests were run, for instance without the dropcnt increment or without reading from the packet header, the packet rate was mostly unchanged. $ perf record -a samples/bpf/xdp1 $(</sys/class/net/eth0/ifindex) proto 17: 20403027 drops/s ./pktgen_sample03_burst_single_flow.sh -i $DEV -d $IP -m $MAC -t 4 Running... ctrl^C to stop Device: eth4@0 Result: OK: 11791017(c11788327+d2689) usec, 59622913 (60byte,0frags) 5056638pps 2427Mb/sec (2427186240bps) errors: 0 Device: eth4@1 Result: OK: 11791012(c11787906+d3106) usec, 60526944 (60byte,0frags) 5133311pps 2463Mb/sec (2463989280bps) errors: 0 Device: eth4@2 Result: OK: 11791019(c11788249+d2769) usec, 59868091 (60byte,0frags) 5077431pps 2437Mb/sec (2437166880bps) errors: 0 Device: eth4@3 Result: OK: 11795039(c11792403+d2636) usec, 59483181 (60byte,0frags) 5043067pps 2420Mb/sec (2420672160bps) errors: 0 perf report --no-children: 26.05% ksoftirqd/0 [mlx4_en] [k] mlx4_en_process_rx_cq 17.84% ksoftirqd/0 [mlx4_en] [k] mlx4_en_alloc_frags 5.52% ksoftirqd/0 [mlx4_en] [k] mlx4_en_free_frag 4.90% swapper [kernel.vmlinux] [k] poll_idle 4.14% ksoftirqd/0 [kernel.vmlinux] [k] get_page_from_freelist 2.78% ksoftirqd/0 [kernel.vmlinux] [k] __free_pages_ok 2.57% ksoftirqd/0 [kernel.vmlinux] [k] bpf_map_lookup_elem 2.51% swapper [mlx4_en] [k] mlx4_en_process_rx_cq 1.94% ksoftirqd/0 [kernel.vmlinux] [k] percpu_array_map_lookup_elem 1.45% swapper [mlx4_en] [k] mlx4_en_alloc_frags 1.35% ksoftirqd/0 [kernel.vmlinux] [k] free_one_page 1.33% swapper [kernel.vmlinux] [k] intel_idle 1.04% ksoftirqd/0 [mlx4_en] [k] 0x000000000001c5c5 0.96% ksoftirqd/0 [mlx4_en] [k] 0x000000000001c58d 0.93% ksoftirqd/0 [mlx4_en] [k] 0x000000000001c6ee 0.92% ksoftirqd/0 [mlx4_en] [k] 0x000000000001c6b9 0.89% ksoftirqd/0 [kernel.vmlinux] [k] __alloc_pages_nodemask 0.83% ksoftirqd/0 [mlx4_en] [k] 0x000000000001c686 0.83% ksoftirqd/0 [mlx4_en] [k] 0x000000000001c5d5 0.78% ksoftirqd/0 [mlx4_en] [k] mlx4_alloc_pages.isra.23 0.77% ksoftirqd/0 [mlx4_en] [k] 0x000000000001c5b4 0.77% ksoftirqd/0 [kernel.vmlinux] [k] net_rx_action machine specs: receiver - Intel E5-1630 v3 @ 3.70GHz sender - Intel E5645 @ 2.40GHz Mellanox ConnectX-3 @40G Signed-off-by: Brenden Blanco <bblanco@plumgrid.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
-rw-r--r--samples/bpf/Makefile4
-rw-r--r--samples/bpf/bpf_load.c8
-rw-r--r--samples/bpf/xdp1_kern.c93
-rw-r--r--samples/bpf/xdp1_user.c181
4 files changed, 286 insertions, 0 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index a98b780e974c..0e4ab3a9dfa9 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -21,6 +21,7 @@ hostprogs-y += spintest
21hostprogs-y += map_perf_test 21hostprogs-y += map_perf_test
22hostprogs-y += test_overhead 22hostprogs-y += test_overhead
23hostprogs-y += test_cgrp2_array_pin 23hostprogs-y += test_cgrp2_array_pin
24hostprogs-y += xdp1
24 25
25test_verifier-objs := test_verifier.o libbpf.o 26test_verifier-objs := test_verifier.o libbpf.o
26test_maps-objs := test_maps.o libbpf.o 27test_maps-objs := test_maps.o libbpf.o
@@ -42,6 +43,7 @@ spintest-objs := bpf_load.o libbpf.o spintest_user.o
42map_perf_test-objs := bpf_load.o libbpf.o map_perf_test_user.o 43map_perf_test-objs := bpf_load.o libbpf.o map_perf_test_user.o
43test_overhead-objs := bpf_load.o libbpf.o test_overhead_user.o 44test_overhead-objs := bpf_load.o libbpf.o test_overhead_user.o
44test_cgrp2_array_pin-objs := libbpf.o test_cgrp2_array_pin.o 45test_cgrp2_array_pin-objs := libbpf.o test_cgrp2_array_pin.o
46xdp1-objs := bpf_load.o libbpf.o xdp1_user.o
45 47
46# Tell kbuild to always build the programs 48# Tell kbuild to always build the programs
47always := $(hostprogs-y) 49always := $(hostprogs-y)
@@ -64,6 +66,7 @@ always += test_overhead_tp_kern.o
64always += test_overhead_kprobe_kern.o 66always += test_overhead_kprobe_kern.o
65always += parse_varlen.o parse_simple.o parse_ldabs.o 67always += parse_varlen.o parse_simple.o parse_ldabs.o
66always += test_cgrp2_tc_kern.o 68always += test_cgrp2_tc_kern.o
69always += xdp1_kern.o
67 70
68HOSTCFLAGS += -I$(objtree)/usr/include 71HOSTCFLAGS += -I$(objtree)/usr/include
69 72
@@ -84,6 +87,7 @@ HOSTLOADLIBES_offwaketime += -lelf
84HOSTLOADLIBES_spintest += -lelf 87HOSTLOADLIBES_spintest += -lelf
85HOSTLOADLIBES_map_perf_test += -lelf -lrt 88HOSTLOADLIBES_map_perf_test += -lelf -lrt
86HOSTLOADLIBES_test_overhead += -lelf -lrt 89HOSTLOADLIBES_test_overhead += -lelf -lrt
90HOSTLOADLIBES_xdp1 += -lelf
87 91
88# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline: 92# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline:
89# make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang 93# make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 022af71c2bb5..0cfda2320320 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -50,6 +50,7 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
50 bool is_kprobe = strncmp(event, "kprobe/", 7) == 0; 50 bool is_kprobe = strncmp(event, "kprobe/", 7) == 0;
51 bool is_kretprobe = strncmp(event, "kretprobe/", 10) == 0; 51 bool is_kretprobe = strncmp(event, "kretprobe/", 10) == 0;
52 bool is_tracepoint = strncmp(event, "tracepoint/", 11) == 0; 52 bool is_tracepoint = strncmp(event, "tracepoint/", 11) == 0;
53 bool is_xdp = strncmp(event, "xdp", 3) == 0;
53 enum bpf_prog_type prog_type; 54 enum bpf_prog_type prog_type;
54 char buf[256]; 55 char buf[256];
55 int fd, efd, err, id; 56 int fd, efd, err, id;
@@ -66,6 +67,8 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
66 prog_type = BPF_PROG_TYPE_KPROBE; 67 prog_type = BPF_PROG_TYPE_KPROBE;
67 } else if (is_tracepoint) { 68 } else if (is_tracepoint) {
68 prog_type = BPF_PROG_TYPE_TRACEPOINT; 69 prog_type = BPF_PROG_TYPE_TRACEPOINT;
70 } else if (is_xdp) {
71 prog_type = BPF_PROG_TYPE_XDP;
69 } else { 72 } else {
70 printf("Unknown event '%s'\n", event); 73 printf("Unknown event '%s'\n", event);
71 return -1; 74 return -1;
@@ -79,6 +82,9 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
79 82
80 prog_fd[prog_cnt++] = fd; 83 prog_fd[prog_cnt++] = fd;
81 84
85 if (is_xdp)
86 return 0;
87
82 if (is_socket) { 88 if (is_socket) {
83 event += 6; 89 event += 6;
84 if (*event != '/') 90 if (*event != '/')
@@ -319,6 +325,7 @@ int load_bpf_file(char *path)
319 if (memcmp(shname_prog, "kprobe/", 7) == 0 || 325 if (memcmp(shname_prog, "kprobe/", 7) == 0 ||
320 memcmp(shname_prog, "kretprobe/", 10) == 0 || 326 memcmp(shname_prog, "kretprobe/", 10) == 0 ||
321 memcmp(shname_prog, "tracepoint/", 11) == 0 || 327 memcmp(shname_prog, "tracepoint/", 11) == 0 ||
328 memcmp(shname_prog, "xdp", 3) == 0 ||
322 memcmp(shname_prog, "socket", 6) == 0) 329 memcmp(shname_prog, "socket", 6) == 0)
323 load_and_attach(shname_prog, insns, data_prog->d_size); 330 load_and_attach(shname_prog, insns, data_prog->d_size);
324 } 331 }
@@ -336,6 +343,7 @@ int load_bpf_file(char *path)
336 if (memcmp(shname, "kprobe/", 7) == 0 || 343 if (memcmp(shname, "kprobe/", 7) == 0 ||
337 memcmp(shname, "kretprobe/", 10) == 0 || 344 memcmp(shname, "kretprobe/", 10) == 0 ||
338 memcmp(shname, "tracepoint/", 11) == 0 || 345 memcmp(shname, "tracepoint/", 11) == 0 ||
346 memcmp(shname, "xdp", 3) == 0 ||
339 memcmp(shname, "socket", 6) == 0) 347 memcmp(shname, "socket", 6) == 0)
340 load_and_attach(shname, data->d_buf, data->d_size); 348 load_and_attach(shname, data->d_buf, data->d_size);
341 } 349 }
diff --git a/samples/bpf/xdp1_kern.c b/samples/bpf/xdp1_kern.c
new file mode 100644
index 000000000000..e7dd8ac40d12
--- /dev/null
+++ b/samples/bpf/xdp1_kern.c
@@ -0,0 +1,93 @@
1/* Copyright (c) 2016 PLUMgrid
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of version 2 of the GNU General Public
5 * License as published by the Free Software Foundation.
6 */
7#define KBUILD_MODNAME "foo"
8#include <uapi/linux/bpf.h>
9#include <linux/in.h>
10#include <linux/if_ether.h>
11#include <linux/if_packet.h>
12#include <linux/if_vlan.h>
13#include <linux/ip.h>
14#include <linux/ipv6.h>
15#include "bpf_helpers.h"
16
17struct bpf_map_def SEC("maps") dropcnt = {
18 .type = BPF_MAP_TYPE_PERCPU_ARRAY,
19 .key_size = sizeof(u32),
20 .value_size = sizeof(long),
21 .max_entries = 256,
22};
23
24static int parse_ipv4(void *data, u64 nh_off, void *data_end)
25{
26 struct iphdr *iph = data + nh_off;
27
28 if (iph + 1 > data_end)
29 return 0;
30 return iph->protocol;
31}
32
33static int parse_ipv6(void *data, u64 nh_off, void *data_end)
34{
35 struct ipv6hdr *ip6h = data + nh_off;
36
37 if (ip6h + 1 > data_end)
38 return 0;
39 return ip6h->nexthdr;
40}
41
42SEC("xdp1")
43int xdp_prog1(struct xdp_md *ctx)
44{
45 void *data_end = (void *)(long)ctx->data_end;
46 void *data = (void *)(long)ctx->data;
47 struct ethhdr *eth = data;
48 int rc = XDP_DROP;
49 long *value;
50 u16 h_proto;
51 u64 nh_off;
52 u32 index;
53
54 nh_off = sizeof(*eth);
55 if (data + nh_off > data_end)
56 return rc;
57
58 h_proto = eth->h_proto;
59
60 if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) {
61 struct vlan_hdr *vhdr;
62
63 vhdr = data + nh_off;
64 nh_off += sizeof(struct vlan_hdr);
65 if (data + nh_off > data_end)
66 return rc;
67 h_proto = vhdr->h_vlan_encapsulated_proto;
68 }
69 if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) {
70 struct vlan_hdr *vhdr;
71
72 vhdr = data + nh_off;
73 nh_off += sizeof(struct vlan_hdr);
74 if (data + nh_off > data_end)
75 return rc;
76 h_proto = vhdr->h_vlan_encapsulated_proto;
77 }
78
79 if (h_proto == htons(ETH_P_IP))
80 index = parse_ipv4(data, nh_off, data_end);
81 else if (h_proto == htons(ETH_P_IPV6))
82 index = parse_ipv6(data, nh_off, data_end);
83 else
84 index = 0;
85
86 value = bpf_map_lookup_elem(&dropcnt, &index);
87 if (value)
88 *value += 1;
89
90 return rc;
91}
92
93char _license[] SEC("license") = "GPL";
diff --git a/samples/bpf/xdp1_user.c b/samples/bpf/x