]> git.proxmox.com Git - mirror_iproute2.git/blob - examples/bpf/bpf_graft.c
f36d25a2a2c104adda2db360aecb590d6485e744
[mirror_iproute2.git] / examples / bpf / bpf_graft.c
1 #include <linux/bpf.h>
2
3 #include "bpf_funcs.h"
4
5 /* This example demonstrates how classifier run-time behaviour
6 * can be altered with tail calls. We start out with an empty
7 * jmp_tc array, then add section aaa to the array slot 0, and
8 * later on atomically replace it with section bbb. Note that
9 * as shown in other examples, the tc loader can prepopulate
10 * tail called sections, here we start out with an empty one
11 * on purpose to show it can also be done this way.
12 *
13 * tc filter add dev foo parent ffff: bpf obj graft.o
14 * tc exec bpf dbg
15 * [...]
16 * Socket Thread-20229 [001] ..s. 138993.003923: : fallthrough
17 * <idle>-0 [001] ..s. 138993.202265: : fallthrough
18 * Socket Thread-20229 [001] ..s. 138994.004149: : fallthrough
19 * [...]
20 *
21 * tc exec bpf graft m:globals/jmp_tc key 0 obj graft.o sec aaa
22 * tc exec bpf dbg
23 * [...]
24 * Socket Thread-19818 [002] ..s. 139012.053587: : aaa
25 * <idle>-0 [002] ..s. 139012.172359: : aaa
26 * Socket Thread-19818 [001] ..s. 139012.173556: : aaa
27 * [...]
28 *
29 * tc exec bpf graft m:globals/jmp_tc key 0 obj graft.o sec bbb
30 * tc exec bpf dbg
31 * [...]
32 * Socket Thread-19818 [002] ..s. 139022.102967: : bbb
33 * <idle>-0 [002] ..s. 139022.155640: : bbb
34 * Socket Thread-19818 [001] ..s. 139022.156730: : bbb
35 * [...]
36 */
37 struct bpf_elf_map __section("maps") jmp_tc = {
38 .type = BPF_MAP_TYPE_PROG_ARRAY,
39 .size_key = sizeof(int),
40 .size_value = sizeof(int),
41 .pinning = PIN_GLOBAL_NS,
42 .max_elem = 1,
43 };
44
45 __section("aaa") int cls_aaa(struct __sk_buff *skb)
46 {
47 char fmt[] = "aaa\n";
48
49 bpf_printk(fmt, sizeof(fmt));
50 return -1;
51 }
52
53 __section("bbb") int cls_bbb(struct __sk_buff *skb)
54 {
55 char fmt[] = "bbb\n";
56
57 bpf_printk(fmt, sizeof(fmt));
58 return -1;
59 }
60
61 __section("classifier") int cls_entry(struct __sk_buff *skb)
62 {
63 char fmt[] = "fallthrough\n";
64
65 bpf_tail_call(skb, &jmp_tc, 0);
66 bpf_printk(fmt, sizeof(fmt));
67 return -1;
68 }
69
70 char __license[] __section("license") = "GPL";