History

Merge tag 'bpf-next-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Pull bpf updates from Alexei Starovoitov: - Add BPF uprobe session support (Jiri Olsa) - Optimize uprobe performance (Andrii Nakryiko) - Add bpf_fastcall support to helpers and kfuncs (Eduard Zingerman) - Avoid calling free_htab_elem() under hash map bucket lock (Hou Tao) - Prevent tailcall infinite loop caused by freplace (Leon Hwang) - Mark raw_tracepoint arguments as nullable (Kumar Kartikeya Dwivedi) - Introduce uptr support in the task local storage map (Martin KaFai Lau) - Stringify errno log messages in libbpf (Mykyta Yatsenko) - Add kmem_cache BPF iterator for perf's lock profiling (Namhyung Kim) - Support BPF objects of either endianness in libbpf (Tony Ambardar) - Add ksym to struct_ops trampoline to fix stack trace (Xu Kuohai) - Introduce private stack for eligible BPF programs (Yonghong Song) - Migrate samples/bpf tests to selftests/bpf test_progs (Daniel T. Lee) - Migrate test_sock to selftests/bpf test_progs (Jordan Rife) * tag 'bpf-next-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (152 commits) libbpf: Change hash_combine parameters from long to unsigned long selftests/bpf: Fix build error with llvm 19 libbpf: Fix memory leak in bpf_program__attach_uprobe_multi bpf: use common instruction history across all states bpf: Add necessary migrate_disable to range_tree. bpf: Do not alloc arena on unsupported arches selftests/bpf: Set test path for token/obj_priv_implicit_token_envvar selftests/bpf: Add a test for arena range tree algorithm bpf: Introduce range_tree data structure and use it in bpf arena samples/bpf: Remove unused variable in xdp2skb_meta_kern.c samples/bpf: Remove unused variables in tc_l2_redirect_kern.c bpftool: Cast variable `var` to long long bpf, x86: Propagate tailcall info only for subprogs bpf: Add kernel symbol for struct_ops trampoline bpf: Use function pointers count as struct_ops links count bpf: Remove unused member rcu from bpf_struct_ops_map selftests/bpf: Add struct_ops prog private stack tests bpf: Support private stack for struct_ops progs selftests/bpf: Add tracing prog private stack tests bpf, x86: Support private stack in jit ...

Linus Torvalds committed 1 year ago

Commit 6e95ef02 parents 43fb83c 2c8b09a211 files · +6961 −3473Browse files

Showing the changes to samples (25 of 211 files). Show all

Unified · Split

25 files
  1. samples/bpf/Makefile +0 −25
  2. samples/bpf/sock_flags.bpf.c +0 −47
  3. samples/bpf/syscall_nrs.c +5 −0
  4. samples/bpf/tc_l2_redirect_kern.c +0 −6
  5. samples/bpf/test_cgrp2_array_pin.c +0 −106
  6. samples/bpf/test_cgrp2_attach.c +0 −177
  7. samples/bpf/test_cgrp2_sock.c +0 −294
  8. samples/bpf/test_cgrp2_sock.sh +0 −137
  9. samples/bpf/test_cgrp2_sock2.c +0 −95
  10. samples/bpf/test_cgrp2_sock2.sh +0 −103
  11. samples/bpf/test_cgrp2_tc.bpf.c +0 −56
  12. samples/bpf/test_cgrp2_tc.sh +0 −187
  13. samples/bpf/test_current_task_under_cgroup.bpf.c +0 −43
  14. samples/bpf/test_current_task_under_cgroup_user.c +0 −115
  15. samples/bpf/test_overhead_kprobe.bpf.c +0 −41
  16. samples/bpf/test_overhead_raw_tp.bpf.c +0 −17
  17. samples/bpf/test_overhead_tp.bpf.c +0 −23
  18. samples/bpf/test_overhead_user.c +0 −225
  19. samples/bpf/test_override_return.sh +0 −16
  20. samples/bpf/test_probe_write_user.bpf.c +0 −52
  21. samples/bpf/test_probe_write_user_user.c +0 −108
  22. samples/bpf/tracex7.bpf.c +0 −15
  23. samples/bpf/tracex7_user.c +0 −56
  24. samples/bpf/xdp2skb_meta_kern.c +1 −1
  25. samples/bpf/xdp_adjust_tail_kern.c +1 −0
