aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
Diffstat (limited to 'samples')
-rw-r--r--samples/Kconfig7
-rw-r--r--samples/Makefile2
-rw-r--r--samples/bpf/Makefile16
-rw-r--r--samples/bpf/bpf_helpers.h4
-rw-r--r--samples/bpf/bpf_load.c8
-rw-r--r--samples/bpf/sockex2_user.c3
-rw-r--r--samples/bpf/sockex3_user.c3
-rw-r--r--samples/bpf/test_cgrp2_array_pin.c109
-rwxr-xr-xsamples/bpf/test_cgrp2_tc.sh184
-rw-r--r--samples/bpf/test_cgrp2_tc_kern.c69
-rw-r--r--samples/bpf/test_probe_write_user_kern.c52
-rw-r--r--samples/bpf/test_probe_write_user_user.c78
-rw-r--r--samples/bpf/xdp1_kern.c93
-rw-r--r--samples/bpf/xdp1_user.c181
-rw-r--r--samples/bpf/xdp2_kern.c114
-rw-r--r--samples/kprobes/kprobe_example.c9
-rw-r--r--samples/pktgen/parameters.sh7
-rwxr-xr-xsamples/pktgen/pktgen.conf-1-1-flows67
-rwxr-xr-xsamples/pktgen/pktgen.conf-1-1-rdos64
-rwxr-xr-xsamples/pktgen/pktgen_bench_xmit_mode_netif_receive.sh6
-rwxr-xr-xsamples/pktgen/pktgen_bench_xmit_mode_queue_xmit.sh68
-rwxr-xr-xsamples/pktgen/pktgen_sample01_simple.sh6
-rwxr-xr-xsamples/pktgen/pktgen_sample02_multiqueue.sh6
-rwxr-xr-xsamples/pktgen/pktgen_sample03_burst_single_flow.sh6
-rwxr-xr-xsamples/pktgen/pktgen_sample04_many_flows.sh93
-rwxr-xr-xsamples/pktgen/pktgen_sample05_flow_per_thread.sh81
-rw-r--r--samples/trace_printk/Makefile6
-rw-r--r--samples/trace_printk/trace-printk.c56
-rw-r--r--samples/v4l/v4l2-pci-skeleton.c17
29 files changed, 1260 insertions, 155 deletions
diff --git a/samples/Kconfig b/samples/Kconfig
index ccc50beaf17b..85c405fcccb0 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -11,6 +11,13 @@ config SAMPLE_TRACE_EVENTS
11 help 11 help
12 This build trace event example modules. 12 This build trace event example modules.
13 13
14config SAMPLE_TRACE_PRINTK
15 tristate "Build trace_printk module - tests various trace_printk formats"
16 depends on EVENT_TRACING && m
17 help
18 This builds a module that calls trace_printk() and can be used to
19 test various trace_printk() calls from a module.
20
14config SAMPLE_KOBJECT 21config SAMPLE_KOBJECT
15 tristate "Build kobject examples -- loadable modules only" 22 tristate "Build kobject examples -- loadable modules only"
16 depends on m 23 depends on m
diff --git a/samples/Makefile b/samples/Makefile
index 2e3b523d7097..1a20169d85ac 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -2,4 +2,4 @@
2 2
3obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ livepatch/ \ 3obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ livepatch/ \
4 hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \ 4 hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \
5 configfs/ connector/ v4l/ 5 configfs/ connector/ v4l/ trace_printk/
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 0bf2478cb7df..90ebf7d35c07 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -14,12 +14,16 @@ hostprogs-y += tracex3
14hostprogs-y += tracex4 14hostprogs-y += tracex4
15hostprogs-y += tracex5 15hostprogs-y += tracex5
16hostprogs-y += tracex6 16hostprogs-y += tracex6
17hostprogs-y += test_probe_write_user
17hostprogs-y += trace_output 18hostprogs-y += trace_output
18hostprogs-y += lathist 19hostprogs-y += lathist
19hostprogs-y += offwaketime 20hostprogs-y += offwaketime
20hostprogs-y += spintest 21hostprogs-y += spintest
21hostprogs-y += map_perf_test 22hostprogs-y += map_perf_test
22hostprogs-y += test_overhead 23hostprogs-y += test_overhead
24hostprogs-y += test_cgrp2_array_pin
25hostprogs-y += xdp1
26hostprogs-y += xdp2
23 27
24test_verifier-objs := test_verifier.o libbpf.o 28test_verifier-objs := test_verifier.o libbpf.o
25test_maps-objs := test_maps.o libbpf.o 29test_maps-objs := test_maps.o libbpf.o
@@ -34,12 +38,17 @@ tracex3-objs := bpf_load.o libbpf.o tracex3_user.o
34tracex4-objs := bpf_load.o libbpf.o tracex4_user.o 38tracex4-objs := bpf_load.o libbpf.o tracex4_user.o
35tracex5-objs := bpf_load.o libbpf.o tracex5_user.o 39tracex5-objs := bpf_load.o libbpf.o tracex5_user.o
36tracex6-objs := bpf_load.o libbpf.o tracex6_user.o 40tracex6-objs := bpf_load.o libbpf.o tracex6_user.o
41test_probe_write_user-objs := bpf_load.o libbpf.o test_probe_write_user_user.o
37trace_output-objs := bpf_load.o libbpf.o trace_output_user.o 42trace_output-objs := bpf_load.o libbpf.o trace_output_user.o
38lathist-objs := bpf_load.o libbpf.o lathist_user.o 43lathist-objs := bpf_load.o libbpf.o lathist_user.o
39offwaketime-objs := bpf_load.o libbpf.o offwaketime_user.o 44offwaketime-objs := bpf_load.o libbpf.o offwaketime_user.o
40spintest-objs := bpf_load.o libbpf.o spintest_user.o 45spintest-objs := bpf_load.o libbpf.o spintest_user.o
41map_perf_test-objs := bpf_load.o libbpf.o map_perf_test_user.o 46map_perf_test-objs := bpf_load.o libbpf.o map_perf_test_user.o
42test_overhead-objs := bpf_load.o libbpf.o test_overhead_user.o 47test_overhead-objs := bpf_load.o libbpf.o test_overhead_user.o
48test_cgrp2_array_pin-objs := libbpf.o test_cgrp2_array_pin.o
49xdp1-objs := bpf_load.o libbpf.o xdp1_user.o
50# reuse xdp1 source intentionally
51xdp2-objs := bpf_load.o libbpf.o xdp1_user.o
43 52
44# Tell kbuild to always build the programs 53# Tell kbuild to always build the programs
45always := $(hostprogs-y) 54always := $(hostprogs-y)
@@ -52,6 +61,7 @@ always += tracex3_kern.o
52always += tracex4_kern.o 61always += tracex4_kern.o
53always += tracex5_kern.o 62always += tracex5_kern.o
54always += tracex6_kern.o 63always += tracex6_kern.o
64always += test_probe_write_user_kern.o
55always += trace_output_kern.o 65always += trace_output_kern.o
56always += tcbpf1_kern.o 66always += tcbpf1_kern.o
57always += lathist_kern.o 67always += lathist_kern.o
@@ -61,6 +71,9 @@ always += map_perf_test_kern.o
61always += test_overhead_tp_kern.o 71always += test_overhead_tp_kern.o
62always += test_overhead_kprobe_kern.o 72always += test_overhead_kprobe_kern.o
63always += parse_varlen.o parse_simple.o parse_ldabs.o 73always += parse_varlen.o parse_simple.o parse_ldabs.o
74always += test_cgrp2_tc_kern.o
75always += xdp1_kern.o
76always += xdp2_kern.o
64 77
65HOSTCFLAGS += -I$(objtree)/usr/include 78HOSTCFLAGS += -I$(objtree)/usr/include
66 79
@@ -75,12 +88,15 @@ HOSTLOADLIBES_tracex3 += -lelf
75HOSTLOADLIBES_tracex4 += -lelf -lrt 88HOSTLOADLIBES_tracex4 += -lelf -lrt
76HOSTLOADLIBES_tracex5 += -lelf 89HOSTLOADLIBES_tracex5 += -lelf
77HOSTLOADLIBES_tracex6 += -lelf 90HOSTLOADLIBES_tracex6 += -lelf
91HOSTLOADLIBES_test_probe_write_user += -lelf
78HOSTLOADLIBES_trace_output += -lelf -lrt 92HOSTLOADLIBES_trace_output += -lelf -lrt
79HOSTLOADLIBES_lathist += -lelf 93HOSTLOADLIBES_lathist += -lelf
80HOSTLOADLIBES_offwaketime += -lelf 94HOSTLOADLIBES_offwaketime += -lelf
81HOSTLOADLIBES_spintest += -lelf 95HOSTLOADLIBES_spintest += -lelf
82HOSTLOADLIBES_map_perf_test += -lelf -lrt 96HOSTLOADLIBES_map_perf_test += -lelf -lrt
83HOSTLOADLIBES_test_overhead += -lelf -lrt 97HOSTLOADLIBES_test_overhead += -lelf -lrt
98HOSTLOADLIBES_xdp1 += -lelf
99HOSTLOADLIBES_xdp2 += -lelf
84 100
85# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline: 101# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline:
86# make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang 102# make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang
diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h
index 7904a2a493de..217c8d507f2e 100644
--- a/samples/bpf/bpf_helpers.h
+++ b/samples/bpf/bpf_helpers.h
@@ -41,6 +41,8 @@ static int (*bpf_perf_event_output)(void *ctx, void *map, int index, void *data,
41 (void *) BPF_FUNC_perf_event_output; 41 (void *) BPF_FUNC_perf_event_output;
42static int (*bpf_get_stackid)(void *ctx, void *map, int flags) = 42static int (*bpf_get_stackid)(void *ctx, void *map, int flags) =
43 (void *) BPF_FUNC_get_stackid; 43 (void *) BPF_FUNC_get_stackid;
44static int (*bpf_probe_write_user)(void *dst, void *src, int size) =
45 (void *) BPF_FUNC_probe_write_user;
44 46
45/* llvm builtin functions that eBPF C program may use to 47/* llvm builtin functions that eBPF C program may use to
46 * emit BPF_LD_ABS and BPF_LD_IND instructions 48 * emit BPF_LD_ABS and BPF_LD_IND instructions
@@ -70,6 +72,8 @@ static int (*bpf_l3_csum_replace)(void *ctx, int off, int from, int to, int flag
70 (void *) BPF_FUNC_l3_csum_replace; 72 (void *) BPF_FUNC_l3_csum_replace;
71static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flags) = 73static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flags) =
72 (void *) BPF_FUNC_l4_csum_replace; 74 (void *) BPF_FUNC_l4_csum_replace;
75static int (*bpf_skb_in_cgroup)(void *ctx, void *map, int index) =
76 (void *) BPF_FUNC_skb_in_cgroup;
73 77
74#if defined(__x86_64__) 78#if defined(__x86_64__)
75 79
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/sockex2_user.c b/samples/bpf/sockex2_user.c
index 29a276d766fc..8a4085c2d117 100644
--- a/samples/bpf/sockex2_user.c
+++ b/samples/bpf/sockex2_user.c
@@ -5,6 +5,7 @@
5#include "bpf_load.h" 5#include "bpf_load.h"
6#include <unistd.h> 6#include <unistd.h>
7#include <arpa/inet.h> 7#include <arpa/inet.h>
8#include <sys/resource.h>
8 9
9struct pair { 10struct pair {
10 __u64 packets; 11 __u64 packets;
@@ -13,11 +14,13 @@ struct pair {
13 14
14int main(int ac, char **argv) 15int main(int ac, char **argv)
15{ 16{
17 struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
16 char filename[256]; 18 char filename[256];
17 FILE *f; 19 FILE *f;
18 int i, sock; 20 int i, sock;
19 21
20 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); 22 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
23 setrlimit(RLIMIT_MEMLOCK, &r);
21 24
22 if (load_bpf_file(filename)) { 25 if (load_bpf_file(filename)) {
23 printf("%s", bpf_log_buf); 26 printf("%s", bpf_log_buf);
diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c
index 2617772d060d..d4184ab5f3ac 100644
--- a/samples/bpf/sockex3_user.c
+++ b/samples/bpf/sockex3_user.c
@@ -5,6 +5,7 @@
5#include "bpf_load.h" 5#include "bpf_load.h"
6#include <unistd.h> 6#include <unistd.h>
7#include <arpa/inet.h> 7#include <arpa/inet.h>
8#include <sys/resource.h>
8 9
9struct flow_keys { 10struct flow_keys {
10 __be32 src; 11 __be32 src;
@@ -23,11 +24,13 @@ struct pair {
23 24
24int main(int argc, char **argv) 25int main(int argc, char **argv)
25{ 26{
27 struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
26 char filename[256]; 28 char filename[256];
27 FILE *f; 29 FILE *f;
28 int i, sock; 30 int i, sock;
29 31
30 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); 32 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
33 setrlimit(RLIMIT_MEMLOCK, &r);
31 34
32 if (load_bpf_file(filename)) { 35 if (load_bpf_file(filename)) {
33 printf("%s", bpf_log_buf); 36 printf("%s", bpf_log_buf);
diff --git a/samples/bpf/test_cgrp2_array_pin.c b/samples/bpf/test_cgrp2_array_pin.c
new file mode 100644
index 000000000000..70e86f7be69d
--- /dev/null
+++ b/samples/bpf/test_cgrp2_array_pin.c
@@ -0,0 +1,109 @@
1/* Copyright (c) 2016 Facebook
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#include <linux/unistd.h>
8#include <linux/bpf.h>
9
10#include <stdio.h>
11#include <stdint.h>
12#include <unistd.h>
13#include <string.h>
14#include <errno.h>
15#include <fcntl.h>
16
17#include "libbpf.h"
18
19static void usage(void)
20{
21 printf("Usage: test_cgrp2_array_pin [...]\n");
22 printf(" -F <file> File to pin an BPF cgroup array\n");
23 printf(" -U <file> Update an already pinned BPF cgroup array\n");
24 printf(" -v <value> Full path of the cgroup2\n");
25 printf(" -h Display this help\n");
26}
27
28int main(int argc, char **argv)
29{
30 const char *pinned_file = NULL, *cg2 = NULL;
31 int create_array = 1;
32 int array_key = 0;
33 int array_fd = -1;
34 int cg2_fd = -1;
35 int ret = -1;
36 int opt;
37
38 while ((opt = getopt(argc, argv, "F:U:v:")) != -1) {
39 switch (opt) {
40 /* General args */
41 case 'F':
42 pinned_file = optarg;
43 break;
44 case 'U':
45 pinned_file = optarg;
46 create_array = 0;
47 break;
48 case 'v':
49 cg2 = optarg;
50 break;
51 default:
52 usage();
53 goto out;
54 }
55 }
56
57 if (!cg2 || !pinned_file) {
58 usage();
59 goto out;
60 }
61
62 cg2_fd = open(cg2, O_RDONLY);
63 if (cg2_fd < 0) {
64 fprintf(stderr, "open(%s,...): %s(%d)\n",
65 cg2, strerror(errno), errno);
66 goto out;
67 }
68
69 if (create_array) {
70 array_fd = bpf_create_map(BPF_MAP_TYPE_CGROUP_ARRAY,
71 sizeof(uint32_t), sizeof(uint32_t),
72 1, 0);
73 if (array_fd < 0) {
74 fprintf(stderr,
75 "bpf_create_map(BPF_MAP_TYPE_CGROUP_ARRAY,...): %s(%d)\n",
76 strerror(errno), errno);
77 goto out;
78 }
79 } else {
80 array_fd = bpf_obj_get(pinned_file);
81 if (array_fd < 0) {
82 fprintf(stderr, "bpf_obj_get(%s): %s(%d)\n",
83 pinned_file, strerror(errno), errno);
84 goto out;
85 }
86 }
87
88 ret = bpf_update_elem(array_fd, &array_key, &cg2_fd, 0);
89 if (ret) {
90 perror("bpf_update_elem");
91 goto out;
92 }
93
94 if (create_array) {
95 ret = bpf_obj_pin(array_fd, pinned_file);
96 if (ret) {
97 fprintf(stderr, "bpf_obj_pin(..., %s): %s(%d)\n",
98 pinned_file, strerror(errno), errno);
99 goto out;
100 }
101 }
102
103out:
104 if (array_fd != -1)
105 close(array_fd);
106 if (cg2_fd != -1)
107 close(cg2_fd);
108 return ret;
109}
diff --git a/samples/bpf/test_cgrp2_tc.sh b/samples/bpf/test_cgrp2_tc.sh
new file mode 100755
index 000000000000..0b119eeaf85c
--- /dev/null
+++ b/samples/bpf/test_cgrp2_tc.sh
@@ -0,0 +1,184 @@
1#!/bin/bash
2
3MY_DIR=$(dirname $0)
4# Details on the bpf prog
5BPF_CGRP2_ARRAY_NAME='test_cgrp2_array_pin'
6BPF_PROG="$MY_DIR/test_cgrp2_tc_kern.o"
7BPF_SECTION='filter'
8
9[ -z "$TC" ] && TC='tc'
10[ -z "$IP" ] && IP='ip'
11
12# Names of the veth interface, net namespace...etc.
13HOST_IFC='ve'
14NS_IFC='vens'
15NS='ns'
16
17find_mnt() {
18 cat /proc/mounts | \
19 awk '{ if ($3 == "'$1'" && mnt == "") { mnt = $2 }} END { print mnt }'
20}
21
22# Init cgroup2 vars
23init_cgrp2_vars() {
24 CGRP2_ROOT=$(find_mnt cgroup2)
25 if [ -z "$CGRP2_ROOT" ]
26 then
27 CGRP2_ROOT='/mnt/cgroup2'
28 MOUNT_CGRP2="yes"
29 fi
30 CGRP2_TC="$CGRP2_ROOT/tc"
31 CGRP2_TC_LEAF="$CGRP2_TC/leaf"
32}
33
34# Init bpf fs vars
35init_bpf_fs_vars() {
36 local bpf_fs_root=$(find_mnt bpf)
37 [ -n "$bpf_fs_root" ] || return -1
38 BPF_FS_TC_SHARE="$bpf_fs_root/tc/globals"
39}
40
41setup_cgrp2() {
42 case $1 in
43 start)
44 if [ "$MOUNT_CGRP2" == 'yes' ]
45 then
46 [ -d $CGRP2_ROOT ] || mkdir -p $CGRP2_ROOT
47 mount -t cgroup2 none $CGRP2_ROOT || return $?
48 fi
49 mkdir -p $CGRP2_TC_LEAF
50 ;;
51 *)
52 rmdir $CGRP2_TC_LEAF && rmdir $CGRP2_TC
53 [ "$MOUNT_CGRP2" == 'yes' ] && umount $CGRP2_ROOT
54 ;;
55 esac
56}
57
58setup_bpf_cgrp2_array() {
59 local bpf_cgrp2_array="$BPF_FS_TC_SHARE/$BPF_CGRP2_ARRAY_NAME"
60 case $1 in
61 start)
62 $MY_DIR/test_cgrp2_array_pin -U $bpf_cgrp2_array -v $CGRP2_TC
63 ;;
64 *)
65 [ -d "$BPF_FS_TC_SHARE" ] && rm -f $bpf_cgrp2_array
66 ;;
67 esac
68}
69
70setup_net() {
71 case $1 in
72 start)
73 $IP link add $HOST_IFC type veth peer name $NS_IFC || return $?
74 $IP link set dev $HOST_IFC up || return $?
75 sysctl -q net.ipv6.conf.$HOST_IFC.accept_dad=0
76
77 $IP netns add ns || return $?
78 $IP link set dev $NS_IFC netns ns || return $?
79 $IP -n $NS link set dev $NS_IFC up || return $?
80 $IP netns exec $NS sysctl -q net.ipv6.conf.$NS_IFC.accept_dad=0
81 $TC qdisc add dev $HOST_IFC clsact || return $?
82 $TC filter add dev $HOST_IFC egress bpf da obj $BPF_PROG sec $BPF_SECTION || return $?
83 ;;
84 *)
85 $IP netns del $NS
86 $IP link del $HOST_IFC
87 ;;
88 esac
89}
90
91run_in_cgrp() {
92 # Fork another bash and move it under the specified cgroup.
93 # It makes the cgroup cleanup easier at the end of the test.
94 cmd='echo $$ > '
95 cmd="$cmd $1/cgroup.procs; exec $2"
96 bash -c "$cmd"
97}
98
99do_test() {
100 run_in_cgrp $CGRP2_TC_LEAF "ping -6 -c3 ff02::1%$HOST_IFC >& /dev/null"
101 local dropped=$($TC -s qdisc show dev $HOST_IFC | tail -3 | \
102 awk '/drop/{print substr($7, 0, index($7, ",")-1)}')
103 if [[ $dropped -eq 0 ]]
104 then
105 echo "FAIL"
106 return 1
107 else
108 echo "Successfully filtered $dropped packets"
109 return 0
110 fi
111}
112
113do_exit() {
114 if [ "$DEBUG" == "yes" ] && [ "$MODE" != 'cleanuponly' ]
115 then
116 echo "------ DEBUG ------"
117 echo "mount: "; mount | egrep '(cgroup2|bpf)'; echo
118 echo "$CGRP2_TC_LEAF: "; ls -l $CGRP2_TC_LEAF; echo
119 if [ -d "$BPF_FS_TC_SHARE" ]
120 then
121 echo "$BPF_FS_TC_SHARE: "; ls -l $BPF_FS_TC_SHARE; echo
122 fi
123 echo "Host net:"
124 $IP netns
125 $IP link show dev $HOST_IFC
126 $IP -6 a show dev $HOST_IFC
127 $TC -s qdisc show dev $HOST_IFC
128 echo
129 echo "$NS net:"
130 $IP -n $NS link show dev $NS_IFC
131 $IP -n $NS -6 link show dev $NS_IFC
132 echo "------ DEBUG ------"
133 echo
134 fi
135
136 if [ "$MODE" != 'nocleanup' ]
137 then
138 setup_net stop
139 setup_bpf_cgrp2_array stop
140 setup_cgrp2 stop
141 fi
142}
143
144init_cgrp2_vars
145init_bpf_fs_vars
146
147while [[ $# -ge 1 ]]
148do
149 a="$1"
150 case $a in
151 debug)
152 DEBUG='yes'
153 shift 1
154 ;;
155 cleanup-only)
156 MODE='cleanuponly'
157 shift 1
158 ;;
159 no-cleanup)
160 MODE='nocleanup'
161 shift 1
162 ;;
163 *)
164 echo "test_cgrp2_tc [debug] [cleanup-only | no-cleanup]"
165 echo " debug: Print cgrp and network setup details at the end of the test"
166 echo " cleanup-only: Try to cleanup things from last test. No test will be run"
167 echo " no-cleanup: Run the test but don't do cleanup at the end"
168 echo "[Note: If no arg is given, it will run the test and do cleanup at the end]"
169 echo
170 exit -1
171 ;;
172 esac
173done
174
175trap do_exit 0
176
177[ "$MODE" == 'cleanuponly' ] && exit
178
179setup_cgrp2 start || exit $?
180setup_net start || exit $?
181init_bpf_fs_vars || exit $?
182setup_bpf_cgrp2_array start || exit $?
183do_test
184echo
diff --git a/samples/bpf/test_cgrp2_tc_kern.c b/samples/bpf/test_cgrp2_tc_kern.c
new file mode 100644
index 000000000000..2732c37c8d5b
--- /dev/null
+++ b/samples/bpf/test_cgrp2_tc_kern.c
@@ -0,0 +1,69 @@
1/* Copyright (c) 2016 Facebook
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#include <uapi/linux/if_ether.h>
8#include <uapi/linux/in6.h>
9#include <uapi/linux/ipv6.h>
10#include <uapi/linux/pkt_cls.h>
11#include <uapi/linux/bpf.h>
12#include "bpf_helpers.h"
13
14/* copy of 'struct ethhdr' without __packed */
15struct eth_hdr {
16 unsigned char h_dest[ETH_ALEN];
17 unsigned char h_source[ETH_ALEN];
18 unsigned short h_proto;
19};
20
21#define PIN_GLOBAL_NS 2
22struct bpf_elf_map {
23 __u32 type;
24 __u32 size_key;
25 __u32 size_value;
26 __u32 max_elem;
27 __u32 flags;
28 __u32 id;
29 __u32 pinning;
30};
31
32struct bpf_elf_map SEC("maps") test_cgrp2_array_pin = {
33 .type = BPF_MAP_TYPE_CGROUP_ARRAY,
34 .size_key = sizeof(uint32_t),
35 .size_value = sizeof(uint32_t),
36 .pinning = PIN_GLOBAL_NS,
37 .max_elem = 1,
38};
39
40SEC("filter")
41int handle_egress(struct __sk_buff *skb)
42{
43 void *data = (void *)(long)skb->data;
44 struct eth_hdr *eth = data;
45 struct ipv6hdr *ip6h = data + sizeof(*eth);
46 void *data_end = (void *)(long)skb->data_end;
47 char dont_care_msg[] = "dont care %04x %d\n";
48 char pass_msg[] = "pass\n";
49 char reject_msg[] = "reject\n";
50
51 /* single length check */
52 if (data + sizeof(*eth) + sizeof(*ip6h) > data_end)
53 return TC_ACT_OK;
54
55 if (eth->h_proto != htons(ETH_P_IPV6) ||
56 ip6h->nexthdr != IPPROTO_ICMPV6) {
57 bpf_trace_printk(dont_care_msg, sizeof(dont_care_msg),
58 eth->h_proto, ip6h->nexthdr);
59 return TC_ACT_OK;
60 } else if (bpf_skb_in_cgroup(skb, &test_cgrp2_array_pin, 0) != 1) {
61 bpf_trace_printk(pass_msg, sizeof(pass_msg));
62 return TC_ACT_OK;
63 } else {
64 bpf_trace_printk(reject_msg, sizeof(reject_msg));
65 return TC_ACT_SHOT;
66 }
67}
68
69char _license[] SEC("license") = "GPL";
diff --git a/samples/bpf/test_probe_write_user_kern.c b/samples/bpf/test_probe_write_user_kern.c
new file mode 100644
index 000000000000..3a677c807044
--- /dev/null
+++ b/samples/bpf/test_probe_write_user_kern.c
@@ -0,0 +1,52 @@
1/* Copyright (c) 2016 Sargun Dhillon <sargun@sargun.me>
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#include <linux/skbuff.h>
8#include <linux/netdevice.h>
9#include <uapi/linux/bpf.h>
10#include <linux/version.h>
11#include "bpf_helpers.h"
12
13struct bpf_map_def SEC("maps") dnat_map = {
14 .type = BPF_MAP_TYPE_HASH,
15 .key_size = sizeof(struct sockaddr_in),
16 .value_size = sizeof(struct sockaddr_in),
17 .max_entries = 256,
18};
19
20/* kprobe is NOT a stable ABI
21 * kernel functions can be removed, renamed or completely change semantics.
22 * Number of arguments and their positions can change, etc.
23 * In such case this bpf+kprobe example will no longer be meaningful
24 *
25 * This example sits on a syscall, and the syscall ABI is relatively stable
26 * of course, across platforms, and over time, the ABI may change.
27 */
28SEC("kprobe/sys_connect")
29int bpf_prog1(struct pt_regs *ctx)
30{
31 struct sockaddr_in new_addr, orig_addr = {};
32 struct sockaddr_in *mapped_addr;
33 void *sockaddr_arg = (void *)PT_REGS_PARM2(ctx);
34 int sockaddr_len = (int)PT_REGS_PARM3(ctx);
35
36 if (sockaddr_len > sizeof(orig_addr))
37 return 0;
38
39 if (bpf_probe_read(&orig_addr, sizeof(orig_addr), sockaddr_arg) != 0)
40 return 0;
41
42 mapped_addr = bpf_map_lookup_elem(&dnat_map, &orig_addr);
43 if (mapped_addr != NULL) {
44 memcpy(&new_addr, mapped_addr, sizeof(new_addr));
45 bpf_probe_write_user(sockaddr_arg, &new_addr,
46 sizeof(new_addr));
47 }
48 return 0;
49}
50
51char _license[] SEC("license") = "GPL";
52u32 _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/test_probe_write_user_user.c b/samples/bpf/test_probe_write_user_user.c
new file mode 100644
index 000000000000..a44bf347bedd
--- /dev/null
+++ b/samples/bpf/test_probe_write_user_user.c
@@ -0,0 +1,78 @@
1#include <stdio.h>
2#include <assert.h>
3#include <linux/bpf.h>
4#include <unistd.h>
5#include "libbpf.h"
6#include "bpf_load.h"
7#include <sys/socket.h>
8#include <string.h>
9#include <netinet/in.h>
10#include <arpa/inet.h>
11
12int main(int ac, char **argv)
13{
14 int serverfd, serverconnfd, clientfd;
15 socklen_t sockaddr_len;
16 struct sockaddr serv_addr, mapped_addr, tmp_addr;
17 struct sockaddr_in *serv_addr_in, *mapped_addr_in, *tmp_addr_in;
18 char filename[256];
19 char *ip;
20
21 serv_addr_in = (struct sockaddr_in *)&serv_addr;
22 mapped_addr_in = (struct sockaddr_in *)&mapped_addr;
23 tmp_addr_in = (struct sockaddr_in *)&tmp_addr;
24
25 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
26
27 if (load_bpf_file(filename)) {
28 printf("%s", bpf_log_buf);
29 return 1;
30 }
31
32 assert((serverfd = socket(AF_INET, SOCK_STREAM, 0)) > 0);
33 assert((clientfd = socket(AF_INET, SOCK_STREAM, 0)) > 0);
34
35 /* Bind server to ephemeral port on lo */
36 memset(&serv_addr, 0, sizeof(serv_addr));
37 serv_addr_in->sin_family = AF_INET;
38 serv_addr_in->sin_port = 0;
39 serv_addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
40
41 assert(bind(serverfd, &serv_addr, sizeof(serv_addr)) == 0);
42
43 sockaddr_len = sizeof(serv_addr);
44 assert(getsockname(serverfd, &serv_addr, &sockaddr_len) == 0);
45 ip = inet_ntoa(serv_addr_in->sin_addr);
46 printf("Server bound to: %s:%d\n", ip, ntohs(serv_addr_in->sin_port));
47
48 memset(&mapped_addr, 0, sizeof(mapped_addr));
49 mapped_addr_in->sin_family = AF_INET;
50 mapped_addr_in->sin_port = htons(5555);
51 mapped_addr_in->sin_addr.s_addr = inet_addr("255.255.255.255");
52
53 assert(!bpf_update_elem(map_fd[0], &mapped_addr, &serv_addr, BPF_ANY));
54
55 assert(listen(serverfd, 5) == 0);
56
57 ip = inet_ntoa(mapped_addr_in->sin_addr);
58 printf("Client connecting to: %s:%d\n",
59 ip, ntohs(mapped_addr_in->sin_port));
60 assert(connect(clientfd, &mapped_addr, sizeof(mapped_addr)) == 0);
61
62 sockaddr_len = sizeof(tmp_addr);
63 ip = inet_ntoa(tmp_addr_in->sin_addr);
64 assert((serverconnfd = accept(serverfd, &tmp_addr, &sockaddr_len)) > 0);
65 printf("Server received connection from: %s:%d\n",
66 ip, ntohs(tmp_addr_in->sin_port));
67
68 sockaddr_len = sizeof(tmp_addr);
69 assert(getpeername(clientfd, &tmp_addr, &sockaddr_len) == 0);
70 ip = inet_ntoa(tmp_addr_in->sin_addr);
71 printf("Client's peer address: %s:%d\n",
72 ip, ntohs(tmp_addr_in->sin_port));
73
74 /* Is the server's getsockname = the socket getpeername */
75 assert(memcmp(&serv_addr, &tmp_addr, sizeof(struct sockaddr_in)) == 0);
76
77 return 0;
78}
diff --git a/samples/bpf/xdp1_kern.c b/samples/bpf/xdp1_kern.c
new file mode 100644
index 000000000000..219742106bfd
--- /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") rxcnt = {
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 ipproto;
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 ipproto = parse_ipv4(data, nh_off, data_end);
81 else if (h_proto == htons(ETH_P_IPV6))
82 ipproto = parse_ipv6(data, nh_off, data_end);
83 else
84 ipproto = 0;
85
86 value = bpf_map_lookup_elem(&rxcnt, &ipproto);
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/xdp1_user.c
new file mode 100644
index 000000000000..a5e109e398a1
--- /dev/null
+++ b/samples/bpf/xdp1_user.c
@@ -0,0 +1,181 @@
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#include <linux/bpf.h>
8#include <linux/netlink.h>
9#include <linux/rtnetlink.h>
10#include <assert.h>
11#include <errno.h>
12#include <signal.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <sys/socket.h>
17#include <unistd.h>
18#include "bpf_load.h"
19#include "libbpf.h"
20
21static int set_link_xdp_fd(int ifindex, int fd)
22{
23 struct sockaddr_nl sa;
24 int sock, seq = 0, len, ret = -1;
25 char buf[4096];
26 struct nlattr *nla, *nla_xdp;
27 struct {
28 struct nlmsghdr nh;
29 struct ifinfomsg ifinfo;
30 char attrbuf[64];
31 } req;
32 struct nlmsghdr *nh;
33 struct nlmsgerr *err;
34
35 memset(&sa, 0, sizeof(sa));
36 sa.nl_family = AF_NETLINK;
37
38 sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
39 if (sock < 0) {
40 printf("open netlink socket: %s\n", strerror(errno));
41 return -1;
42 }
43
44 if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
45 printf("bind to netlink: %s\n", strerror(errno));
46 goto cleanup;
47 }
48
49 memset(&req, 0, sizeof(req));
50 req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
51 req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
52 req.nh.nlmsg_type = RTM_SETLINK;
53 req.nh.nlmsg_pid = 0;
54 req.nh.nlmsg_seq = ++seq;
55 req.ifinfo.ifi_family = AF_UNSPEC;
56 req.ifinfo.ifi_index = ifindex;
57 nla = (struct nlattr *)(((char *)&req)
58 + NLMSG_ALIGN(req.nh.nlmsg_len));
59 nla->nla_type = NLA_F_NESTED | 43/*IFLA_XDP*/;
60
61 nla_xdp = (struct nlattr *)((char *)nla + NLA_HDRLEN);
62 nla_xdp->nla_type = 1/*IFLA_XDP_FD*/;
63 nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
64 memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
65 nla->nla_len = NLA_HDRLEN + nla_xdp->nla_len;
66
67 req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
68
69 if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
70 printf("send to netlink: %s\n", strerror(errno));
71 goto cleanup;
72 }
73
74 len = recv(sock, buf, sizeof(buf), 0);
75 if (len < 0) {
76 printf("recv from netlink: %s\n", strerror(errno));
77 goto cleanup;
78 }
79
80 for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
81 nh = NLMSG_NEXT(nh, len)) {
82 if (nh->nlmsg_pid != getpid()) {
83 printf("Wrong pid %d, expected %d\n",
84 nh->nlmsg_pid, getpid());
85 goto cleanup;
86 }
87 if (nh->nlmsg_seq != seq) {
88 printf("Wrong seq %d, expected %d\n",
89 nh->nlmsg_seq, seq);
90 goto cleanup;
91 }
92 switch (nh->nlmsg_type) {
93 case NLMSG_ERROR:
94 err = (struct nlmsgerr *)NLMSG_DATA(nh);
95 if (!err->error)
96 continue;
97 printf("nlmsg error %s\n", strerror(-err->error));
98 goto cleanup;
99 case NLMSG_DONE:
100 break;
101 }
102 }
103
104 ret = 0;
105
106cleanup:
107 close(sock);
108 return ret;
109}
110
111static int ifindex;
112
113static void int_exit(int sig)
114{
115 set_link_xdp_fd(ifindex, -1);
116 exit(0);
117}
118
119/* simple per-protocol drop counter
120 */
121static void poll_stats(int interval)
122{
123 unsigned int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
124 const unsigned int nr_keys = 256;
125 __u64 values[nr_cpus], prev[nr_keys][nr_cpus];
126 __u32 key;
127 int i;
128
129 memset(prev, 0, sizeof(prev));
130
131 while (1) {
132 sleep(interval);
133
134 for (key = 0; key < nr_keys; key++) {
135 __u64 sum = 0;
136
137 assert(bpf_lookup_elem(map_fd[0], &key, values) == 0);
138 for (i = 0; i < nr_cpus; i++)
139 sum += (values[i] - prev[key][i]);
140 if (sum)
141 printf("proto %u: %10llu pkt/s\n",
142 key, sum / interval);
143 memcpy(prev[key], values, sizeof(values));
144 }
145 }
146}
147
148int main(int ac, char **argv)
149{
150 char filename[256];
151
152 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
153
154 if (ac != 2) {
155 printf("usage: %s IFINDEX\n", argv[0]);
156 return 1;
157 }
158
159 ifindex = strtoul(argv[1], NULL, 0);
160
161 if (load_bpf_file(filename)) {
162 printf("%s", bpf_log_buf);
163 return 1;
164 }
165
166 if (!prog_fd[0]) {
167 printf("load_bpf_file: %s\n", strerror(errno));
168 return 1;
169 }
170
171 signal(SIGINT, int_exit);
172
173 if (set_link_xdp_fd(ifindex, prog_fd[0]) < 0) {
174 printf("link set xdp fd failed\n");
175 return 1;
176 }
177
178 poll_stats(2);
179
180 return 0;
181}
diff --git a/samples/bpf/xdp2_kern.c b/samples/bpf/xdp2_kern.c
new file mode 100644
index 000000000000..e01288867d15
--- /dev/null
+++ b/samples/bpf/xdp2_kern.c
@@ -0,0 +1,114 @@
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") rxcnt = {
18 .type = BPF_MAP_TYPE_PERCPU_ARRAY,
19 .key_size = sizeof(u32),
20 .value_size = sizeof(long),
21 .max_entries = 256,
22};
23
24static void swap_src_dst_mac(void *data)
25{
26 unsigned short *p = data;
27 unsigned short dst[3];
28
29 dst[0] = p[0];
30 dst[1] = p[1];
31 dst[2] = p[2];
32 p[0] = p[3];
33 p[1] = p[4];
34 p[2] = p[5];
35 p[3] = dst[0];
36 p[4] = dst[1];
37 p[5] = dst[2];
38}
39
40static int parse_ipv4(void *data, u64 nh_off, void *data_end)
41{
42 struct iphdr *iph = data + nh_off;
43
44 if (iph + 1 > data_end)
45 return 0;
46 return iph->protocol;
47}
48
49static int parse_ipv6(void *data, u64 nh_off, void *data_end)
50{
51 struct ipv6hdr *ip6h = data + nh_off;
52
53 if (ip6h + 1 > data_end)
54 return 0;
55 return ip6h->nexthdr;
56}
57
58SEC("xdp1")
59int xdp_prog1(struct xdp_md *ctx)
60{
61 void *data_end = (void *)(long)ctx->data_end;
62 void *data = (void *)(long)ctx->data;
63 struct ethhdr *eth = data;
64 int rc = XDP_DROP;
65 long *value;
66 u16 h_proto;
67 u64 nh_off;
68 u32 ipproto;
69
70 nh_off = sizeof(*eth);
71 if (data + nh_off > data_end)
72 return rc;
73
74 h_proto = eth->h_proto;
75
76 if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) {
77 struct vlan_hdr *vhdr;
78
79 vhdr = data + nh_off;
80 nh_off += sizeof(struct vlan_hdr);
81 if (data + nh_off > data_end)
82 return rc;
83 h_proto = vhdr->h_vlan_encapsulated_proto;
84 }
85 if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) {
86 struct vlan_hdr *vhdr;
87
88 vhdr = data + nh_off;
89 nh_off += sizeof(struct vlan_hdr);
90 if (data + nh_off > data_end)
91 return rc;
92 h_proto = vhdr->h_vlan_encapsulated_proto;
93 }
94
95 if (h_proto == htons(ETH_P_IP))
96 ipproto = parse_ipv4(data, nh_off, data_end);
97 else if (h_proto == htons(ETH_P_IPV6))
98 ipproto = parse_ipv6(data, nh_off, data_end);
99 else
100 ipproto = 0;
101
102 value = bpf_map_lookup_elem(&rxcnt, &ipproto);
103 if (value)
104 *value += 1;
105
106 if (ipproto == IPPROTO_UDP) {
107 swap_src_dst_mac(data);
108 rc = XDP_TX;
109 }
110
111 return rc;
112}
113
114char _license[] SEC("license") = "GPL";
diff --git a/samples/kprobes/kprobe_example.c b/samples/kprobes/kprobe_example.c
index ed0ca0c07242..f3b61b4ee09c 100644
--- a/samples/kprobes/kprobe_example.c
+++ b/samples/kprobes/kprobe_example.c
@@ -46,6 +46,11 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs)
46 " ex1 = 0x%lx\n", 46 " ex1 = 0x%lx\n",
47 p->symbol_name, p->addr, regs->pc, regs->ex1); 47 p->symbol_name, p->addr, regs->pc, regs->ex1);
48#endif 48#endif
49#ifdef CONFIG_ARM64
50 pr_info("<%s> pre_handler: p->addr = 0x%p, pc = 0x%lx,"
51 " pstate = 0x%lx\n",
52 p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
53#endif
49 54
50 /* A dump_stack() here will give a stack backtrace */ 55 /* A dump_stack() here will give a stack backtrace */
51 return 0; 56 return 0;
@@ -71,6 +76,10 @@ static void handler_post(struct kprobe *p, struct pt_regs *regs,
71 printk(KERN_INFO "<%s> post_handler: p->addr = 0x%p, ex1 = 0x%lx\n", 76 printk(KERN_INFO "<%s> post_handler: p->addr = 0x%p, ex1 = 0x%lx\n",
72 p->symbol_name, p->addr, regs->ex1); 77 p->symbol_name, p->addr, regs->ex1);
73#endif 78#endif
79#ifdef CONFIG_ARM64
80 pr_info("<%s> post_handler: p->addr = 0x%p, pstate = 0x%lx\n",
81 p->symbol_name, p->addr, (long)regs->pstate);
82#endif
74} 83}
75 84
76/* 85/*
diff --git a/samples/pktgen/parameters.sh b/samples/pktgen/parameters.sh
index 33b70fdd5a4a..f70ea7dd5660 100644
--- a/samples/pktgen/parameters.sh
+++ b/samples/pktgen/parameters.sh
@@ -14,12 +14,13 @@ function usage() {
14 echo " -b : (\$BURST) HW level bursting of SKBs" 14 echo " -b : (\$BURST) HW level bursting of SKBs"
15 echo " -v : (\$VERBOSE) verbose" 15 echo " -v : (\$VERBOSE) verbose"
16 echo " -x : (\$DEBUG) debug" 16 echo " -x : (\$DEBUG) debug"
17 echo " -6 : (\$IP6) IPv6"
17 echo "" 18 echo ""
18} 19}
19 20
20## --- Parse command line arguments / parameters --- 21## --- Parse command line arguments / parameters ---
21## echo "Commandline options:" 22## echo "Commandline options:"
22while getopts "s:i:d:m:t:c:b:vxh" option; do 23while getopts "s:i:d:m:t:c:b:vxh6" option; do
23 case $option in 24 case $option in
24 i) # interface 25 i) # interface
25 export DEV=$OPTARG 26 export DEV=$OPTARG
@@ -59,6 +60,10 @@ while getopts "s:i:d:m:t:c:b:vxh" option; do
59 export DEBUG=yes 60 export DEBUG=yes
60 info "Debug mode: DEBUG=$DEBUG" 61 info "Debug mode: DEBUG=$DEBUG"
61 ;; 62 ;;
63 6)
64 export IP6=6
65 info "IP6: IP6=$IP6"
66 ;;
62 h|?|*) 67 h|?|*)
63 usage; 68 usage;
64 err 2 "[ERROR] Unknown parameters!!!" 69 err 2 "[ERROR] Unknown parameters!!!"
diff --git a/samples/pktgen/pktgen.conf-1-1-flows b/samples/pktgen/pktgen.conf-1-1-flows
deleted file mode 100755
index 081749c9707d..000000000000
--- a/samples/pktgen/pktgen.conf-1-1-flows
+++ /dev/null
@@ -1,67 +0,0 @@
1#!/bin/bash
2
3#modprobe pktgen
4
5
6function pgset() {
7 local result
8
9 echo $1 > $PGDEV
10
11 result=`cat $PGDEV | fgrep "Result: OK:"`
12 if [ "$result" = "" ]; then
13 cat $PGDEV | fgrep Result:
14 fi
15}
16
17# Config Start Here -----------------------------------------------------------
18
19
20# thread config
21# Each CPU has its own thread. One CPU example. We add eth1.
22
23PGDEV=/proc/net/pktgen/kpktgend_0
24 echo "Removing all devices"
25 pgset "rem_device_all"
26 echo "Adding eth1"
27 pgset "add_device eth1"
28
29
30# device config
31# delay 0
32# We need to do alloc for every skb since we cannot clone here.
33
34CLONE_SKB="clone_skb 0"
35# NIC adds 4 bytes CRC
36PKT_SIZE="pkt_size 60"
37
38# COUNT 0 means forever
39#COUNT="count 0"
40COUNT="count 10000000"
41DELAY="delay 0"
42
43PGDEV=/proc/net/pktgen/eth1
44 echo "Configuring $PGDEV"
45 pgset "$COUNT"
46 pgset "$CLONE_SKB"
47 pgset "$PKT_SIZE"
48 pgset "$DELAY"
49 # Random address with in the min-max range
50 pgset "flag IPDST_RND"
51 pgset "dst_min 10.0.0.0"
52 pgset "dst_max 10.255.255.255"
53
54 # 8k Concurrent flows at 4 pkts
55 pgset "flows 8192"
56 pgset "flowlen 4"
57
58 pgset "dst_mac 00:04:23:08:91:dc"
59
60# Time to run
61PGDEV=/proc/net/pktgen/pgctrl
62
63 echo "Running... ctrl^C to stop"
64 trap true INT
65 pgset "start"
66 echo "Done"
67 cat /proc/net/pktgen/eth1
diff --git a/samples/pktgen/pktgen.conf-1-1-rdos b/samples/pktgen/pktgen.conf-1-1-rdos
deleted file mode 100755
index c7553be49b80..000000000000
--- a/samples/pktgen/pktgen.conf-1-1-rdos
+++ /dev/null
@@ -1,64 +0,0 @@
1#!/bin/bash
2
3#modprobe pktgen
4
5
6function pgset() {
7 local result
8
9 echo $1 > $PGDEV
10
11 result=`cat $PGDEV | fgrep "Result: OK:"`
12 if [ "$result" = "" ]; then
13 cat $PGDEV | fgrep Result:
14 fi
15}
16
17# Config Start Here -----------------------------------------------------------
18
19
20# thread config
21# Each CPU has its own thread. One CPU example. We add eth1.
22
23PGDEV=/proc/net/pktgen/kpktgend_0
24 echo "Removing all devices"
25 pgset "rem_device_all"
26 echo "Adding eth1"
27 pgset "add_device eth1"
28
29
30# device config
31# delay 0
32
33# We need to do alloc for every skb since we cannot clone here.
34
35CLONE_SKB="clone_skb 0"
36# NIC adds 4 bytes CRC
37PKT_SIZE="pkt_size 60"
38
39# COUNT 0 means forever
40#COUNT="count 0"
41COUNT="count 10000000"
42DELAY="delay 0"
43
44PGDEV=/proc/net/pktgen/eth1
45 echo "Configuring $PGDEV"
46 pgset "$COUNT"
47 pgset "$CLONE_SKB"
48 pgset "$PKT_SIZE"
49 pgset "$DELAY"
50 # Random address with in the min-max range
51 pgset "flag IPDST_RND"
52 pgset "dst_min 10.0.0.0"
53 pgset "dst_max 10.255.255.255"
54
55 pgset "dst_mac 00:04:23:08:91:dc"
56
57# Time to run
58PGDEV=/proc/net/pktgen/pgctrl
59
60 echo "Running... ctrl^C to stop"
61 trap true INT
62 pgset "start"
63 echo "Done"
64 cat /proc/net/pktgen/eth1
diff --git a/samples/pktgen/pktgen_bench_xmit_mode_netif_receive.sh b/samples/pktgen/pktgen_bench_xmit_mode_netif_receive.sh
index cb1590331b47..f3e1bedfd77f 100755
--- a/samples/pktgen/pktgen_bench_xmit_mode_netif_receive.sh
+++ b/samples/pktgen/pktgen_bench_xmit_mode_netif_receive.sh
@@ -34,7 +34,9 @@ root_check_run_with_sudo "$@"
34source ${basedir}/parameters.sh 34source ${basedir}/parameters.sh
35# Using invalid DST_MAC will cause the packets to get dropped in 35# Using invalid DST_MAC will cause the packets to get dropped in
36# ip_rcv() which is part of the test 36# ip_rcv() which is part of the test
37[ -z "$DEST_IP" ] && DEST_IP="198.18.0.42" 37if [ -z "$DEST_IP" ]; then
38 [ -z "$IP6" ] && DEST_IP="198.18.0.42" || DEST_IP="FD00::1"
39fi
38[ -z "$DST_MAC" ] && DST_MAC="90:e2:ba:ff:ff:ff" 40[ -z "$DST_MAC" ] && DST_MAC="90:e2:ba:ff:ff:ff"
39[ -z "$BURST" ] && BURST=1024 41[ -z "$BURST" ] && BURST=1024
40 42
@@ -64,7 +66,7 @@ for ((thread = 0; thread < $THREADS; thread++)); do
64 66
65 # Destination 67 # Destination
66 pg_set $dev "dst_mac $DST_MAC" 68 pg_set $dev "dst_mac $DST_MAC"
67 pg_set $dev "dst $DEST_IP" 69 pg_set $dev "dst$IP6 $DEST_IP"
68 70
69 # Inject packet into RX path of stack 71 # Inject packet into RX path of stack
70 pg_set $dev "xmit_mode netif_receive" 72 pg_set $dev "xmit_mode netif_receive"
diff --git a/samples/pktgen/pktgen_bench_xmit_mode_queue_xmit.sh b/samples/pktgen/pktgen_bench_xmit_mode_queue_xmit.sh
new file mode 100755
index 000000000000..cc102e923241
--- /dev/null
+++ b/samples/pktgen/pktgen_bench_xmit_mode_queue_xmit.sh
@@ -0,0 +1,68 @@
1#!/bin/bash
2#
3# Benchmark script:
4# - developed for benchmarking egress qdisc path, derived (more
5# like cut'n'pasted) from ingress benchmark script.
6#
7# Script for injecting packets into egress qdisc path of the stack
8# with pktgen "xmit_mode queue_xmit".
9#
10basedir=`dirname $0`
11source ${basedir}/functions.sh
12root_check_run_with_sudo "$@"
13
14# Parameter parsing via include
15source ${basedir}/parameters.sh
16if [ -z "$DEST_IP" ]; then
17 [ -z "$IP6" ] && DEST_IP="198.18.0.42" || DEST_IP="FD00::1"
18fi
19[ -z "$DST_MAC" ] && DST_MAC="90:e2:ba:ff:ff:ff"
20
21# Burst greater than 1 are invalid for queue_xmit mode
22if [[ -n "$BURST" ]]; then
23 err 1 "Bursting not supported for this mode"
24fi
25
26# Base Config
27DELAY="0" # Zero means max speed
28COUNT="10000000" # Zero means indefinitely
29
30# General cleanup everything since last run
31pg_ctrl "reset"
32
33# Threads are specified with parameter -t value in $THREADS
34for ((thread = 0; thread < $THREADS; thread++)); do
35 # The device name is extended with @name, using thread number to
36 # make then unique, but any name will do.
37 dev=${DEV}@${thread}
38
39 # Add remove all other devices and add_device $dev to thread
40 pg_thread $thread "rem_device_all"
41 pg_thread $thread "add_device" $dev
42
43 # Base config of dev
44 pg_set $dev "flag QUEUE_MAP_CPU"
45 pg_set $dev "count $COUNT"
46 pg_set $dev "pkt_size $PKT_SIZE"
47 pg_set $dev "delay $DELAY"
48 pg_set $dev "flag NO_TIMESTAMP"
49
50 # Destination
51 pg_set $dev "dst_mac $DST_MAC"
52 pg_set $dev "dst$IP6 $DEST_IP"
53
54 # Inject packet into TX qdisc egress path of stack
55 pg_set $dev "xmit_mode queue_xmit"
56done
57
58# start_run
59echo "Running... ctrl^C to stop" >&2
60pg_ctrl "start"
61echo "Done" >&2
62
63# Print results
64for ((thread = 0; thread < $THREADS; thread++)); do
65 dev=${DEV}@${thread}
66 echo "Device: $dev"
67 cat /proc/net/pktgen/$dev | grep -A2 "Result:"
68done
diff --git a/samples/pktgen/pktgen_sample01_simple.sh b/samples/pktgen/pktgen_sample01_simple.sh
index 8c9d318c221b..29ef4ba50796 100755
--- a/samples/pktgen/pktgen_sample01_simple.sh
+++ b/samples/pktgen/pktgen_sample01_simple.sh
@@ -14,7 +14,9 @@ root_check_run_with_sudo "$@"
14source ${basedir}/parameters.sh 14source ${basedir}/parameters.sh
15# 15#
16# Set some default params, if they didn't get set 16# Set some default params, if they didn't get set
17[ -z "$DEST_IP" ] && DEST_IP="198.18.0.42" 17if [ -z "$DEST_IP" ]; then
18 [ -z "$IP6" ] && DEST_IP="198.18.0.42" || DEST_IP="FD00::1"
19fi
18[ -z "$CLONE_SKB" ] && CLONE_SKB="0" 20[ -z "$CLONE_SKB" ] && CLONE_SKB="0"
19# Example enforce param "-m" for dst_mac 21# Example enforce param "-m" for dst_mac
20[ -z "$DST_MAC" ] && usage && err 2 "Must specify -m dst_mac" 22[ -z "$DST_MAC" ] && usage && err 2 "Must specify -m dst_mac"
@@ -54,7 +56,7 @@ pg_set $DEV "flag NO_TIMESTAMP"
54 56
55# Destination 57# Destination
56pg_set $DEV "dst_mac $DST_MAC" 58pg_set $DEV "dst_mac $DST_MAC"
57pg_set $DEV "dst $DEST_IP" 59pg_set $DEV "dst$IP6 $DEST_IP"
58 60
59# Setup random UDP port src range 61# Setup random UDP port src range
60pg_set $DEV "flag UDPSRC_RND" 62pg_set $DEV "flag UDPSRC_RND"
diff --git a/samples/pktgen/pktgen_sample02_multiqueue.sh b/samples/pktgen/pktgen_sample02_multiqueue.sh
index 32467aea8e47..c88a161d3e6f 100755
--- a/samples/pktgen/pktgen_sample02_multiqueue.sh
+++ b/samples/pktgen/pktgen_sample02_multiqueue.sh
@@ -23,7 +23,9 @@ UDP_MIN=9
23UDP_MAX=109 23UDP_MAX=109
24 24
25# (example of setting default params in your script) 25# (example of setting default params in your script)
26[ -z "$DEST_IP" ] && DEST_IP="198.18.0.42" 26if [ -z "$DEST_IP" ]; then
27 [ -z "$IP6" ] && DEST_IP="198.18.0.42" || DEST_IP="FD00::1"
28fi
27[ -z "$DST_MAC" ] && DST_MAC="90:e2:ba:ff:ff:ff" 29[ -z "$DST_MAC" ] && DST_MAC="90:e2:ba:ff:ff:ff"
28 30
29# General cleanup everything since last run 31# General cleanup everything since last run
@@ -54,7 +56,7 @@ for ((thread = 0; thread < $THREADS; thread++)); do
54 56
55 # Destination 57 # Destination
56 pg_set $dev "dst_mac $DST_MAC" 58 pg_set $dev "dst_mac $DST_MAC"
57 pg_set $dev "dst $DEST_IP" 59 pg_set $dev "dst$IP6 $DEST_IP"
58 60
59 # Setup random UDP port src range 61 # Setup random UDP port src range
60 pg_set $dev "flag UDPSRC_RND" 62 pg_set $dev "flag UDPSRC_RND"
diff --git a/samples/pktgen/pktgen_sample03_burst_single_flow.sh b/samples/pktgen/pktgen_sample03_burst_single_flow.sh
index 775f5d0a1e53..80cf8f5ba6b2 100755
--- a/samples/pktgen/pktgen_sample03_burst_single_flow.sh
+++ b/samples/pktgen/pktgen_sample03_burst_single_flow.sh
@@ -25,7 +25,9 @@ root_check_run_with_sudo "$@"
25# Parameter parsing via include 25# Parameter parsing via include
26source ${basedir}/parameters.sh 26source ${basedir}/parameters.sh
27# Set some default params, if they didn't get set 27# Set some default params, if they didn't get set
28[ -z "$DEST_IP" ] && DEST_IP="198.18.0.42" 28if [ -z "$DEST_IP" ]; then
29 [ -z "$IP6" ] && DEST_IP="198.18.0.42" || DEST_IP="FD00::1"
30fi
29[ -z "$DST_MAC" ] && DST_MAC="90:e2:ba:ff:ff:ff" 31[ -z "$DST_MAC" ] && DST_MAC="90:e2:ba:ff:ff:ff"
30[ -z "$BURST" ] && BURST=32 32[ -z "$BURST" ] && BURST=32
31[ -z "$CLONE_SKB" ] && CLONE_SKB="100000" 33[ -z "$CLONE_SKB" ] && CLONE_SKB="100000"
@@ -55,7 +57,7 @@ for ((thread = 0; thread < $THREADS; thread++)); do
55 57
56 # Destination 58 # Destination
57 pg_set $dev "dst_mac $DST_MAC" 59 pg_set $dev "dst_mac $DST_MAC"
58 pg_set $dev "dst $DEST_IP" 60 pg_set $dev "dst$IP6 $DEST_IP"
59 61
60 # Setup burst, for easy testing -b 0 disable bursting 62 # Setup burst, for easy testing -b 0 disable bursting
61 # (internally in pktgen default and minimum burst=1) 63 # (internally in pktgen default and minimum burst=1)
diff --git a/samples/pktgen/pktgen_sample04_many_flows.sh b/samples/pktgen/pktgen_sample04_many_flows.sh
new file mode 100755
index 000000000000..f60412e445bb
--- /dev/null
+++ b/samples/pktgen/pktgen_sample04_many_flows.sh
@@ -0,0 +1,93 @@
1#!/bin/bash
2#
3# Script example for many flows testing
4#
5# Number of simultaneous flows limited by variable $FLOWS
6# and number of packets per flow controlled by variable $FLOWLEN
7#
8basedir=`dirname $0`
9source ${basedir}/functions.sh
10root_check_run_with_sudo "$@"
11
12# Parameter parsing via include
13source ${basedir}/parameters.sh
14# Set some default params, if they didn't get set
15[ -z "$DEST_IP" ] && DEST_IP="198.18.0.42"
16[ -z "$DST_MAC" ] && DST_MAC="90:e2:ba:ff:ff:ff"
17[ -z "$CLONE_SKB" ] && CLONE_SKB="0"
18
19# NOTICE: Script specific settings
20# =======
21# Limiting the number of concurrent flows ($FLOWS)
22# and also set how many packets each flow contains ($FLOWLEN)
23#
24[ -z "$FLOWS" ] && FLOWS="8000"
25[ -z "$FLOWLEN" ] && FLOWLEN="10"
26
27# Base Config
28DELAY="0" # Zero means max speed
29COUNT="0" # Zero means indefinitely
30
31if [[ -n "$BURST" ]]; then
32 err 1 "Bursting not supported for this mode"
33fi
34
35# General cleanup everything since last run
36pg_ctrl "reset"
37
38# Threads are specified with parameter -t value in $THREADS
39for ((thread = 0; thread < $THREADS; thread++)); do
40 dev=${DEV}@${thread}
41
42 # Add remove all other devices and add_device $dev to thread
43 pg_thread $thread "rem_device_all"
44 pg_thread $thread "add_device" $dev
45
46 # Base config
47 pg_set $dev "flag QUEUE_MAP_CPU"
48 pg_set $dev "count $COUNT"
49 pg_set $dev "clone_skb $CLONE_SKB"
50 pg_set $dev "pkt_size $PKT_SIZE"
51 pg_set $dev "delay $DELAY"
52 pg_set $dev "flag NO_TIMESTAMP"
53
54 # Single destination
55 pg_set $dev "dst_mac $DST_MAC"
56 pg_set $dev "dst $DEST_IP"
57
58 # Randomize source IP-addresses
59 pg_set $dev "flag IPSRC_RND"
60 pg_set $dev "src_min 198.18.0.0"
61 pg_set $dev "src_max 198.19.255.255"
62
63 # Limit number of flows (max 65535)
64 pg_set $dev "flows $FLOWS"
65 #
66 # How many packets a flow will send, before flow "entry" is
67 # re-generated/setup.
68 pg_set $dev "flowlen $FLOWLEN"
69 #
70 # Flag FLOW_SEQ will cause $FLOWLEN packets from the same flow
71 # being send back-to-back, before next flow is selected
72 # incrementally. This helps lookup caches, and is more realistic.
73 #
74 pg_set $dev "flag FLOW_SEQ"
75
76done
77
78# Run if user hits control-c
79function print_result() {
80 # Print results
81 for ((thread = 0; thread < $THREADS; thread++)); do
82 dev=${DEV}@${thread}
83 echo "Device: $dev"
84 cat /proc/net/pktgen/$dev | grep -A2 "Result:"
85 done
86}
87# trap keyboard interrupt (Ctrl-C)
88trap true SIGINT
89
90echo "Running... ctrl^C to stop" >&2
91pg_ctrl "start"
92
93print_result
diff --git a/samples/pktgen/pktgen_sample05_flow_per_thread.sh b/samples/pktgen/pktgen_sample05_flow_per_thread.sh
new file mode 100755
index 000000000000..32ad818e2829
--- /dev/null
+++ b/samples/pktgen/pktgen_sample05_flow_per_thread.sh
@@ -0,0 +1,81 @@
1#!/bin/bash
2#
3# Script will generate one flow per thread (-t N)
4# - Same destination IP
5# - Fake source IPs for each flow (fixed based on thread number)
6#
7# Useful for scale testing on receiver, to see whether silo'ing flows
8# works and scales. For optimal scalability (on receiver) each
9# separate-flow should not access shared variables/data. This script
10# helps magnify any of these scaling issues by overloading the receiver.
11#
12basedir=`dirname $0`
13source ${basedir}/functions.sh
14root_check_run_with_sudo "$@"
15
16# Parameter parsing via include
17source ${basedir}/parameters.sh
18# Set some default params, if they didn't get set
19[ -z "$DEST_IP" ] && DEST_IP="198.18.0.42"
20[ -z "$DST_MAC" ] && DST_MAC="90:e2:ba:ff:ff:ff"
21[ -z "$CLONE_SKB" ] && CLONE_SKB="0"
22[ -z "$BURST" ] && BURST=32
23
24
25# Base Config
26DELAY="0" # Zero means max speed
27COUNT="0" # Zero means indefinitely
28
29# General cleanup everything since last run
30pg_ctrl "reset"
31
32# Threads are specified with parameter -t value in $THREADS
33for ((thread = 0; thread < $THREADS; thread++)); do
34 dev=${DEV}@${thread}
35
36 # Add remove all other devices and add_device $dev to thread
37 pg_thread $thread "rem_device_all"
38 pg_thread $thread "add_device" $dev
39
40 # Base config
41 pg_set $dev "flag QUEUE_MAP_CPU"
42 pg_set $dev "count $COUNT"
43 pg_set $dev "clone_skb $CLONE_SKB"
44 pg_set $dev "pkt_size $PKT_SIZE"
45 pg_set $dev "delay $DELAY"
46 pg_set $dev "flag NO_TIMESTAMP"
47
48 # Single destination
49 pg_set $dev "dst_mac $DST_MAC"
50 pg_set $dev "dst $DEST_IP"
51
52 # Setup source IP-addresses based on thread number
53 pg_set $dev "src_min 198.18.$((thread+1)).1"
54 pg_set $dev "src_max 198.18.$((thread+1)).1"
55
56 # Setup burst, for easy testing -b 0 disable bursting
57 # (internally in pktgen default and minimum burst=1)
58 if [[ ${BURST} -ne 0 ]]; then
59 pg_set $dev "burst $BURST"
60 else
61 info "$dev: Not using burst"
62 fi
63
64done
65
66# Run if user hits control-c
67function print_result() {
68 # Print results
69 for ((thread = 0; thread < $THREADS; thread++)); do
70 dev=${DEV}@${thread}
71 echo "Device: $dev"
72 cat /proc/net/pktgen/$dev | grep -A2 "Result:"
73 done
74}
75# trap keyboard interrupt (Ctrl-C)
76trap true SIGINT
77
78echo "Running... ctrl^C to stop" >&2
79pg_ctrl "start"
80
81print_result
diff --git a/samples/trace_printk/Makefile b/samples/trace_printk/Makefile
new file mode 100644
index 000000000000..19900ab2b00d
--- /dev/null
+++ b/samples/trace_printk/Makefile
@@ -0,0 +1,6 @@
1# builds a module that calls various trace_printk routines
2# then to use one (as root): insmod <module_name.ko>
3
4# This module can also be used to test the trace_printk code.
5
6obj-$(CONFIG_SAMPLE_TRACE_PRINTK) += trace-printk.o
diff --git a/samples/trace_printk/trace-printk.c b/samples/trace_printk/trace-printk.c
new file mode 100644
index 000000000000..e9e0040ff7be
--- /dev/null
+++ b/samples/trace_printk/trace-printk.c
@@ -0,0 +1,56 @@
1#include <linux/module.h>
2#include <linux/kthread.h>
3#include <linux/irq_work.h>
4
5/* Must not be static to force gcc to consider these non constant */
6char *trace_printk_test_global_str =
7 "This is a dynamic string that will use trace_puts\n";
8
9char *trace_printk_test_global_str_irq =
10 "(irq) This is a dynamic string that will use trace_puts\n";
11
12char *trace_printk_test_global_str_fmt =
13 "%sThis is a %s that will use trace_printk\n";
14
15static struct irq_work irqwork;
16
17static void trace_printk_irq_work(struct irq_work *work)
18{
19 trace_printk("(irq) This is a static string that will use trace_bputs\n");
20 trace_printk(trace_printk_test_global_str_irq);
21
22 trace_printk("(irq) This is a %s that will use trace_bprintk()\n",
23 "static string");
24
25 trace_printk(trace_printk_test_global_str_fmt,
26 "(irq) ", "dynamic string");
27}
28
29static int __init trace_printk_init(void)
30{
31 init_irq_work(&irqwork, trace_printk_irq_work);
32
33 trace_printk("This is a static string that will use trace_bputs\n");
34 trace_printk(trace_printk_test_global_str);
35
36 /* Kick off printing in irq context */
37 irq_work_queue(&irqwork);
38
39 trace_printk("This is a %s that will use trace_bprintk()\n",
40 "static string");
41
42 trace_printk(trace_printk_test_global_str_fmt, "", "dynamic string");
43
44 return 0;
45}
46
47static void __exit trace_printk_exit(void)
48{
49}
50
51module_init(trace_printk_init);
52module_exit(trace_printk_exit);
53
54MODULE_AUTHOR("Steven Rostedt");
55MODULE_DESCRIPTION("trace-printk");
56MODULE_LICENSE("GPL");
diff --git a/samples/v4l/v4l2-pci-skeleton.c b/samples/v4l/v4l2-pci-skeleton.c
index a55cf94ac907..93b76c3220fd 100644
--- a/samples/v4l/v4l2-pci-skeleton.c
+++ b/samples/v4l/v4l2-pci-skeleton.c
@@ -56,7 +56,6 @@ MODULE_LICENSE("GPL v2");
56 * @format: current pix format 56 * @format: current pix format
57 * @input: current video input (0 = SDTV, 1 = HDTV) 57 * @input: current video input (0 = SDTV, 1 = HDTV)
58 * @queue: vb2 video capture queue 58 * @queue: vb2 video capture queue
59 * @alloc_ctx: vb2 contiguous DMA context
60 * @qlock: spinlock controlling access to buf_list and sequence 59 * @qlock: spinlock controlling access to buf_list and sequence
61 * @buf_list: list of buffers queued for DMA 60 * @buf_list: list of buffers queued for DMA
62 * @sequence: frame sequence counter 61 * @sequence: frame sequence counter
@@ -73,7 +72,6 @@ struct skeleton {
73 unsigned input; 72 unsigned input;
74 73
75 struct vb2_queue queue; 74 struct vb2_queue queue;
76 struct vb2_alloc_ctx *alloc_ctx;
77 75
78 spinlock_t qlock; 76 spinlock_t qlock;
79 struct list_head buf_list; 77 struct list_head buf_list;
@@ -165,7 +163,7 @@ static irqreturn_t skeleton_irq(int irq, void *dev_id)
165 */ 163 */
166static int queue_setup(struct vb2_queue *vq, 164static int queue_setup(struct vb2_queue *vq,
167 unsigned int *nbuffers, unsigned int *nplanes, 165 unsigned int *nbuffers, unsigned int *nplanes,
168 unsigned int sizes[], void *alloc_ctxs[]) 166 unsigned int sizes[], struct device *alloc_devs[])
169{ 167{
170 struct skeleton *skel = vb2_get_drv_priv(vq); 168 struct skeleton *skel = vb2_get_drv_priv(vq);
171 169
@@ -182,7 +180,6 @@ static int queue_setup(struct vb2_queue *vq,
182 180
183 if (vq->num_buffers + *nbuffers < 3) 181 if (vq->num_buffers + *nbuffers < 3)
184 *nbuffers = 3 - vq->num_buffers; 182 *nbuffers = 3 - vq->num_buffers;
185 alloc_ctxs[0] = skel->alloc_ctx;
186 183
187 if (*nplanes) 184 if (*nplanes)
188 return sizes[0] < skel->format.sizeimage ? -EINVAL : 0; 185 return sizes[0] < skel->format.sizeimage ? -EINVAL : 0;
@@ -820,6 +817,7 @@ static int skeleton_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
820 q = &skel->queue; 817 q = &skel->queue;
821 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 818 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
822 q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; 819 q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
820 q->dev = &pdev->dev;
823 q->drv_priv = skel; 821 q->drv_priv = skel;
824 q->buf_struct_size = sizeof(struct skel_buffer); 822 q->buf_struct_size = sizeof(struct skel_buffer);
825 q->ops = &skel_qops; 823 q->ops = &skel_qops;
@@ -850,12 +848,6 @@ static int skeleton_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
850 if (ret) 848 if (ret)
851 goto free_hdl; 849 goto free_hdl;
852 850
853 skel->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
854 if (IS_ERR(skel->alloc_ctx)) {
855 dev_err(&pdev->dev, "Can't allocate buffer context");
856 ret = PTR_ERR(skel->alloc_ctx);
857 goto free_hdl;
858 }
859 INIT_LIST_HEAD(&skel->buf_list); 851 INIT_LIST_HEAD(&skel->buf_list);
860 spin_lock_init(&skel->qlock); 852 spin_lock_init(&skel->qlock);
861 853
@@ -885,13 +877,11 @@ static int skeleton_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
885 877
886 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); 878 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
887 if (ret) 879 if (ret)
888 goto free_ctx; 880 goto free_hdl;
889 881
890 dev_info(&pdev->dev, "V4L2 PCI Skeleton Driver loaded\n"); 882 dev_info(&pdev->dev, "V4L2 PCI Skeleton Driver loaded\n");
891 return 0; 883 return 0;
892 884
893free_ctx:
894 vb2_dma_contig_cleanup_ctx(skel->alloc_ctx);
895free_hdl: 885free_hdl:
896 v4l2_ctrl_handler_free(&skel->ctrl_handler); 886 v4l2_ctrl_handler_free(&skel->ctrl_handler);
897 v4l2_device_unregister(&skel->v4l2_dev); 887 v4l2_device_unregister(&skel->v4l2_dev);
@@ -907,7 +897,6 @@ static void skeleton_remove(struct pci_dev *pdev)
907 897
908 video_unregister_device(&skel->vdev); 898 video_unregister_device(&skel->vdev);
909 v4l2_ctrl_handler_free(&skel->ctrl_handler); 899 v4l2_ctrl_handler_free(&skel->ctrl_handler);
910 vb2_dma_contig_cleanup_ctx(skel->alloc_ctx);
911 v4l2_device_unregister(&skel->v4l2_dev); 900 v4l2_device_unregister(&skel->v4l2_dev);
912 pci_disable_device(skel->pdev); 901 pci_disable_device(skel->pdev);
913} 902}