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