samples/bpf/Makefile+0−25
@@ -17,20 +17,12 @@ tprogs-y += tracex3 · 16 unmodified lines
1717 tprogs-y += tracex4
1818 tprogs-y += tracex5
1919 tprogs-y += tracex6
20−tprogs-y += tracex7
21−tprogs-y += test_probe_write_user
2220 tprogs-y += trace_output
2321 tprogs-y += lathist
2422 tprogs-y += offwaketime
2523 tprogs-y += spintest
2624 tprogs-y += map_perf_test
27−tprogs-y += test_overhead
28−tprogs-y += test_cgrp2_array_pin
29−tprogs-y += test_cgrp2_attach
30−tprogs-y += test_cgrp2_sock
31−tprogs-y += test_cgrp2_sock2
3225 tprogs-y += xdp_router_ipv4
33−tprogs-y += test_current_task_under_cgroup
3426 tprogs-y += trace_event
3527 tprogs-y += sampleip
3628 tprogs-y += tc_l2_redirect
@@ -66,20 +58,12 @@ tracex3-objs := tracex3_user.o · 29 unmodified lines
6658 tracex4-objs := tracex4_user.o
6759 tracex5-objs := tracex5_user.o $(TRACE_HELPERS)
6860 tracex6-objs := tracex6_user.o
69−tracex7-objs := tracex7_user.o
70−test_probe_write_user-objs := test_probe_write_user_user.o
7161 trace_output-objs := trace_output_user.o
7262 lathist-objs := lathist_user.o
7363 offwaketime-objs := offwaketime_user.o $(TRACE_HELPERS)
7464 spintest-objs := spintest_user.o $(TRACE_HELPERS)
7565 map_perf_test-objs := map_perf_test_user.o
7666 test_overhead-objs := test_overhead_user.o
77−test_cgrp2_array_pin-objs := test_cgrp2_array_pin.o
78−test_cgrp2_attach-objs := test_cgrp2_attach.o
79−test_cgrp2_sock-objs := test_cgrp2_sock.o
80−test_cgrp2_sock2-objs := test_cgrp2_sock2.o
81−test_current_task_under_cgroup-objs := $(CGROUP_HELPERS) \
82− test_current_task_under_cgroup_user.o
8367 trace_event-objs := trace_event_user.o $(TRACE_HELPERS)
8468 sampleip-objs := sampleip_user.o $(TRACE_HELPERS)
8569 tc_l2_redirect-objs := tc_l2_redirect_user.o
@@ -107,9 +91,6 @@ always-y += tracex3.bpf.o · 21 unmodified lines
10791 always-y += tracex4.bpf.o
10892 always-y += tracex5.bpf.o
10993 always-y += tracex6.bpf.o
110−always-y += tracex7.bpf.o
111−always-y += sock_flags.bpf.o
112−always-y += test_probe_write_user.bpf.o
11394 always-y += trace_output.bpf.o
11495 always-y += tcbpf1_kern.o
11596 always-y += tc_l2_redirect_kern.o
@@ -117,12 +98,7 @@ always-y += lathist_kern.o · 1 unmodified line
11798 always-y += offwaketime.bpf.o
11899 always-y += spintest.bpf.o
119100 always-y += map_perf_test.bpf.o
120−always-y += test_overhead_tp.bpf.o
121−always-y += test_overhead_raw_tp.bpf.o
122−always-y += test_overhead_kprobe.bpf.o
123101 always-y += parse_varlen.o parse_simple.o parse_ldabs.o
124−always-y += test_cgrp2_tc.bpf.o
125−always-y += test_current_task_under_cgroup.bpf.o
126102 always-y += trace_event_kern.o
127103 always-y += sampleip_kern.o
128104 always-y += lwt_len_hist.bpf.o
@@ -195,7 +171,6 @@ TPROGLDLIBS_xdp_router_ipv4 += -lm -pthread · 66 unmodified lines
195171 TPROGLDLIBS_tracex4 += -lrt
196172 TPROGLDLIBS_trace_output += -lrt
197173 TPROGLDLIBS_map_perf_test += -lrt
198−TPROGLDLIBS_test_overhead += -lrt
199174
200175 # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline:
201176 # make M=samples/bpf LLC=~/git/llvm-project/llvm/build/bin/llc CLANG=~/git/llvm-project/llvm/build/bin/clang
samples/bpf/sock_flags.bpf.c+0−47
@@ -1,47 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0
2−#include "vmlinux.h"
3−#include "net_shared.h"
4−#include <bpf/bpf_helpers.h>
5−
6−SEC("cgroup/sock")
7−int bpf_prog1(struct bpf_sock *sk)
8−{
9− char fmt[] = "socket: family %d type %d protocol %d\n";
10− char fmt2[] = "socket: uid %u gid %u\n";
11− __u64 gid_uid = bpf_get_current_uid_gid();
12− __u32 uid = gid_uid & 0xffffffff;
13− __u32 gid = gid_uid >> 32;
14−
15− bpf_trace_printk(fmt, sizeof(fmt), sk->family, sk->type, sk->protocol);
16− bpf_trace_printk(fmt2, sizeof(fmt2), uid, gid);
17−
18− /* block AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6 sockets
19− * ie., make ping6 fail
20− */
21− if (sk->family == AF_INET6 &&
22− sk->type == SOCK_DGRAM &&
23− sk->protocol == IPPROTO_ICMPV6)
24− return 0;
25−
26− return 1;
27−}
28−
29−SEC("cgroup/sock")
30−int bpf_prog2(struct bpf_sock *sk)
31−{
32− char fmt[] = "socket: family %d type %d protocol %d\n";
33−
34− bpf_trace_printk(fmt, sizeof(fmt), sk->family, sk->type, sk->protocol);
35−
36− /* block AF_INET, SOCK_DGRAM, IPPROTO_ICMP sockets
37− * ie., make ping fail
38− */
39− if (sk->family == AF_INET &&
40− sk->type == SOCK_DGRAM &&
41− sk->protocol == IPPROTO_ICMP)
42− return 0;
43−
44− return 1;
45−}
46−
47−char _license[] SEC("license") = "GPL";
samples/bpf/syscall_nrs.c+5−0
@@ -2,6 +2,9 @@ · 1 unmodified line
22 #include <uapi/linux/unistd.h>
33 #include <linux/kbuild.h>
44
5+#pragma GCC diagnostic push
6+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
7+
58 #define SYSNR(_NR) DEFINE(SYS ## _NR, _NR)
69
710 void syscall_defines(void)
@@ -17,3 +20,5 @@ void syscall_defines(void) · 9 unmodified lines
1720 #endif
1821
1922 }
23+
24+#pragma GCC diagnostic pop
samples/bpf/tc_l2_redirect_kern.c+0−6
@@ -58,14 +58,11 @@ static __always_inline bool is_vip_addr(__be16 eth_proto, __be32 daddr) · 57 unmodified lines
5858 SEC("l2_to_iptun_ingress_forward")
5959 int _l2_to_iptun_ingress_forward(struct __sk_buff *skb)
6060 {
61− struct bpf_tunnel_key tkey = {};
6261 void *data = (void *)(long)skb->data;
6362 struct eth_hdr *eth = data;
6463 void *data_end = (void *)(long)skb->data_end;
6564 int key = 0, *ifindex;
6665
67− int ret;
68−
6966 if (data + sizeof(*eth) > data_end)
7067 return TC_ACT_OK;
7168
@@ -115,8 +112,6 @@ int _l2_to_iptun_ingress_redirect(struct __sk_buff *skb) · 43 unmodified lines
115112 void *data_end = (void *)(long)skb->data_end;
116113 int key = 0, *ifindex;
117114
118− int ret;
119−
120115 if (data + sizeof(*eth) > data_end)
121116 return TC_ACT_OK;
122117
@@ -205,7 +200,6 @@ int _l2_to_ip6tun_ingress_redirect(struct __sk_buff *skb) · 82 unmodified lines
205200 SEC("drop_non_tun_vip")
206201 int _drop_non_tun_vip(struct __sk_buff *skb)
207202 {
208− struct bpf_tunnel_key tkey = {};
209203 void *data = (void *)(long)skb->data;
210204 struct eth_hdr *eth = data;
211205 void *data_end = (void *)(long)skb->data_end;
samples/bpf/test_cgrp2_array_pin.c+0−106
@@ -1,106 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-only
2−/* Copyright (c) 2016 Facebook
3− */
4−#include <linux/unistd.h>
5−#include <linux/bpf.h>
6−
7−#include <stdio.h>
8−#include <stdint.h>
9−#include <unistd.h>
10−#include <string.h>
11−#include <errno.h>
12−#include <fcntl.h>
13−
14−#include <bpf/bpf.h>
15−
16−static void usage(void)
17−{
18− printf("Usage: test_cgrp2_array_pin [...]\n");
19− printf(" -F <file> File to pin an BPF cgroup array\n");
20− printf(" -U <file> Update an already pinned BPF cgroup array\n");
21− printf(" -v <value> Full path of the cgroup2\n");
22− printf(" -h Display this help\n");
23−}
24−
25−int main(int argc, char **argv)
26−{
27− const char *pinned_file = NULL, *cg2 = NULL;
28− int create_array = 1;
29− int array_key = 0;
30− int array_fd = -1;
31− int cg2_fd = -1;
32− int ret = -1;
33− int opt;
34−
35− while ((opt = getopt(argc, argv, "F:U:v:")) != -1) {
36− switch (opt) {
37− /* General args */
38− case 'F':
39− pinned_file = optarg;
40− break;
41− case 'U':
42− pinned_file = optarg;
43− create_array = 0;
44− break;
45− case 'v':
46− cg2 = optarg;
47− break;
48− default:
49− usage();
50− goto out;
51− }
52− }
53−
54− if (!cg2 || !pinned_file) {
55− usage();
56− goto out;
57− }
58−
59− cg2_fd = open(cg2, O_RDONLY);
60− if (cg2_fd < 0) {
61− fprintf(stderr, "open(%s,...): %s(%d)\n",
62− cg2, strerror(errno), errno);
63− goto out;
64− }
65−
66− if (create_array) {
67− array_fd = bpf_map_create(BPF_MAP_TYPE_CGROUP_ARRAY, NULL,
68− sizeof(uint32_t), sizeof(uint32_t),
69− 1, NULL);
70− if (array_fd < 0) {
71− fprintf(stderr,
72− "bpf_create_map(BPF_MAP_TYPE_CGROUP_ARRAY,...): %s(%d)\n",
73− strerror(errno), errno);
74− goto out;
75− }
76− } else {
77− array_fd = bpf_obj_get(pinned_file);
78− if (array_fd < 0) {
79− fprintf(stderr, "bpf_obj_get(%s): %s(%d)\n",
80− pinned_file, strerror(errno), errno);
81− goto out;
82− }
83− }
84−
85− ret = bpf_map_update_elem(array_fd, &array_key, &cg2_fd, 0);
86− if (ret) {
87− perror("bpf_map_update_elem");
88− goto out;
89− }
90−
91− if (create_array) {
92− ret = bpf_obj_pin(array_fd, pinned_file);
93− if (ret) {
94− fprintf(stderr, "bpf_obj_pin(..., %s): %s(%d)\n",
95− pinned_file, strerror(errno), errno);
96− goto out;
97− }
98− }
99−
100−out:
101− if (array_fd != -1)
102− close(array_fd);
103− if (cg2_fd != -1)
104− close(cg2_fd);
105− return ret;
106−}
samples/bpf/test_cgrp2_attach.c+0−177
@@ -1,177 +0,0 @@
1−/* eBPF example program:
2− *
3− * - Creates arraymap in kernel with 4 bytes keys and 8 byte values
4− *
5− * - Loads eBPF program
6− *
7− * The eBPF program accesses the map passed in to store two pieces of
8− * information. The number of invocations of the program, which maps
9− * to the number of packets received, is stored to key 0. Key 1 is
10− * incremented on each iteration by the number of bytes stored in
11− * the skb.
12− *
13− * - Attaches the new program to a cgroup using BPF_PROG_ATTACH
14− *
15− * - Every second, reads map[0] and map[1] to see how many bytes and
16− * packets were seen on any socket of tasks in the given cgroup.
17− */
18−
19−#define _GNU_SOURCE
20−
21−#include <stdio.h>
22−#include <stdlib.h>
23−#include <stddef.h>
24−#include <string.h>
25−#include <unistd.h>
26−#include <assert.h>
27−#include <errno.h>
28−#include <fcntl.h>
29−
30−#include <linux/bpf.h>
31−#include <bpf/bpf.h>
32−
33−#include "bpf_insn.h"
34−#include "bpf_util.h"
35−
36−enum {
37− MAP_KEY_PACKETS,
38− MAP_KEY_BYTES,
39−};
40−
41−char bpf_log_buf[BPF_LOG_BUF_SIZE];
42−
43−static int prog_load(int map_fd, int verdict)
44−{
45− struct bpf_insn prog[] = {
46− BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), /* save r6 so it's not clobbered by BPF_CALL */
47−
48− /* Count packets */
49− BPF_MOV64_IMM(BPF_REG_0, MAP_KEY_PACKETS), /* r0 = 0 */
50− BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4), /* *(u32 *)(fp - 4) = r0 */
51− BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
52− BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), /* r2 = fp - 4 */
53− BPF_LD_MAP_FD(BPF_REG_1, map_fd), /* load map fd to r1 */
54− BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
55− BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
56− BPF_MOV64_IMM(BPF_REG_1, 1), /* r1 = 1 */
57− BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_0, BPF_REG_1, 0),
58−
59− /* Count bytes */
60− BPF_MOV64_IMM(BPF_REG_0, MAP_KEY_BYTES), /* r0 = 1 */
61− BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4), /* *(u32 *)(fp - 4) = r0 */
62− BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
63− BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), /* r2 = fp - 4 */
64− BPF_LD_MAP_FD(BPF_REG_1, map_fd),
65− BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
66− BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
67− BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6, offsetof(struct __sk_buff, len)), /* r1 = skb->len */
68−
69− BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_0, BPF_REG_1, 0),
70−
71− BPF_MOV64_IMM(BPF_REG_0, verdict), /* r0 = verdict */
72− BPF_EXIT_INSN(),
73− };
74− size_t insns_cnt = ARRAY_SIZE(prog);
75− LIBBPF_OPTS(bpf_prog_load_opts, opts,
76− .log_buf = bpf_log_buf,
77− .log_size = BPF_LOG_BUF_SIZE,
78− );
79−
80− return bpf_prog_load(BPF_PROG_TYPE_CGROUP_SKB, NULL, "GPL",
81− prog, insns_cnt, &opts);
82−}
83−
84−static int usage(const char *argv0)
85−{
86− printf("Usage: %s [-d] [-D] <cg-path> <egress|ingress>\n", argv0);
87− printf(" -d Drop Traffic\n");
88− printf(" -D Detach filter, and exit\n");
89− return EXIT_FAILURE;
90−}
91−
92−static int attach_filter(int cg_fd, int type, int verdict)
93−{
94− int prog_fd, map_fd, ret, key;
95− long long pkt_cnt, byte_cnt;
96−
97− map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL,
98− sizeof(key), sizeof(byte_cnt),
99− 256, NULL);
100− if (map_fd < 0) {
101− printf("Failed to create map: '%s'\n", strerror(errno));
102− return EXIT_FAILURE;
103− }
104−
105− prog_fd = prog_load(map_fd, verdict);
106− printf("Output from kernel verifier:\n%s\n-------\n", bpf_log_buf);
107−
108− if (prog_fd < 0) {
109− printf("Failed to load prog: '%s'\n", strerror(errno));
110− return EXIT_FAILURE;
111− }
112−
113− ret = bpf_prog_attach(prog_fd, cg_fd, type, 0);
114− if (ret < 0) {
115− printf("Failed to attach prog to cgroup: '%s'\n",
116− strerror(errno));
117− return EXIT_FAILURE;
118− }
119− while (1) {
120− key = MAP_KEY_PACKETS;
121− assert(bpf_map_lookup_elem(map_fd, &key, &pkt_cnt) == 0);
122−
123− key = MAP_KEY_BYTES;
124− assert(bpf_map_lookup_elem(map_fd, &key, &byte_cnt) == 0);
125−
126− printf("cgroup received %lld packets, %lld bytes\n",
127− pkt_cnt, byte_cnt);
128− sleep(1);
129− }
130−
131− return EXIT_SUCCESS;
132−}
133−
134−int main(int argc, char **argv)
135−{
136− int detach_only = 0, verdict = 1;
137− enum bpf_attach_type type;
138− int opt, cg_fd, ret;
139−
140− while ((opt = getopt(argc, argv, "Dd")) != -1) {
141− switch (opt) {
142− case 'd':
143− verdict = 0;
144− break;
145− case 'D':
146− detach_only = 1;
147− break;
148− default:
149− return usage(argv[0]);
150− }
151− }
152−
153− if (argc - optind < 2)
154− return usage(argv[0]);
155−
156− if (strcmp(argv[optind + 1], "ingress") == 0)
157− type = BPF_CGROUP_INET_INGRESS;
158− else if (strcmp(argv[optind + 1], "egress") == 0)
159− type = BPF_CGROUP_INET_EGRESS;
160− else
161− return usage(argv[0]);
162−
163− cg_fd = open(argv[optind], O_DIRECTORY | O_RDONLY);
164− if (cg_fd < 0) {
165− printf("Failed to open cgroup path: '%s'\n", strerror(errno));
166− return EXIT_FAILURE;
167− }
168−
169− if (detach_only) {
170− ret = bpf_prog_detach(cg_fd, type);
171− printf("bpf_prog_detach() returned '%s' (%d)\n",
172− strerror(errno), errno);
173− } else
174− ret = attach_filter(cg_fd, type, verdict);
175−
176− return ret;
177−}
samples/bpf/test_cgrp2_sock.c+0−294
@@ -1,294 +0,0 @@
1−/* eBPF example program:
2− *
3− * - Loads eBPF program
4− *
5− * The eBPF program sets the sk_bound_dev_if index in new AF_INET{6}
6− * sockets opened by processes in the cgroup.
7− *
8− * - Attaches the new program to a cgroup using BPF_PROG_ATTACH
9− */
10−
11−#define _GNU_SOURCE
12−
13−#include <stdio.h>
14−#include <stdlib.h>
15−#include <stddef.h>
16−#include <string.h>
17−#include <unistd.h>
18−#include <assert.h>
19−#include <errno.h>
20−#include <fcntl.h>
21−#include <net/if.h>
22−#include <inttypes.h>
23−#include <linux/bpf.h>
24−#include <bpf/bpf.h>
25−
26−#include "bpf_insn.h"
27−
28−char bpf_log_buf[BPF_LOG_BUF_SIZE];
29−
30−static int prog_load(__u32 idx, __u32 mark, __u32 prio)
31−{
32− /* save pointer to context */
33− struct bpf_insn prog_start[] = {
34− BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
35− };
36− struct bpf_insn prog_end[] = {
37− BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = verdict */
38− BPF_EXIT_INSN(),
39− };
40−
41− /* set sk_bound_dev_if on socket */
42− struct bpf_insn prog_dev[] = {
43− BPF_MOV64_IMM(BPF_REG_3, idx),
44− BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, bound_dev_if)),
45− BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, bound_dev_if)),
46− };
47−
48− /* set mark on socket */
49− struct bpf_insn prog_mark[] = {
50− /* get uid of process */
51− BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
52− BPF_FUNC_get_current_uid_gid),
53− BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffffffff),
54−
55− /* if uid is 0, use given mark, else use the uid as the mark */
56− BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
57− BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
58− BPF_MOV64_IMM(BPF_REG_3, mark),
59−
60− /* set the mark on the new socket */
61− BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
62− BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, mark)),
63− BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, mark)),
64− };
65−
66− /* set priority on socket */
67− struct bpf_insn prog_prio[] = {
68− BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
69− BPF_MOV64_IMM(BPF_REG_3, prio),
70− BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, priority)),
71− BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, priority)),
72− };
73− LIBBPF_OPTS(bpf_prog_load_opts, opts,
74− .log_buf = bpf_log_buf,
75− .log_size = BPF_LOG_BUF_SIZE,
76− );
77−
78− struct bpf_insn *prog;
79− size_t insns_cnt;
80− void *p;
81− int ret;
82−
83− insns_cnt = sizeof(prog_start) + sizeof(prog_end);
84− if (idx)
85− insns_cnt += sizeof(prog_dev);
86−
87− if (mark)
88− insns_cnt += sizeof(prog_mark);
89−
90− if (prio)
91− insns_cnt += sizeof(prog_prio);
92−
93− p = prog = malloc(insns_cnt);
94− if (!prog) {
95− fprintf(stderr, "Failed to allocate memory for instructions\n");
96− return EXIT_FAILURE;
97− }
98−
99− memcpy(p, prog_start, sizeof(prog_start));
100− p += sizeof(prog_start);
101−
102− if (idx) {
103− memcpy(p, prog_dev, sizeof(prog_dev));
104− p += sizeof(prog_dev);
105− }
106−
107− if (mark) {
108− memcpy(p, prog_mark, sizeof(prog_mark));
109− p += sizeof(prog_mark);
110− }
111−
112− if (prio) {
113− memcpy(p, prog_prio, sizeof(prog_prio));
114− p += sizeof(prog_prio);
115− }
116−
117− memcpy(p, prog_end, sizeof(prog_end));
118− p += sizeof(prog_end);
119−
120− insns_cnt /= sizeof(struct bpf_insn);
121−
122− ret = bpf_prog_load(BPF_PROG_TYPE_CGROUP_SOCK, NULL, "GPL",
123− prog, insns_cnt, &opts);
124−
125− free(prog);
126−
127− return ret;
128−}
129−
130−static int get_bind_to_device(int sd, char *name, size_t len)
131−{
132− socklen_t optlen = len;
133− int rc;
134−
135− name[0] = '\0';
136− rc = getsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, &optlen);
137− if (rc < 0)
138− perror("setsockopt(SO_BINDTODEVICE)");
139−
140− return rc;
141−}
142−
143−static unsigned int get_somark(int sd)
144−{
145− unsigned int mark = 0;
146− socklen_t optlen = sizeof(mark);
147− int rc;
148−
149− rc = getsockopt(sd, SOL_SOCKET, SO_MARK, &mark, &optlen);
150− if (rc < 0)
151− perror("getsockopt(SO_MARK)");
152−
153− return mark;
154−}
155−
156−static unsigned int get_priority(int sd)
157−{
158− unsigned int prio = 0;
159− socklen_t optlen = sizeof(prio);
160− int rc;
161−
162− rc = getsockopt(sd, SOL_SOCKET, SO_PRIORITY, &prio, &optlen);
163− if (rc < 0)
164− perror("getsockopt(SO_PRIORITY)");
165−
166− return prio;
167−}
168−
169−static int show_sockopts(int family)
170−{
171− unsigned int mark, prio;
172− char name[16];
173− int sd;
174−
175− sd = socket(family, SOCK_DGRAM, 17);
176− if (sd < 0) {
177− perror("socket");
178− return 1;
179− }
180−
181− if (get_bind_to_device(sd, name, sizeof(name)) < 0)
182− return 1;
183−
184− mark = get_somark(sd);
185− prio = get_priority(sd);
186−
187− close(sd);
188−
189− printf("sd %d: dev %s, mark %u, priority %u\n", sd, name, mark, prio);
190−
191− return 0;
192−}
193−
194−static int usage(const char *argv0)
195−{
196− printf("Usage:\n");
197− printf(" Attach a program\n");
198− printf(" %s -b bind-to-dev -m mark -p prio cg-path\n", argv0);
199− printf("\n");
200− printf(" Detach a program\n");
201− printf(" %s -d cg-path\n", argv0);
202− printf("\n");
203− printf(" Show inherited socket settings (mark, priority, and device)\n");
204− printf(" %s [-6]\n", argv0);
205− return EXIT_FAILURE;
206−}
207−
208−int main(int argc, char **argv)
209−{
210− __u32 idx = 0, mark = 0, prio = 0;
211− const char *cgrp_path = NULL;
212− int cg_fd, prog_fd, ret;
213− int family = PF_INET;
214− int do_attach = 1;
215− int rc;
216−
217− while ((rc = getopt(argc, argv, "db:m:p:6")) != -1) {
218− switch (rc) {
219− case 'd':
220− do_attach = 0;
221− break;
222− case 'b':
223− idx = if_nametoindex(optarg);
224− if (!idx) {
225− idx = strtoumax(optarg, NULL, 0);
226− if (!idx) {
227− printf("Invalid device name\n");
228− return EXIT_FAILURE;
229− }
230− }
231− break;
232− case 'm':
233− mark = strtoumax(optarg, NULL, 0);
234− break;
235− case 'p':
236− prio = strtoumax(optarg, NULL, 0);
237− break;
238− case '6':
239− family = PF_INET6;
240− break;
241− default:
242− return usage(argv[0]);
243− }
244− }
245−
246− if (optind == argc)
247− return show_sockopts(family);
248−
249− cgrp_path = argv[optind];
250− if (!cgrp_path) {
251− fprintf(stderr, "cgroup path not given\n");
252− return EXIT_FAILURE;
253− }
254−
255− if (do_attach && !idx && !mark && !prio) {
256− fprintf(stderr,
257− "One of device, mark or priority must be given\n");
258− return EXIT_FAILURE;
259− }
260−
261− cg_fd = open(cgrp_path, O_DIRECTORY | O_RDONLY);
262− if (cg_fd < 0) {
263− printf("Failed to open cgroup path: '%s'\n", strerror(errno));
264− return EXIT_FAILURE;
265− }
266−
267− if (do_attach) {
268− prog_fd = prog_load(idx, mark, prio);
269− if (prog_fd < 0) {
270− printf("Failed to load prog: '%s'\n", strerror(errno));
271− printf("Output from kernel verifier:\n%s\n-------\n",
272− bpf_log_buf);
273− return EXIT_FAILURE;
274− }
275−
276− ret = bpf_prog_attach(prog_fd, cg_fd,
277− BPF_CGROUP_INET_SOCK_CREATE, 0);
278− if (ret < 0) {
279− printf("Failed to attach prog to cgroup: '%s'\n",
280− strerror(errno));
281− return EXIT_FAILURE;
282− }
283− } else {
284− ret = bpf_prog_detach(cg_fd, BPF_CGROUP_INET_SOCK_CREATE);
285− if (ret < 0) {
286− printf("Failed to detach prog from cgroup: '%s'\n",
287− strerror(errno));
288− return EXIT_FAILURE;
289− }
290− }
291−
292− close(cg_fd);
293− return EXIT_SUCCESS;
294−}
samples/bpf/test_cgrp2_sock.sh+0−137
@@ -1,137 +0,0 @@
1−#!/bin/sh
2−# SPDX-License-Identifier: GPL-2.0
3−
4−# Test various socket options that can be set by attaching programs to cgroups.
5−
6−MY_DIR=$(dirname $0)
7−TEST=$MY_DIR/test_cgrp2_sock
8−CGRP_MNT="/tmp/cgroupv2-test_cgrp2_sock"
9−
10−################################################################################
11−#
12−print_result()
13−{
14− local rc=$1
15− local status=" OK "
16−
17− [ $rc -ne 0 ] && status="FAIL"
18−
19− printf "%-50s [%4s]\n" "$2" "$status"
20−}
21−
22−check_sock()
23−{
24− out=$($TEST)
25− echo $out | grep -q "$1"
26− if [ $? -ne 0 ]; then
27− print_result 1 "IPv4: $2"
28− echo " expected: $1"
29− echo " have: $out"
30− rc=1
31− else
32− print_result 0 "IPv4: $2"
33− fi
34−}
35−
36−check_sock6()
37−{
38− out=$($TEST -6)
39− echo $out | grep -q "$1"
40− if [ $? -ne 0 ]; then
41− print_result 1 "IPv6: $2"
42− echo " expected: $1"
43− echo " have: $out"
44− rc=1
45− else
46− print_result 0 "IPv6: $2"
47− fi
48−}
49−
50−################################################################################
51−#
52−
53−cleanup()
54−{
55− echo $$ >> ${CGRP_MNT}/cgroup.procs
56− rmdir ${CGRP_MNT}/sockopts
57−}
58−
59−cleanup_and_exit()
60−{
61− local rc=$1
62− local msg="$2"
63−
64− [ -n "$msg" ] && echo "ERROR: $msg"
65−
66− $TEST -d ${CGRP_MNT}/sockopts
67− ip li del cgrp2_sock
68− umount ${CGRP_MNT}
69−
70− exit $rc
71−}
72−
73−
74−################################################################################
75−# main
76−
77−rc=0
78−
79−ip li add cgrp2_sock type dummy 2>/dev/null
80−
81−set -e
82−mkdir -p ${CGRP_MNT}
83−mount -t cgroup2 none ${CGRP_MNT}
84−set +e
85−
86−
87−# make sure we have a known start point
88−cleanup 2>/dev/null
89−
90−mkdir -p ${CGRP_MNT}/sockopts
91−[ $? -ne 0 ] && cleanup_and_exit 1 "Failed to create cgroup hierarchy"
92−
93−
94−# set pid into cgroup
95−echo $$ > ${CGRP_MNT}/sockopts/cgroup.procs
96−
97−# no bpf program attached, so socket should show no settings
98−check_sock "dev , mark 0, priority 0" "No programs attached"
99−check_sock6 "dev , mark 0, priority 0" "No programs attached"
100−
101−# verify device is set
102−#
103−$TEST -b cgrp2_sock ${CGRP_MNT}/sockopts
104−if [ $? -ne 0 ]; then
105− cleanup_and_exit 1 "Failed to install program to set device"
106−fi
107−check_sock "dev cgrp2_sock, mark 0, priority 0" "Device set"
108−check_sock6 "dev cgrp2_sock, mark 0, priority 0" "Device set"
109−
110−# verify mark is set
111−#
112−$TEST -m 666 ${CGRP_MNT}/sockopts
113−if [ $? -ne 0 ]; then
114− cleanup_and_exit 1 "Failed to install program to set mark"
115−fi
116−check_sock "dev , mark 666, priority 0" "Mark set"
117−check_sock6 "dev , mark 666, priority 0" "Mark set"
118−
119−# verify priority is set
120−#
121−$TEST -p 123 ${CGRP_MNT}/sockopts
122−if [ $? -ne 0 ]; then
123− cleanup_and_exit 1 "Failed to install program to set priority"
124−fi
125−check_sock "dev , mark 0, priority 123" "Priority set"
126−check_sock6 "dev , mark 0, priority 123" "Priority set"
127−
128−# all 3 at once
129−#
130−$TEST -b cgrp2_sock -m 666 -p 123 ${CGRP_MNT}/sockopts
131−if [ $? -ne 0 ]; then
132− cleanup_and_exit 1 "Failed to install program to set device, mark and priority"
133−fi
134−check_sock "dev cgrp2_sock, mark 666, priority 123" "Priority set"
135−check_sock6 "dev cgrp2_sock, mark 666, priority 123" "Priority set"
136−
137−cleanup_and_exit $rc
samples/bpf/test_cgrp2_sock2.c+0−95
@@ -1,95 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0
2−/* eBPF example program:
3− *
4− * - Loads eBPF program
5− *
6− * The eBPF program loads a filter from file and attaches the
7− * program to a cgroup using BPF_PROG_ATTACH
8− */
9−
10−#define _GNU_SOURCE
11−
12−#include <stdio.h>
13−#include <stdlib.h>
14−#include <stddef.h>
15−#include <string.h>
16−#include <unistd.h>
17−#include <assert.h>
18−#include <errno.h>
19−#include <fcntl.h>
20−#include <net/if.h>
21−#include <linux/bpf.h>
22−#include <bpf/bpf.h>
23−#include <bpf/libbpf.h>
24−
25−#include "bpf_insn.h"
26−
27−static int usage(const char *argv0)
28−{
29− printf("Usage: %s cg-path filter-path [filter-id]\n", argv0);
30− return EXIT_FAILURE;
31−}
32−
33−int main(int argc, char **argv)
34−{
35− int cg_fd, err, ret = EXIT_FAILURE, filter_id = 0, prog_cnt = 0;
36− const char *link_pin_path = "/sys/fs/bpf/test_cgrp2_sock2";
37− struct bpf_link *link = NULL;
38− struct bpf_program *progs[2];
39− struct bpf_program *prog;
40− struct bpf_object *obj;
41−
42− if (argc < 3)
43− return usage(argv[0]);
44−
45− if (argc > 3)
46− filter_id = atoi(argv[3]);
47−
48− cg_fd = open(argv[1], O_DIRECTORY | O_RDONLY);
49− if (cg_fd < 0) {
50− printf("Failed to open cgroup path: '%s'\n", strerror(errno));
51− return ret;
52− }
53−
54− obj = bpf_object__open_file(argv[2], NULL);
55− if (libbpf_get_error(obj)) {
56− printf("ERROR: opening BPF object file failed\n");
57− return ret;
58− }
59−
60− bpf_object__for_each_program(prog, obj) {
61− progs[prog_cnt] = prog;
62− prog_cnt++;
63− }
64−
65− if (filter_id >= prog_cnt) {
66− printf("Invalid program id; program not found in file\n");
67− goto cleanup;
68− }
69−
70− /* load BPF program */
71− if (bpf_object__load(obj)) {
72− printf("ERROR: loading BPF object file failed\n");
73− goto cleanup;
74− }
75−
76− link = bpf_program__attach_cgroup(progs[filter_id], cg_fd);
77− if (libbpf_get_error(link)) {
78− printf("ERROR: bpf_program__attach failed\n");
79− link = NULL;
80− goto cleanup;
81− }
82−
83− err = bpf_link__pin(link, link_pin_path);
84− if (err < 0) {
85− printf("ERROR: bpf_link__pin failed: %d\n", err);
86− goto cleanup;
87− }
88−
89− ret = EXIT_SUCCESS;
90−
91−cleanup:
92− bpf_link__destroy(link);
93− bpf_object__close(obj);
94− return ret;
95−}
samples/bpf/test_cgrp2_sock2.sh+0−103
@@ -1,103 +0,0 @@
1−#!/bin/bash
2−# SPDX-License-Identifier: GPL-2.0
3−
4−BPFFS=/sys/fs/bpf
5−MY_DIR=$(dirname $0)
6−TEST=$MY_DIR/test_cgrp2_sock2
7−LINK_PIN=$BPFFS/test_cgrp2_sock2
8−BPF_PROG=$MY_DIR/sock_flags.bpf.o
9−
10−function config_device {
11− ip netns add at_ns0
12− ip link add veth0 type veth peer name veth0b
13− ip link set veth0 netns at_ns0
14− ip netns exec at_ns0 sysctl -q net.ipv6.conf.veth0.disable_ipv6=0
15− ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0
16− ip netns exec at_ns0 ip addr add 2401:db00::1/64 dev veth0 nodad
17− ip netns exec at_ns0 ip link set dev veth0 up
18− sysctl -q net.ipv6.conf.veth0b.disable_ipv6=0
19− ip addr add 172.16.1.101/24 dev veth0b
20− ip addr add 2401:db00::2/64 dev veth0b nodad
21− ip link set veth0b up
22−}
23−
24−function config_cgroup {
25− rm -rf /tmp/cgroupv2
26− mkdir -p /tmp/cgroupv2
27− mount -t cgroup2 none /tmp/cgroupv2
28− mkdir -p /tmp/cgroupv2/foo
29− echo $$ >> /tmp/cgroupv2/foo/cgroup.procs
30−}
31−
32−function config_bpffs {
33− if mount | grep $BPFFS > /dev/null; then
34− echo "bpffs already mounted"
35− else
36− echo "bpffs not mounted. Mounting..."
37− mount -t bpf none $BPFFS
38− fi
39−}
40−
41−function attach_bpf {
42− $TEST /tmp/cgroupv2/foo $BPF_PROG $1
43− [ $? -ne 0 ] && exit 1
44−}
45−
46−function cleanup {
47− rm -rf $LINK_PIN
48− ip link del veth0b
49− ip netns delete at_ns0
50− umount /tmp/cgroupv2
51− rm -rf /tmp/cgroupv2
52−}
53−
54−cleanup 2>/dev/null
55−
56−set -e
57−config_device
58−config_cgroup
59−config_bpffs
60−set +e
61−
62−#
63−# Test 1 - fail ping6
64−#
65−attach_bpf 0
66−ping -c1 -w1 172.16.1.100
67−if [ $? -ne 0 ]; then
68− echo "ping failed when it should succeed"
69− cleanup
70− exit 1
71−fi
72−
73−ping6 -c1 -w1 2401:db00::1
74−if [ $? -eq 0 ]; then
75− echo "ping6 succeeded when it should not"
76− cleanup
77− exit 1
78−fi
79−
80−rm -rf $LINK_PIN
81−sleep 1 # Wait for link detach
82−
83−#
84−# Test 2 - fail ping
85−#
86−attach_bpf 1
87−ping6 -c1 -w1 2401:db00::1
88−if [ $? -ne 0 ]; then
89− echo "ping6 failed when it should succeed"
90− cleanup
91− exit 1
92−fi
93−
94−ping -c1 -w1 172.16.1.100
95−if [ $? -eq 0 ]; then
96− echo "ping succeeded when it should not"
97− cleanup
98− exit 1
99−fi
100−
101−cleanup
102−echo
103−echo "*** PASS ***"
samples/bpf/test_cgrp2_tc.bpf.c+0−56
@@ -1,56 +0,0 @@
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−#define KBUILD_MODNAME "foo"
8−#include "vmlinux.h"
9−#include "net_shared.h"
10−#include <bpf/bpf_helpers.h>
11−
12−/* copy of 'struct ethhdr' without __packed */
13−struct eth_hdr {
14− unsigned char h_dest[ETH_ALEN];
15− unsigned char h_source[ETH_ALEN];
16− unsigned short h_proto;
17−};
18−
19−struct {
20− __uint(type, BPF_MAP_TYPE_CGROUP_ARRAY);
21− __type(key, u32);
22− __type(value, u32);
23− __uint(pinning, LIBBPF_PIN_BY_NAME);
24− __uint(max_entries, 1);
25−} test_cgrp2_array_pin SEC(".maps");
26−
27−SEC("filter")
28−int handle_egress(struct __sk_buff *skb)
29−{
30− void *data = (void *)(long)skb->data;
31− struct eth_hdr *eth = data;
32− struct ipv6hdr *ip6h = data + sizeof(*eth);
33− void *data_end = (void *)(long)skb->data_end;
34− char dont_care_msg[] = "dont care %04x %d\n";
35− char pass_msg[] = "pass\n";
36− char reject_msg[] = "reject\n";
37−
38− /* single length check */
39− if (data + sizeof(*eth) + sizeof(*ip6h) > data_end)
40− return TC_ACT_OK;
41−
42− if (eth->h_proto != bpf_htons(ETH_P_IPV6) ||
43− ip6h->nexthdr != IPPROTO_ICMPV6) {
44− bpf_trace_printk(dont_care_msg, sizeof(dont_care_msg),
45− eth->h_proto, ip6h->nexthdr);
46− return TC_ACT_OK;
47− } else if (bpf_skb_under_cgroup(skb, &test_cgrp2_array_pin, 0) != 1) {
48− bpf_trace_printk(pass_msg, sizeof(pass_msg));
49− return TC_ACT_OK;
50− } else {
51− bpf_trace_printk(reject_msg, sizeof(reject_msg));
52− return TC_ACT_SHOT;
53− }
54−}
55−
56−char _license[] SEC("license") = "GPL";
samples/bpf/test_cgrp2_tc.sh+0−187
@@ -1,187 +0,0 @@
1−#!/bin/bash
2−# SPDX-License-Identifier: GPL-2.0
3−
4−MY_DIR=$(dirname $0)
5−# Details on the bpf prog
6−BPF_CGRP2_ARRAY_NAME='test_cgrp2_array_pin'
7−BPF_PROG="$MY_DIR/test_cgrp2_tc.bpf.o"
8−BPF_SECTION='filter'
9−
10−[ -z "$TC" ] && TC='tc'
11−[ -z "$IP" ] && IP='ip'
12−
13−# Names of the veth interface, net namespace...etc.
14−HOST_IFC='ve'
15−NS_IFC='vens'
16−NS='ns'
17−
18−find_mnt() {
19− cat /proc/mounts | \
20− awk '{ if ($3 == "'$1'" && mnt == "") { mnt = $2 }} END { print mnt }'
21−}
22−
23−# Init cgroup2 vars
24−init_cgrp2_vars() {
25− CGRP2_ROOT=$(find_mnt cgroup2)
26− if [ -z "$CGRP2_ROOT" ]
27− then
28− CGRP2_ROOT='/mnt/cgroup2'
29− MOUNT_CGRP2="yes"
30− fi
31− CGRP2_TC="$CGRP2_ROOT/tc"
32− CGRP2_TC_LEAF="$CGRP2_TC/leaf"
33−}
34−
35−# Init bpf fs vars
36−init_bpf_fs_vars() {
37− local bpf_fs_root=$(find_mnt bpf)
38− [ -n "$bpf_fs_root" ] || return -1
39− BPF_FS_TC_SHARE="$bpf_fs_root/tc/globals"
40−}
41−
42−setup_cgrp2() {
43− case $1 in
44− start)
45− if [ "$MOUNT_CGRP2" == 'yes' ]
46− then
47− [ -d $CGRP2_ROOT ] || mkdir -p $CGRP2_ROOT
48− mount -t cgroup2 none $CGRP2_ROOT || return $?
49− fi
50− mkdir -p $CGRP2_TC_LEAF
51− ;;
52− *)
53− rmdir $CGRP2_TC_LEAF && rmdir $CGRP2_TC
54− [ "$MOUNT_CGRP2" == 'yes' ] && umount $CGRP2_ROOT
55− ;;
56− esac
57−}
58−
59−setup_bpf_cgrp2_array() {
60− local bpf_cgrp2_array="$BPF_FS_TC_SHARE/$BPF_CGRP2_ARRAY_NAME"
61− case $1 in
62− start)
63− $MY_DIR/test_cgrp2_array_pin -U $bpf_cgrp2_array -v $CGRP2_TC
64− ;;
65− *)
66− [ -d "$BPF_FS_TC_SHARE" ] && rm -f $bpf_cgrp2_array
67− ;;
68− esac
69−}
70−
71−setup_net() {
72− case $1 in
73− start)
74− $IP link add $HOST_IFC type veth peer name $NS_IFC || return $?
75− $IP link set dev $HOST_IFC up || return $?
76− sysctl -q net.ipv6.conf.$HOST_IFC.disable_ipv6=0
77− sysctl -q net.ipv6.conf.$HOST_IFC.accept_dad=0
78−
79− $IP netns add $NS || return $?
80− $IP link set dev $NS_IFC netns $NS || return $?
81− $IP -n $NS link set dev $NS_IFC up || return $?
82− $IP netns exec $NS sysctl -q net.ipv6.conf.$NS_IFC.disable_ipv6=0
83− $IP netns exec $NS sysctl -q net.ipv6.conf.$NS_IFC.accept_dad=0
84− $TC qdisc add dev $HOST_IFC clsact || return $?
85− $TC filter add dev $HOST_IFC egress bpf da obj $BPF_PROG sec $BPF_SECTION || return $?
86− ;;
87− *)
88− $IP netns del $NS
89− $IP link del $HOST_IFC
90− ;;
91− esac
92−}
93−
94−run_in_cgrp() {
95− # Fork another bash and move it under the specified cgroup.
96− # It makes the cgroup cleanup easier at the end of the test.
97− cmd='echo $$ > '
98− cmd="$cmd $1/cgroup.procs; exec $2"
99− bash -c "$cmd"
100−}
101−
102−do_test() {
103− run_in_cgrp $CGRP2_TC_LEAF "ping -6 -c3 ff02::1%$HOST_IFC >& /dev/null"
104− local dropped=$($TC -s qdisc show dev $HOST_IFC | tail -3 | \
105− awk '/drop/{print substr($7, 0, index($7, ",")-1)}')
106− if [[ $dropped -eq 0 ]]
107− then
108− echo "FAIL"
109− return 1
110− else
111− echo "Successfully filtered $dropped packets"
112− return 0
113− fi
114−}
115−
116−do_exit() {
117− if [ "$DEBUG" == "yes" ] && [ "$MODE" != 'cleanuponly' ]
118− then
119− echo "------ DEBUG ------"
120− echo "mount: "; mount | grep -E '(cgroup2|bpf)'; echo
121− echo "$CGRP2_TC_LEAF: "; ls -l $CGRP2_TC_LEAF; echo
122− if [ -d "$BPF_FS_TC_SHARE" ]
123− then
124− echo "$BPF_FS_TC_SHARE: "; ls -l $BPF_FS_TC_SHARE; echo
125− fi
126− echo "Host net:"
127− $IP netns
128− $IP link show dev $HOST_IFC
129− $IP -6 a show dev $HOST_IFC
130− $TC -s qdisc show dev $HOST_IFC
131− echo
132− echo "$NS net:"
133− $IP -n $NS link show dev $NS_IFC
134− $IP -n $NS -6 link show dev $NS_IFC
135− echo "------ DEBUG ------"
136− echo
137− fi
138−
139− if [ "$MODE" != 'nocleanup' ]
140− then
141− setup_net stop
142− setup_bpf_cgrp2_array stop
143− setup_cgrp2 stop
144− fi
145−}
146−
147−init_cgrp2_vars
148−init_bpf_fs_vars
149−
150−while [[ $# -ge 1 ]]
151−do
152− a="$1"
153− case $a in
154− debug)
155− DEBUG='yes'
156− shift 1
157− ;;
158− cleanup-only)
159− MODE='cleanuponly'
160− shift 1
161− ;;
162− no-cleanup)
163− MODE='nocleanup'
164− shift 1
165− ;;
166− *)
167− echo "test_cgrp2_tc [debug] [cleanup-only | no-cleanup]"
168− echo " debug: Print cgrp and network setup details at the end of the test"
169− echo " cleanup-only: Try to cleanup things from last test. No test will be run"
170− echo " no-cleanup: Run the test but don't do cleanup at the end"
171− echo "[Note: If no arg is given, it will run the test and do cleanup at the end]"
172− echo
173− exit -1
174− ;;
175− esac
176−done
177−
178−trap do_exit 0
179−
180−[ "$MODE" == 'cleanuponly' ] && exit
181−
182−setup_cgrp2 start || exit $?
183−setup_net start || exit $?
184−init_bpf_fs_vars || exit $?
185−setup_bpf_cgrp2_array start || exit $?
186−do_test
187−echo
samples/bpf/test_current_task_under_cgroup.bpf.c+0−43
@@ -1,43 +0,0 @@
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−
8−#include "vmlinux.h"
9−#include <linux/version.h>
10−#include <bpf/bpf_helpers.h>
11−#include <bpf/bpf_tracing.h>
12−#include <bpf/bpf_core_read.h>
13−
14−struct {
15− __uint(type, BPF_MAP_TYPE_CGROUP_ARRAY);
16− __uint(key_size, sizeof(u32));
17− __uint(value_size, sizeof(u32));
18− __uint(max_entries, 1);
19−} cgroup_map SEC(".maps");
20−
21−struct {
22− __uint(type, BPF_MAP_TYPE_ARRAY);
23− __type(key, u32);
24− __type(value, u64);
25− __uint(max_entries, 1);
26−} perf_map SEC(".maps");
27−
28−/* Writes the last PID that called sync to a map at index 0 */
29−SEC("ksyscall/sync")
30−int BPF_KSYSCALL(bpf_prog1)
31−{
32− u64 pid = bpf_get_current_pid_tgid();
33− int idx = 0;
34−
35− if (!bpf_current_task_under_cgroup(&cgroup_map, 0))
36− return 0;
37−
38− bpf_map_update_elem(&perf_map, &idx, &pid, BPF_ANY);
39− return 0;
40−}
41−
42−char _license[] SEC("license") = "GPL";
43−u32 _version SEC("version") = LINUX_VERSION_CODE;
samples/bpf/test_current_task_under_cgroup_user.c+0−115
@@ -1,115 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-only
2−/* Copyright (c) 2016 Sargun Dhillon <sargun@sargun.me>
3− */
4−
5−#define _GNU_SOURCE
6−#include <stdio.h>
7−#include <unistd.h>
8−#include <bpf/bpf.h>
9−#include <bpf/libbpf.h>
10−#include "cgroup_helpers.h"
11−
12−#define CGROUP_PATH "/my-cgroup"
13−
14−int main(int argc, char **argv)
15−{
16− pid_t remote_pid, local_pid = getpid();
17− int cg2 = -1, idx = 0, rc = 1;
18− struct bpf_link *link = NULL;
19− struct bpf_program *prog;
20− struct bpf_object *obj;
21− char filename[256];
22− int map_fd[2];
23−
24− snprintf(filename, sizeof(filename), "%s.bpf.o", argv[0]);
25− obj = bpf_object__open_file(filename, NULL);
26− if (libbpf_get_error(obj)) {
27− fprintf(stderr, "ERROR: opening BPF object file failed\n");
28− return 0;
29− }
30−
31− prog = bpf_object__find_program_by_name(obj, "bpf_prog1");
32− if (!prog) {
33− printf("finding a prog in obj file failed\n");
34− goto cleanup;
35− }
36−
37− /* load BPF program */
38− if (bpf_object__load(obj)) {
39− fprintf(stderr, "ERROR: loading BPF object file failed\n");
40− goto cleanup;
41− }
42−
43− map_fd[0] = bpf_object__find_map_fd_by_name(obj, "cgroup_map");
44− map_fd[1] = bpf_object__find_map_fd_by_name(obj, "perf_map");
45− if (map_fd[0] < 0 || map_fd[1] < 0) {
46− fprintf(stderr, "ERROR: finding a map in obj file failed\n");
47− goto cleanup;
48− }
49−
50− link = bpf_program__attach(prog);
51− if (libbpf_get_error(link)) {
52− fprintf(stderr, "ERROR: bpf_program__attach failed\n");
53− link = NULL;
54− goto cleanup;
55− }
56−
57− if (setup_cgroup_environment())
58− goto err;
59−
60− cg2 = create_and_get_cgroup(CGROUP_PATH);
61−
62− if (cg2 < 0)
63− goto err;
64−
65− if (bpf_map_update_elem(map_fd[0], &idx, &cg2, BPF_ANY)) {
66− log_err("Adding target cgroup to map");
67− goto err;
68− }
69−
70− if (join_cgroup(CGROUP_PATH))
71− goto err;
72−
73− /*
74− * The installed helper program catched the sync call, and should
75− * write it to the map.
76− */
77−
78− sync();
79− bpf_map_lookup_elem(map_fd[1], &idx, &remote_pid);
80−
81− if (local_pid != remote_pid) {
82− fprintf(stderr,
83− "BPF Helper didn't write correct PID to map, but: %d\n",
84− remote_pid);
85− goto err;
86− }
87−
88− /* Verify the negative scenario; leave the cgroup */
89− if (join_cgroup("/"))
90− goto err;
91−
92− remote_pid = 0;
93− bpf_map_update_elem(map_fd[1], &idx, &remote_pid, BPF_ANY);
94−
95− sync();
96− bpf_map_lookup_elem(map_fd[1], &idx, &remote_pid);
97−
98− if (local_pid == remote_pid) {
99− fprintf(stderr, "BPF cgroup negative test did not work\n");
100− goto err;
101− }
102−
103− rc = 0;
104−
105−err:
106− if (cg2 != -1)
107− close(cg2);
108−
109− cleanup_cgroup_environment();
110−
111−cleanup:
112− bpf_link__destroy(link);
113− bpf_object__close(obj);
114− return rc;
115−}
samples/bpf/test_overhead_kprobe.bpf.c+0−41
@@ -1,41 +0,0 @@
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 "vmlinux.h"
8−#include <linux/version.h>
9−#include <bpf/bpf_helpers.h>
10−#include <bpf/bpf_tracing.h>
11−#include <bpf/bpf_core_read.h>
12−
13−SEC("kprobe/__set_task_comm")
14−int prog(struct pt_regs *ctx)
15−{
16− struct signal_struct *signal;
17− struct task_struct *tsk;
18− char oldcomm[TASK_COMM_LEN] = {};
19− char newcomm[TASK_COMM_LEN] = {};
20− u16 oom_score_adj;
21− u32 pid;
22−
23− tsk = (void *)PT_REGS_PARM1_CORE(ctx);
24−
25− pid = BPF_CORE_READ(tsk, pid);
26− bpf_core_read_str(oldcomm, sizeof(oldcomm), &tsk->comm);
27− bpf_core_read_str(newcomm, sizeof(newcomm),
28− (void *)PT_REGS_PARM2(ctx));
29− signal = BPF_CORE_READ(tsk, signal);
30− oom_score_adj = BPF_CORE_READ(signal, oom_score_adj);
31− return 0;
32−}
33−
34−SEC("kprobe/fib_table_lookup")
35−int prog2(struct pt_regs *ctx)
36−{
37− return 0;
38−}
39−
40−char _license[] SEC("license") = "GPL";
41−u32 _version SEC("version") = LINUX_VERSION_CODE;
samples/bpf/test_overhead_raw_tp.bpf.c+0−17
@@ -1,17 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0
2−/* Copyright (c) 2018 Facebook */
3−#include "vmlinux.h"
4−#include <bpf/bpf_helpers.h>
5−
6−SEC("raw_tracepoint/task_rename")
7−int prog(struct bpf_raw_tracepoint_args *ctx)
8−{
9− return 0;
10−}
11−
12−SEC("raw_tracepoint/fib_table_lookup")
13−int prog2(struct bpf_raw_tracepoint_args *ctx)
14−{
15− return 0;
16−}
17−char _license[] SEC("license") = "GPL";
samples/bpf/test_overhead_tp.bpf.c+0−23
@@ -1,23 +0,0 @@
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 "vmlinux.h"
8−#include <bpf/bpf_helpers.h>
9−
10−/* from /sys/kernel/tracing/events/task/task_rename/format */
11−SEC("tracepoint/task/task_rename")
12−int prog(struct trace_event_raw_task_rename *ctx)
13−{
14− return 0;
15−}
16−
17−/* from /sys/kernel/tracing/events/fib/fib_table_lookup/format */
18−SEC("tracepoint/fib/fib_table_lookup")
19−int prog2(struct trace_event_raw_fib_table_lookup *ctx)
20−{
21− return 0;
22−}
23−char _license[] SEC("license") = "GPL";
samples/bpf/test_overhead_user.c+0−225
@@ -1,225 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-only
2−/* Copyright (c) 2016 Facebook
3− */
4−#define _GNU_SOURCE
5−#include <sched.h>
6−#include <errno.h>
7−#include <stdio.h>
8−#include <sys/types.h>
9−#include <asm/unistd.h>
10−#include <fcntl.h>
11−#include <unistd.h>
12−#include <assert.h>
13−#include <sys/wait.h>
14−#include <sys/socket.h>
15−#include <arpa/inet.h>
16−#include <stdlib.h>
17−#include <signal.h>
18−#include <linux/bpf.h>
19−#include <string.h>
20−#include <time.h>
21−#include <bpf/bpf.h>
22−#include <bpf/libbpf.h>
23−
24−#define MAX_CNT 1000000
25−#define DUMMY_IP "127.0.0.1"
26−#define DUMMY_PORT 80
27−
28−static struct bpf_link *links[2];
29−static struct bpf_object *obj;
30−static int cnt;
31−
32−static __u64 time_get_ns(void)
33−{
34− struct timespec ts;
35−
36− clock_gettime(CLOCK_MONOTONIC, &ts);
37− return ts.tv_sec * 1000000000ull + ts.tv_nsec;
38−}
39−
40−static void test_task_rename(int cpu)
41−{
42− char buf[] = "test\n";
43− __u64 start_time;
44− int i, fd;
45−
46− fd = open("/proc/self/comm", O_WRONLY|O_TRUNC);
47− if (fd < 0) {
48− printf("couldn't open /proc\n");
49− exit(1);
50− }
51− start_time = time_get_ns();
52− for (i = 0; i < MAX_CNT; i++) {
53− if (write(fd, buf, sizeof(buf)) < 0) {
54− printf("task rename failed: %s\n", strerror(errno));
55− close(fd);
56− return;
57− }
58− }
59− printf("task_rename:%d: %lld events per sec\n",
60− cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
61− close(fd);
62−}
63−
64−static void test_fib_table_lookup(int cpu)
65−{
66− struct sockaddr_in addr;
67− char buf[] = "test\n";
68− __u64 start_time;
69− int i, fd;
70−
71− fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
72− if (fd < 0) {
73− printf("couldn't open socket\n");
74− exit(1);
75− }
76− memset((char *)&addr, 0, sizeof(addr));
77− addr.sin_addr.s_addr = inet_addr(DUMMY_IP);
78− addr.sin_port = htons(DUMMY_PORT);
79− addr.sin_family = AF_INET;
80− start_time = time_get_ns();
81− for (i = 0; i < MAX_CNT; i++) {
82− if (sendto(fd, buf, strlen(buf), 0,
83− (struct sockaddr *)&addr, sizeof(addr)) < 0) {
84− printf("failed to start ping: %s\n", strerror(errno));
85− close(fd);
86− return;
87− }
88− }
89− printf("fib_table_lookup:%d: %lld events per sec\n",
90− cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
91− close(fd);
92−}
93−
94−static void loop(int cpu, int flags)
95−{
96− cpu_set_t cpuset;
97−
98− CPU_ZERO(&cpuset);
99− CPU_SET(cpu, &cpuset);
100− sched_setaffinity(0, sizeof(cpuset), &cpuset);
101−
102− if (flags & 1)
103− test_task_rename(cpu);
104− if (flags & 2)
105− test_fib_table_lookup(cpu);
106−}
107−
108−static void run_perf_test(int tasks, int flags)
109−{
110− pid_t pid[tasks];
111− int i;
112−
113− for (i = 0; i < tasks; i++) {
114− pid[i] = fork();
115− if (pid[i] == 0) {
116− loop(i, flags);
117− exit(0);
118− } else if (pid[i] == -1) {
119− printf("couldn't spawn #%d process\n", i);
120− exit(1);
121− }
122− }
123− for (i = 0; i < tasks; i++) {
124− int status;
125−
126− assert(waitpid(pid[i], &status, 0) == pid[i]);
127− assert(status == 0);
128− }
129−}
130−
131−static int load_progs(char *filename)
132−{
133− struct bpf_program *prog;
134− int err = 0;
135−
136− obj = bpf_object__open_file(filename, NULL);
137− err = libbpf_get_error(obj);
138− if (err < 0) {
139− fprintf(stderr, "ERROR: opening BPF object file failed\n");
140− return err;
141− }
142−
143− /* load BPF program */
144− err = bpf_object__load(obj);
145− if (err < 0) {
146− fprintf(stderr, "ERROR: loading BPF object file failed\n");
147− return err;
148− }
149−
150− bpf_object__for_each_program(prog, obj) {
151− links[cnt] = bpf_program__attach(prog);
152− err = libbpf_get_error(links[cnt]);
153− if (err < 0) {
154− fprintf(stderr, "ERROR: bpf_program__attach failed\n");
155− links[cnt] = NULL;
156− return err;
157− }
158− cnt++;
159− }
160−
161− return err;
162−}
163−
164−static void unload_progs(void)
165−{
166− while (cnt)
167− bpf_link__destroy(links[--cnt]);
168−
169− bpf_object__close(obj);
170−}
171−
172−int main(int argc, char **argv)
173−{
174− int num_cpu = sysconf(_SC_NPROCESSORS_ONLN);
175− int test_flags = ~0;
176− char filename[256];
177− int err = 0;
178−
179−
180− if (argc > 1)
181− test_flags = atoi(argv[1]) ? : test_flags;
182− if (argc > 2)
183− num_cpu = atoi(argv[2]) ? : num_cpu;
184−
185− if (test_flags & 0x3) {
186− printf("BASE\n");
187− run_perf_test(num_cpu, test_flags);
188− }
189−
190− if (test_flags & 0xC) {
191− snprintf(filename, sizeof(filename),
192− "%s_kprobe.bpf.o", argv[0]);
193−
194− printf("w/KPROBE\n");
195− err = load_progs(filename);
196− if (!err)
197− run_perf_test(num_cpu, test_flags >> 2);
198−
199− unload_progs();
200− }
201−
202− if (test_flags & 0x30) {
203− snprintf(filename, sizeof(filename),
204− "%s_tp.bpf.o", argv[0]);
205− printf("w/TRACEPOINT\n");
206− err = load_progs(filename);
207− if (!err)
208− run_perf_test(num_cpu, test_flags >> 4);
209−
210− unload_progs();
211− }
212−
213− if (test_flags & 0xC0) {
214− snprintf(filename, sizeof(filename),
215− "%s_raw_tp.bpf.o", argv[0]);
216− printf("w/RAW_TRACEPOINT\n");
217− err = load_progs(filename);
218− if (!err)
219− run_perf_test(num_cpu, test_flags >> 6);
220−
221− unload_progs();
222− }
223−
224− return err;
225−}
samples/bpf/test_override_return.sh+0−16
@@ -1,16 +0,0 @@
1−#!/bin/bash
2−
3−rm -r tmpmnt
4−rm -f testfile.img
5−dd if=/dev/zero of=testfile.img bs=1M seek=1000 count=1
6−DEVICE=$(losetup --show -f testfile.img)
7−mkfs.btrfs -f $DEVICE
8−mkdir tmpmnt
9−./tracex7 $DEVICE
10−if [ $? -eq 0 ]
11−then
12− echo "SUCCESS!"
13−else
14− echo "FAILED!"
15−fi
16−losetup -d $DEVICE
samples/bpf/test_probe_write_user.bpf.c+0−52
@@ -1,52 +0,0 @@
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 "vmlinux.h"
8−#include <string.h>
9−#include <linux/version.h>
10−#include <bpf/bpf_helpers.h>
11−#include <bpf/bpf_tracing.h>
12−#include <bpf/bpf_core_read.h>
13−
14−struct {
15− __uint(type, BPF_MAP_TYPE_HASH);
16− __type(key, struct sockaddr_in);
17− __type(value, struct sockaddr_in);
18− __uint(max_entries, 256);
19−} dnat_map SEC(".maps");
20−
21−/* kprobe is NOT a stable ABI
22− * kernel functions can be removed, renamed or completely change semantics.
23− * Number of arguments and their positions can change, etc.
24− * In such case this bpf+kprobe example will no longer be meaningful
25− *
26− * This example sits on a syscall, and the syscall ABI is relatively stable
27− * of course, across platforms, and over time, the ABI may change.
28− */
29−SEC("ksyscall/connect")
30−int BPF_KSYSCALL(bpf_prog1, int fd, struct sockaddr_in *uservaddr,
31− int addrlen)
32−{
33− struct sockaddr_in new_addr, orig_addr = {};
34− struct sockaddr_in *mapped_addr;
35−
36− if (addrlen > sizeof(orig_addr))
37− return 0;
38−
39− if (bpf_probe_read_user(&orig_addr, sizeof(orig_addr), uservaddr) != 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(uservaddr, &new_addr,
46− sizeof(new_addr));
47− }
48− return 0;
49−}
50−
51−char _license[] SEC("license") = "GPL";
52−u32 _version SEC("version") = LINUX_VERSION_CODE;
samples/bpf/test_probe_write_user_user.c+0−108
@@ -1,108 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0
2−#include <stdio.h>
3−#include <assert.h>
4−#include <unistd.h>
5−#include <bpf/bpf.h>
6−#include <bpf/libbpf.h>
7−#include <sys/socket.h>
8−#include <netinet/in.h>
9−#include <arpa/inet.h>
10−
11−int main(int ac, char **argv)
12−{
13− struct sockaddr_in *serv_addr_in, *mapped_addr_in, *tmp_addr_in;
14− struct sockaddr serv_addr, mapped_addr, tmp_addr;
15− int serverfd, serverconnfd, clientfd, map_fd;
16− struct bpf_link *link = NULL;
17− struct bpf_program *prog;
18− struct bpf_object *obj;
19− socklen_t sockaddr_len;
20− char filename[256];
21− char *ip;
22−
23− serv_addr_in = (struct sockaddr_in *)&serv_addr;
24− mapped_addr_in = (struct sockaddr_in *)&mapped_addr;
25− tmp_addr_in = (struct sockaddr_in *)&tmp_addr;
26−
27− snprintf(filename, sizeof(filename), "%s.bpf.o", argv[0]);
28− obj = bpf_object__open_file(filename, NULL);
29− if (libbpf_get_error(obj)) {
30− fprintf(stderr, "ERROR: opening BPF object file failed\n");
31− return 0;
32− }
33−
34− prog = bpf_object__find_program_by_name(obj, "bpf_prog1");
35− if (libbpf_get_error(prog)) {
36− fprintf(stderr, "ERROR: finding a prog in obj file failed\n");
37− goto cleanup;
38− }
39−
40− /* load BPF program */
41− if (bpf_object__load(obj)) {
42− fprintf(stderr, "ERROR: loading BPF object file failed\n");
43− goto cleanup;
44− }
45−
46− map_fd = bpf_object__find_map_fd_by_name(obj, "dnat_map");
47− if (map_fd < 0) {
48− fprintf(stderr, "ERROR: finding a map in obj file failed\n");
49− goto cleanup;
50− }
51−
52− link = bpf_program__attach(prog);
53− if (libbpf_get_error(link)) {
54− fprintf(stderr, "ERROR: bpf_program__attach failed\n");
55− link = NULL;
56− goto cleanup;
57− }
58−
59− assert((serverfd = socket(AF_INET, SOCK_STREAM, 0)) > 0);
60− assert((clientfd = socket(AF_INET, SOCK_STREAM, 0)) > 0);
61−
62− /* Bind server to ephemeral port on lo */
63− memset(&serv_addr, 0, sizeof(serv_addr));
64− serv_addr_in->sin_family = AF_INET;
65− serv_addr_in->sin_port = 0;
66− serv_addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
67−
68− assert(bind(serverfd, &serv_addr, sizeof(serv_addr)) == 0);
69−
70− sockaddr_len = sizeof(serv_addr);
71− assert(getsockname(serverfd, &serv_addr, &sockaddr_len) == 0);
72− ip = inet_ntoa(serv_addr_in->sin_addr);
73− printf("Server bound to: %s:%d\n", ip, ntohs(serv_addr_in->sin_port));
74−
75− memset(&mapped_addr, 0, sizeof(mapped_addr));
76− mapped_addr_in->sin_family = AF_INET;
77− mapped_addr_in->sin_port = htons(5555);
78− mapped_addr_in->sin_addr.s_addr = inet_addr("255.255.255.255");
79−
80− assert(!bpf_map_update_elem(map_fd, &mapped_addr, &serv_addr, BPF_ANY));
81−
82− assert(listen(serverfd, 5) == 0);
83−
84− ip = inet_ntoa(mapped_addr_in->sin_addr);
85− printf("Client connecting to: %s:%d\n",
86− ip, ntohs(mapped_addr_in->sin_port));
87− assert(connect(clientfd, &mapped_addr, sizeof(mapped_addr)) == 0);
88−
89− sockaddr_len = sizeof(tmp_addr);
90− ip = inet_ntoa(tmp_addr_in->sin_addr);
91− assert((serverconnfd = accept(serverfd, &tmp_addr, &sockaddr_len)) > 0);
92− printf("Server received connection from: %s:%d\n",
93− ip, ntohs(tmp_addr_in->sin_port));
94−
95− sockaddr_len = sizeof(tmp_addr);
96− assert(getpeername(clientfd, &tmp_addr, &sockaddr_len) == 0);
97− ip = inet_ntoa(tmp_addr_in->sin_addr);
98− printf("Client's peer address: %s:%d\n",
99− ip, ntohs(tmp_addr_in->sin_port));
100−
101− /* Is the server's getsockname = the socket getpeername */
102− assert(memcmp(&serv_addr, &tmp_addr, sizeof(struct sockaddr_in)) == 0);
103−
104−cleanup:
105− bpf_link__destroy(link);
106− bpf_object__close(obj);
107− return 0;
108−}
samples/bpf/tracex7.bpf.c+0−15
@@ -1,15 +0,0 @@
1−#include "vmlinux.h"
2−#include <linux/version.h>
3−#include <bpf/bpf_helpers.h>
4−
5−SEC("kprobe/open_ctree")
6−int bpf_prog1(struct pt_regs *ctx)
7−{
8− unsigned long rc = -12;
9−
10− bpf_override_return(ctx, rc);
11− return 0;
12−}
13−
14−char _license[] SEC("license") = "GPL";
15−u32 _version SEC("version") = LINUX_VERSION_CODE;
samples/bpf/tracex7_user.c+0−56
@@ -1,56 +0,0 @@
1−#define _GNU_SOURCE
2−
3−#include <stdio.h>
4−#include <unistd.h>
5−#include <bpf/libbpf.h>
6−
7−int main(int argc, char **argv)
8−{
9− struct bpf_link *link = NULL;
10− struct bpf_program *prog;
11− struct bpf_object *obj;
12− char filename[256];
13− char command[256];
14− int ret = 0;
15− FILE *f;
16−
17− if (!argv[1]) {
18− fprintf(stderr, "ERROR: Run with the btrfs device argument!\n");
19− return 0;
20− }
21−
22− snprintf(filename, sizeof(filename), "%s.bpf.o", argv[0]);
23− obj = bpf_object__open_file(filename, NULL);
24− if (libbpf_get_error(obj)) {
25− fprintf(stderr, "ERROR: opening BPF object file failed\n");
26− return 0;
27− }
28−
29− prog = bpf_object__find_program_by_name(obj, "bpf_prog1");
30− if (!prog) {
31− fprintf(stderr, "ERROR: finding a prog in obj file failed\n");
32− goto cleanup;
33− }
34−
35− /* load BPF program */
36− if (bpf_object__load(obj)) {
37− fprintf(stderr, "ERROR: loading BPF object file failed\n");
38− goto cleanup;
39− }
40−
41− link = bpf_program__attach(prog);
42− if (libbpf_get_error(link)) {
43− fprintf(stderr, "ERROR: bpf_program__attach failed\n");
44− link = NULL;
45− goto cleanup;
46− }
47−
48− snprintf(command, 256, "mount %s tmpmnt/", argv[1]);
49− f = popen(command, "r");
50− ret = pclose(f);
51−
52−cleanup:
53− bpf_link__destroy(link);
54− bpf_object__close(obj);
55− return ret ? 0 : 1;
56−}
samples/bpf/xdp2skb_meta_kern.c+1−1
@@ -32,7 +32,7 @@ SEC("xdp_mark") · 31 unmodified lines
3232 int _xdp_mark(struct xdp_md *ctx)
3333 {
3434 struct meta_info *meta;
35− void *data, *data_end;
35+ void *data;
3636 int ret;
3737
3838 /* Reserve space in-front of data pointer for our meta info.
samples/bpf/xdp_adjust_tail_kern.c+1−0
@@ -57,6 +57,7 @@ static __always_inline void swap_mac(void *data, struct ethhdr *orig_eth) · 56 unmodified lines
5757
5858 static __always_inline __u16 csum_fold_helper(__u32 csum)
5959 {
60+ csum = (csum & 0xffff) + (csum >> 16);
6061 return ~((csum & 0xffff) + (csum >> 16));
6162 }
6263

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t