-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathhelper_spec.json
2993 lines (2993 loc) · 95.7 KB
/
helper_spec.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
[{
"bpf_map_lookup_elem": {
"description": "Perform a lookup in *map* for an entry associated to *key*.",
"pre": {
"map": "!=null",
"key": "!=null"
},
"post": {
"return": "==null"
}
}
},
{
"bpf_map_update_elem": {
"description": "Add or update the value of the entry associated to *key* in *map* with *value*.",
"pre": {
"map": "!=null",
"key": "!=null",
"value": "!=null",
"flags": "in [BPF_NOEXIST, BPF_EXIST, BPF_ANY]",
"map_type": "not in [BPF_MAP_TYPE_ARRAY, BPF_MAP_TYPE_PERCPU_ARRAY] when flags == BPF_NOEXIST"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_map_delete_elem": {
"description": "Delete entry with *key* from *map*.",
"pre": {
"map": "!=null",
"key": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_probe_read": {
"description": "For tracing programs, safely attempt to read *size* bytes from kernel space address *unsafe_ptr* and store the data in *dst*.",
"pre": {
"dst": "!=null",
"size": ">=0",
"unsafe_ptr": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_ktime_get_ns": {
"description": "Return the time elapsed since system boot, in nanoseconds. Does not include time the system was suspended. See: clock_gettime (CLOCK_MONOTONIC)",
"pre": {},
"post": {
"return": "Current ktime"
}
}
},
{
"bpf_trace_printk": {
"description": "This helper is a \"printk()-like\" facility for debugging. It prints a message defined by format *fmt* (of size *fmt_size*) to file */sys/kernel/tracing/trace* from TraceFS, if available. It can take up to three additional **u64** arguments (as an eBPF helpers, the total number of arguments is limited to five).",
"pre": {
"fmt": "!=null",
"fmt_size": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_get_prandom_u32": {
"description": "Get a pseudo-random number.",
"pre": {},
"post": {
"return": "32-bit unsigned value"
}
}
},
{
"bpf_get_smp_processor_id": {
"description": "Get the SMP (symmetric multiprocessing) processor id. Note that all programs run with migration disabled, which means that the SMP processor id is stable during all the execution of the program.",
"pre": {},
"post": {
"return": ">= 0"
}
}
},
{
"bpf_skb_store_bytes": {
"description": "Store *len* bytes from address *from* into the packet associated to *skb*, at *offset*. *flags* are a combination of **BPF_F_RECOMPUTE_CSUM** (automatically recompute the checksum for the packet after storing the bytes) and **BPF_F_INVALIDATE_HASH** (set *skb*->hash, *skb*->swhash and *skb*->l4hash to 0).",
"pre": {
"skb": "!=null",
"offset": ">=0",
"from": "!=null",
"len": ">=0",
"flags": ">=0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_l3_csum_replace": {
"description": "Recompute the layer 3 (e.g. IP) checksum for the packet associated to *skb*.",
"pre": {
"skb": "!=null",
"offset": ">=0",
"from": ">=0",
"to": ">=0",
"size": "in [2, 4]"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_l4_csum_replace": {
"description": "Recompute the layer 4 (e.g. TCP, UDP or ICMP) checksum for the packet associated to *skb*.",
"pre": {
"skb": "!=null",
"offset": ">=0",
"from": ">=0",
"to": ">=0",
"flags": ">=0",
"flags & 0xF": "in [2, 4]",
"flags & ~0xF": "in [0, BPF_F_MARK_MANGLED_0, BPF_F_MARK_MANGLED_0 | BPF_F_MARK_ENFORCE, BPF_F_PSEUDO_HDR]"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_tail_call": {
"description": "This special helper is used to trigger a 'tail call', or in other words, to jump into another eBPF program.",
"pre": {
"ctx": "!=null",
"prog_array_map": "!=null",
"index": "!=null",
"prog_array_map_type": "== BPF_MAP_TYPE_PROG_ARRAY"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_clone_redirect": {
"description": "Clone and redirect the packet associated to *skb* to another net device of index *ifindex*.",
"pre": {
"skb": "!=null",
"ifindex": "!=null",
"flags": "in [BPF_F_INGRESS]"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_get_current_pid_tgid": {
"description": "Get the current pid and tgid.",
"pre": {},
"post": {
"return": "64-bit integer containing the current tgid and pid, created as: *current_task*->tgid << 32 | *current_task*->pid"
}
}
},
{
"bpf_get_current_uid_gid": {
"description": "Get the current uid and gid.",
"pre": {},
"post": {
"return": "64-bit integer containing the current GID and UID, created as such: *current_gid* << 32 | *current_uid*"
}
}
},
{
"bpf_get_current_comm": {
"description": "Copy the comm attribute of the current task into buf of size_of_buf. The comm attribute contains the name of the executable (excluding the path) for the current task. The size_of_buf must be strictly positive. On success, the helper makes sure that the buf is NUL-terminated. On failure, it is filled with zeroes.",
"pre": {
"buf": "!=null",
"size_of_buf": ">0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_get_cgroup_classid": {
"description": "Retrieve the classid for the current task, i.e. for the net_cls cgroup to which *skb* belongs.",
"pre": {
"skb": "!=null"
},
"post": {
"return": ">= 0"
}
}
},
{
"bpf_skb_vlan_push": {
"description": "Push a *vlan_tci* (VLAN tag control information) of protocol *vlan_proto* to the packet associated to *skb*, then update the checksum. Note that if *vlan_proto* is different from **ETH_P_8021Q** and **ETH_P_8021AD**, it is considered to be **ETH_P_8021Q**.",
"pre": {
"skb": "!=null",
"vlan_proto": "!=null",
"vlan_tci": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_skb_vlan_pop": {
"description": "Pop a VLAN header from the packet associated to *skb*.",
"pre": {
"skb": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_skb_get_tunnel_key": {
"description": "Get tunnel metadata.",
"pre": {
"skb": "!=null",
"key": "!=null",
"size": ">=sizeof(struct bpf_tunnel_key)",
"flags": "in [0, BPF_F_TUNINFO_IPV6]"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_skb_set_tunnel_key": {
"description": "Populate tunnel metadata for packet associated to *skb*.",
"pre": {
"skb": "!=null",
"key": "!=null",
"size": ">=0",
"flags": ">=0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_perf_event_read": {
"description": "Read the value of a perf event counter.",
"pre": {
"map": "!=null",
"flags": ">=0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_redirect": {
"description": "Redirect the packet to another net device of index *ifindex*.",
"pre": {
"ifindex": "!=null",
"flags": "in [0, BPF_F_INGRESS]"
},
"post": {
"return": "in [XDP_REDIRECT, XDP_ABORTED, TC_ACT_REDIRECT, TC_ACT_SHOT]"
}
}
},
{
"bpf_get_route_realm": {
"description": "Retrieve the realm or the route, that is to say the **tclassid** field of the destination for the *skb*.",
"pre": {
"skb": "!=null"
},
"post": {
"return": ">=0"
}
}
},
{
"bpf_perf_event_output": {
"description": "Write raw *data* blob into a special BPF perf event held by *map* of type BPF_MAP_TYPE_PERF_EVENT_ARRAY. This perf event must have the following attributes: PERF_SAMPLE_RAW as sample_type, PERF_TYPE_SOFTWARE as type, and PERF_COUNT_SW_BPF_OUTPUT as config.",
"pre": {
"ctx": "!=null",
"map": "!=null",
"flags": "in [BPF_F_INDEX_MASK, BPF_F_CURRENT_CPU]",
"data": "!=null",
"size": ">=0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_skb_load_bytes": {
"description": "This helper was provided as an easy way to load data from a packet. It can be used to load *len* bytes from *offset* from the packet associated to *skb*, into the buffer pointed by *to*.",
"pre": {
"skb": "!=null",
"offset": ">=0",
"to": "!=null",
"len": ">=0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_get_stackid": {
"description": "Walk a user or a kernel stack and return its id.",
"pre": {
"ctx": "!=null",
"map": "!=null",
"flags": ">=0, <=255"
},
"post": {
"return": ">=0, negative number"
}
}
},
{
"bpf_csum_diff": {
"description": "Compute a checksum difference from the raw buffer pointed by *from* towards the raw buffer pointed by *to*.",
"pre": {
"from": "!=null",
"from_size": "% 4 == 0",
"to": "!=null",
"to_size": "% 4 == 0",
"seed": ">= 0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_skb_get_tunnel_opt": {
"description": "Retrieve tunnel options metadata for the packet associated to *skb*, and store the raw tunnel option data to the buffer *opt* of *size*.",
"pre": {
"skb": "!=null",
"opt": "!=null",
"size": "!=null"
},
"post": {
"return": ">=0"
}
}
},
{
"bpf_skb_set_tunnel_opt": {
"description": "Set tunnel options metadata for the packet associated to *skb* to the option data contained in the raw buffer *opt* of *size*.",
"pre": {
"skb": "!=null",
"opt": "!=null",
"size": ">=0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_skb_change_proto": {
"description": "Change the protocol of the *skb* to *proto*. Currently supported are transition from IPv4 to IPv6, and from IPv6 to IPv4. The helper takes care of the groundwork for the transition, including resizing the socket buffer. The eBPF program is expected to fill the new headers, if any, via **skb_store_bytes**\\ () and to recompute the checksums with **bpf_l3_csum_replace**\\ () and **bpf_l4_csum_replace**\\ (). The main case for this helper is to perform NAT64 operations out of an eBPF program.\\n\\nInternally, the GSO type is marked as dodgy so that headers are checked and segments are recalculated by the GSO/GRO engine. The size for GSO target is adapted as well.\\n\\nAll values for *flags* are reserved for future usage, and must be left at zero.\\n\\nA call to this helper is susceptible to change the underlying packet buffer. Therefore, at load time, all checks on pointers previously done by the verifier are invalidated and must be performed again, if the helper is used in combination with direct packet access.",
"pre": {
"skb": "!=null",
"proto": "!=null",
"flags": "==0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_skb_change_type": {
"description": "Change the packet type for the packet associated to *skb*.",
"pre": {
"skb": "!=null",
"type": "in [PACKET_HOST, PACKET_BROADCAST, PACKET_MULTICAST, PACKET_OTHERHOST]"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_skb_under_cgroup": {
"description": "Check whether *skb* is a descendant of the cgroup2 held by *map* of type **BPF_MAP_TYPE_CGROUP_ARRAY**, at *index*.",
"pre": {
"skb": "!=null",
"map": "!=null",
"index": "!=null",
"map_type": "== BPF_MAP_TYPE_CGROUP_ARRAY"
},
"post": {
"return": "in [0, 1, negative number]"
}
}
},
{
"bpf_get_hash_recalc": {
"description": "Retrieve the hash of the packet, skb->hash. If it is not set, in particular if the hash was cleared due to mangling, recompute this hash. Later accesses to the hash can be done directly with skb->hash.",
"pre": {
"skb": "!=null"
},
"post": {
"return": "32-bit integer"
}
}
},
{
"bpf_get_current_task": {
"description": "Get the current task.",
"pre": {},
"post": {
"return": "!=null"
}
}
},
{
"bpf_probe_write_user": {
"description": "Attempt in a safe way to write *len* bytes from the buffer *src* to *dst* in memory.",
"pre": {
"dst": "!=null",
"src": "!=null",
"len": ">=0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_current_task_under_cgroup": {
"description": "Check whether the probe is being run in the context of a given subset of the cgroup2 hierarchy.",
"pre": {
"map": "!=null",
"index": "!=null",
"map_type": "BPF_MAP_TYPE_CGROUP_ARRAY"
},
"post": {
"return": "in [1, 0, negative number]"
}
}
},
{
"bpf_skb_change_tail": {
"description": "Resize (trim or grow) the packet associated to *skb* to the new *len*. The *flags* are reserved for future usage, and must be left at zero.",
"pre": {
"skb": "!=null",
"len": ">=0",
"flags": "==0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_skb_pull_data": {
"description": "Pull in non-linear data in case the *skb* is non-linear and not all of *len* are part of the linear section. Make *len* bytes from *skb* readable and writable. If a zero value is passed for *len*, then all bytes in the linear part of *skb* will be made readable and writable.",
"pre": {
"skb": "!=null",
"len": ">=0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_csum_update": {
"description": "Add the checksum *csum* into *skb*->csum in case the driver has supplied a checksum for the entire packet into that field. Return an error otherwise. This helper is intended to be used in combination with bpf_csum_diff(), in particular when the checksum needs to be updated after data has been written into the packet through direct packet access.",
"pre": {
"skb": "!=null",
"csum": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_set_hash_invalid": {
"description": "Invalidate the current skb->hash. It can be used after mangling on headers through direct packet access, in order to indicate that the hash is outdated and to trigger a recalculation the next time the kernel tries to access this hash or when the bpf_get_hash_recalc() helper is called.",
"pre": {},
"post": {
"return": "void"
}
}
},
{
"bpf_get_numa_node_id": {
"description": "Return the id of the current NUMA node. The primary use case for this helper is the selection of sockets for the local NUMA node, when the program is attached to sockets using the SO_ATTACH_REUSEPORT_EBPF option (see also socket(7)), but the helper is also available to other eBPF program types, similarly to bpf_get_smp_processor_id().",
"pre": {},
"post": {
"return": ">= 0"
}
}
},
{
"bpf_skb_change_head": {
"description": "Grows headroom of packet associated to *skb* and adjusts the offset of the MAC header accordingly, adding *len* bytes of space. It automatically extends and reallocates memory as required. This helper can be used on a layer 3 *skb* to push a MAC header for redirection into a layer 2 device. All values for *flags* are reserved for future usage, and must be left at zero. A call to this helper is susceptible to change the underlying packet buffer. Therefore, at load time, all checks on pointers previously done by the verifier are invalidated and must be performed again, if the helper is used in combination with direct packet access.",
"pre": {
"skb": "!=null",
"len": ">=0",
"flags": "==0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_xdp_adjust_head": {
"description": "Adjust (move) *xdp_md* ->data by *delta* bytes. Note that it is possible to use a negative value for *delta*. This helper can be used to prepare the packet for pushing or popping headers.",
"pre": {
"xdp_md": "!=null",
"delta": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_probe_read_str": {
"description": "Copy a NUL terminated string from an unsafe kernel address *unsafe_ptr* to *dst*.",
"pre": {
"dst": "!=null",
"size": ">=0",
"unsafe_ptr": "!=null"
},
"post": {
"return": "in [>0, negative number]"
}
}
},
{
"bpf_get_socket_cookie": {
"description": "If the struct sk_buff pointed by skb has a known socket, retrieve the cookie (generated by the kernel) of this socket. If no cookie has been set yet, generate a new cookie. Once generated, the socket cookie remains stable for the life of the socket. This helper can be useful for monitoring per socket networking traffic statistics as it provides a global socket identifier that can be assumed unique.",
"pre": {
"skb": "!=null"
},
"post": {
"return": "in [0, 8-byte long unique number]"
}
}
},
{
"bpf_get_socket_uid": {
"description": "Get the owner UID of the socket associated to *skb*.",
"pre": {
"skb": "!=null"
},
"post": {
"return": ">= 0"
}
}
},
{
"bpf_set_hash": {
"description": "Set the full hash for *skb* (set the field *skb*->hash) to value *hash*.",
"pre": {
"skb": "!=null",
"hash": "!=null"
},
"post": {
"return": "0"
}
}
},
{
"bpf_setsockopt": {
"description": "Emulate a call to setsockopt() on the socket associated to bpf_socket.",
"pre": {
"bpf_socket": "!=null",
"level": "!=null",
"optname": "!=null",
"optval": "!=null",
"optlen": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_skb_adjust_room": {
"description": "Grow or shrink the room for data in the packet associated to *skb* by *len_diff*, and according to the selected *mode*.",
"pre": {
"skb": "!=null",
"len_diff": "!=null",
"mode": "in [BPF_ADJ_ROOM_MAC, BPF_ADJ_ROOM_NET]",
"flags": "in [BPF_F_ADJ_ROOM_NO_CSUM_RESET, BPF_F_ADJ_ROOM_FIXED_GSO, BPF_F_ADJ_ROOM_ENCAP_L3_IPV4, BPF_F_ADJ_ROOM_ENCAP_L3_IPV6, BPF_F_ADJ_ROOM_ENCAP_L4_GRE, BPF_F_ADJ_ROOM_ENCAP_L4_UDP, BPF_F_ADJ_ROOM_ENCAP_L2_ETH, BPF_F_ADJ_ROOM_DECAP_L3_IPV4, BPF_F_ADJ_ROOM_DECAP_L3_IPV6]",
"flags_len": ">=0 when flags contains BPF_F_ADJ_ROOM_ENCAP_L2",
"flags_len": ">=0 when flags contains BPF_F_ADJ_ROOM_ENCAP_L2_ETH"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_redirect_map": {
"description": "Redirect the packet to the endpoint referenced by *map* at index *key*.",
"pre": {
"map": "!=null",
"key": "!=null",
"flags": "in [BPF_F_BROADCAST, BPF_F_EXCLUDE_INGRESS]",
"flags_lower_bits": "in [0, 1, 2, 3]",
"flags_higher_bits": "in [0, 1, 2, 3, 4, 5, 6, 7]",
"map_type": "not in [BPF_MAP_TYPE_ARRAY, BPF_MAP_TYPE_PERCPU_ARRAY]"
},
"post": {
"return": "in [XDP_REDIRECT, 0, 1, 2, 3]"
}
}
},
{
"bpf_sk_redirect_map": {
"description": "Redirect the packet to the socket referenced by *map* (of type **BPF_MAP_TYPE_SOCKMAP**) at index *key*. Both ingress and egress interfaces can be used for redirection. The **BPF_F_INGRESS** value in *flags* is used to make the distinction (ingress path is selected if the flag is present, egress path otherwise). This is the only flag supported for now.",
"pre": {
"skb": "!=null",
"map": "!=null",
"key": "!=null",
"flags": "in [BPF_F_INGRESS]"
},
"post": {
"return": "in [SK_PASS, SK_DROP]"
}
}
},
{
"bpf_sock_map_update": {
"description": "Add an entry to, or update a *map* referencing sockets.",
"pre": {
"skops": "!=null",
"map": "!=null",
"key": "!=null",
"flags": "in [BPF_NOEXIST, BPF_EXIST, BPF_ANY]"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_xdp_adjust_meta": {
"description": "Adjust the address pointed by *xdp_md*->data_meta by *delta* (which can be positive or negative).",
"pre": {
"xdp_md": "!=null",
"delta": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_perf_event_read_value": {
"description": "Read the value of a perf event counter, and store it into *buf* of size *buf_size*.",
"pre": {
"map": "!=null",
"flags": "!=null",
"buf": "!=null",
"buf_size": "!=null",
"map_type": "== BPF_MAP_TYPE_PERF_EVENT_ARRAY"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_perf_prog_read_value": {
"description": "For an eBPF program attached to a perf event, retrieve the value of the event counter associated to *ctx* and store it in the structure pointed by *buf* and of size *buf_size*. Enabled and running times are also stored in the structure (see description of helper **bpf_perf_event_read_value** for more details).",
"pre": {
"ctx": "!=null",
"buf": "!=null",
"buf_size": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_getsockopt": {
"description": "Emulate a call to getsockopt() on the socket associated to bpf_socket.",
"pre": {
"bpf_socket": "!=null",
"level": "!=null",
"optname": "!=null",
"optval": "!=null",
"optlen": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_override_return": {
"description": "Used for error injection, this helper uses kprobes to override the return value of the probed function, and to set it to *rc*. The first argument is the context *regs* on which the kprobe works.",
"pre": {
"regs": "!=null",
"rc": "!=null"
},
"post": {
"return": "0"
}
}
},
{
"bpf_sock_ops_cb_flags_set": {
"description": "Attempt to set the value of the bpf_sock_ops_cb_flags field for the full TCP socket associated to bpf_sock_ops to argval.",
"pre": {
"bpf_sock_ops": "!=null",
"argval": "in [BPF_SOCK_OPS_RTO_CB_FLAG, BPF_SOCK_OPS_RETRANS_CB_FLAG, BPF_SOCK_OPS_STATE_CB_FLAG, BPF_SOCK_OPS_RTT_CB_FLAG]"
},
"post": {
"return": "in [-EINVAL, positive number]"
}
}
},
{
"bpf_msg_redirect_map": {
"description": "This helper is used in programs implementing policies at the socket level. If the message *msg* is allowed to pass (i.e. if the verdict eBPF program returns **SK_PASS**), redirect it to the socket referenced by *map* (of type **BPF_MAP_TYPE_SOCKMAP**) at index *key*. Both ingress and egress interfaces can be used for redirection. The **BPF_F_INGRESS** value in *flags* is used to make the distinction (ingress path is selected if the flag is present, egress path otherwise). This is the only flag supported for now.",
"pre": {
"msg": "!=null",
"map": "!=null",
"key": "!=null",
"flags": "in [BPF_F_INGRESS]"
},
"post": {
"return": "in [SK_PASS, SK_DROP]"
}
}
},
{
"bpf_msg_apply_bytes": {
"description": "For socket policies, apply the verdict of the eBPF program to the next *bytes* (number of bytes) of message *msg*.",
"pre": {
"msg": "!=null",
"bytes": ">=0"
},
"post": {
"return": "0"
}
}
},
{
"bpf_msg_cork_bytes": {
"description": "For socket policies, prevent the execution of the verdict eBPF program for message *msg* until *bytes* (byte number) have been accumulated.",
"pre": {
"msg": "!=null",
"bytes": ">=0"
},
"post": {
"return": "0"
}
}
},
{
"bpf_msg_pull_data": {
"description": "For socket policies, pull in non-linear data from user space for *msg* and set pointers *msg*->data and *msg*->data_end to *start* and *end* bytes offsets into *msg*, respectively.",
"pre": {
"msg": "!=null",
"start": ">=0",
"end": ">=0",
"flags": "==0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_bind": {
"description": "Bind the socket associated to *ctx* to the address pointed by *addr*, of length *addr_len*.",
"pre": {
"ctx": "!=null",
"addr": "!=null",
"addr_len": ">=0",
"addr->sa_family": "==AF_INET || ==AF_INET6",
"addr->sin_port || addr->sin6_port": "==0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_xdp_adjust_tail": {
"description": "Adjust (move) *xdp_md*->data_end by *delta* bytes. It is possible to both shrink and grow the packet tail. Shrink done via *delta* being a negative integer.",
"pre": {
"xdp_md": "!=null",
"delta": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_skb_get_xfrm_state": {
"description": "Retrieve the XFRM state at index in XFRM 'security path' for skb.",
"pre": {
"skb": "!=null",
"index": "!=null",
"xfrm_state": "!=null",
"size": "!=null",
"flags": "==0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_get_stack": {
"description": "Return a user or a kernel stack in bpf program provided buffer.",
"pre": {
"ctx": "!=null",
"buf": "!=null",
"size": ">=0",
"flags": ">=0 and <=255",
"flags & BPF_F_SKIP_FIELD_MASK": "==0",
"flags & BPF_F_USER_STACK": "in [0, 1]",
"flags & BPF_F_USER_BUILD_ID": "in [0, 1] when flags & BPF_F_USER_STACK == 1"
},
"post": {
"return": ">=0 or negative number"
}
}
},
{
"bpf_skb_load_bytes_relative": {
"description": "This helper is similar to bpf_skb_load_bytes() in that it provides an easy way to load len bytes from offset from the packet associated to skb, into the buffer pointed by to. The difference to bpf_skb_load_bytes() is that a fifth argument start_header exists in order to select a base offset to start from. start_header can be one of: BPF_HDR_START_MAC - Base offset to load data from is skb's mac header. BPF_HDR_START_NET - Base offset to load data from is skb's network header. In general, 'direct packet access' is the preferred method to access packet data, however, this helper is in particular useful in socket filters where skb->data does not always point to the start of the mac header and where 'direct packet access' is not available.",
"pre": {
"skb": "!=null",
"offset": ">=0",
"to": "!=null",
"len": ">=0",
"start_header": "in [BPF_HDR_START_MAC, BPF_HDR_START_NET]"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_fib_lookup": {
"description": "Do FIB lookup in kernel tables using parameters in *params*.",
"pre": {
"ctx": "!=null",
"params": "!=null",
"plen": ">=0",
"flags": ">=0",
"tbid": ">=0 when flags & BPF_FIB_LOOKUP_DIRECT",
"dmac": "!=null when !(flags & BPF_FIB_LOOKUP_SKIP_NEIGH)",
"smac": "!=null when !(flags & BPF_FIB_LOOKUP_SKIP_NEIGH)"
},
"post": {
"return": "<=0"
}
}
},
{
"bpf_sock_hash_update": {
"description": "Add an entry to, or update a sockhash *map* referencing sockets.",
"pre": {
"skops": "!=null",
"map": "!=null",
"key": "!=null",
"flags": "in [BPF_NOEXIST, BPF_EXIST, BPF_ANY]"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_msg_redirect_hash": {
"description": "This helper is used in programs implementing policies at the socket level. If the message *msg* is allowed to pass (i.e. if the verdict eBPF program returns **SK_PASS**), redirect it to the socket referenced by *map* (of type **BPF_MAP_TYPE_SOCKHASH**) using hash *key*. Both ingress and egress interfaces can be used for redirection. The **BPF_F_INGRESS** value in *flags* is used to make the distinction (ingress path is selected if the flag is present, egress path otherwise). This is the only flag supported for now.",
"pre": {
"msg": "!=null",
"map": "!=null",
"key": "!=null",
"flags": "in [BPF_F_INGRESS]"
},
"post": {
"return": "in [SK_PASS, SK_DROP]"
}
}
},
{
"bpf_sk_redirect_hash": {
"description": "This helper is used in programs implementing policies at the skb socket level. If the sk_buff *skb* is allowed to pass (i.e. if the verdict eBPF program returns SK_PASS), redirect it to the socket referenced by *map* (of type BPF_MAP_TYPE_SOCKHASH) using hash *key*. Both ingress and egress interfaces can be used for redirection. The BPF_F_INGRESS value in *flags* is used to make the distinction (ingress path is selected if the flag is present, egress otherwise). This is the only flag supported for now.",
"pre": {
"skb": "!=null",
"map": "!=null",
"key": "!=null",
"flags": "in [BPF_F_INGRESS, 0]"
},
"post": {
"return": "in [SK_PASS, SK_DROP]"
}
}
},
{
"bpf_lwt_push_encap": {
"description": "Encapsulate the packet associated to *skb* within a Layer 3 protocol header.",
"pre": {
"skb": "!=null",
"type": "!=null",
"hdr": "!=null",
"len": "!=null",
"type": "in [BPF_LWT_ENCAP_SEG6, BPF_LWT_ENCAP_SEG6_INLINE, BPF_LWT_ENCAP_IP]",
"hdr": "in [struct ipv6_sr_hdr, struct ipv6_sr_hdr, IPv4, IPv6]"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_lwt_seg6_store_bytes": {
"description": "Store *len* bytes from address *from* into the packet associated to *skb*, at *offset*. Only the flags, tag and TLVs inside the outermost IPv6 Segment Routing Header can be modified through this helper.",
"pre": {
"skb": "!=null",
"offset": "!=null",
"from": "!=null",
"len": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_lwt_seg6_adjust_srh": {
"description": "Adjust the size allocated to TLVs in the outermost IPv6 Segment Routing Header contained in the packet associated to *skb*, at position *offset* by *delta* bytes. Only offsets after the segments are accepted. *delta* can be as well positive (growing) as negative (shrinking). A call to this helper is susceptible to change the underlying packet buffer. Therefore, at load time, all checks on pointers previously done by the verifier are invalidated and must be performed again, if the helper is used in combination with direct packet access.",
"pre": {
"skb": "!=null",
"offset": "!=null",
"delta": "!=null"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_lwt_seg6_action": {
"description": "Apply an IPv6 Segment Routing action to the packet.",
"pre": {
"skb": "!=null",
"action": "in [SEG6_LOCAL_ACTION_END_X, SEG6_LOCAL_ACTION_END_T, SEG6_LOCAL_ACTION_END_B6, SEG6_LOCAL_ACTION_END_B6_ENCAP]",
"param": "!=null",
"param_len": ">=0"
},
"post": {
"return": "in [0, negative number]"
}
}
},
{
"bpf_rc_repeat": {
"description": "This helper is used in programs implementing IR decoding, to report a successfully decoded repeat key message. This delays the generation of a key up event for previously generated key down event. Some IR protocols like NEC have a special IR message for repeating last button, for when a button is held down. The *ctx* should point to the lirc sample as passed into the program. This helper is only available if the kernel was compiled with the CONFIG_BPF_LIRC_MODE2 configuration option set to 'y'.",
"pre": {
"ctx": "!=null"
},
"post": {
"return": "0"
}
}
},
{
"bpf_rc_keydown": {
"description": "This helper is used in programs implementing IR decoding, to report a successfully decoded key press with scancode, toggle value in the given protocol. The scancode will be translated to a keycode using the rc keymap, and reported as an input key down event. After a period a key up event is generated. This period can be extended by calling either bpf_rc_keydown() again with the same values, or calling bpf_rc_repeat(). Some protocols include a toggle bit, in case the button was released and pressed again between consecutive scancodes. The ctx should point to the lirc sample as passed into the program. The protocol is the decoded protocol number (see enum rc_proto for some predefined values). This helper is only available if the kernel was compiled with the CONFIG_BPF_LIRC_MODE2 configuration option set to 'y'.",
"pre": {
"ctx": "!=null",