authorgravatar for mattnite@protonmail.comMatthew Knight <mattnite@protonmail.com> 2020-09-07 12:41:29-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-09-07 15:41:29-04:00
logdb7a2382977a12e3ad95e3f2249c538d9c31cd87
treeeee18ab6bd453284268700ed941872fcebbd46f3
parentf96f3265b56bddb4d4faa89d65b865d0a42ad5ed
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

BPF: add some more documentation (#6268)

* added documentation for ringbuffers, which context type maps to which program type, and added some formatting

1 files changed, 284 insertions(+), 4 deletions(-)

lib/std/os/linux/bpf.zig+284-4
......@@ -62,6 +62,7 @@ pub const MAXINSNS = 4096;
6262// instruction classes
6363/// jmp mode in word width
6464pub const JMP32 = 0x06;
65
6566/// alu mode in double word width
6667pub const ALU64 = 0x07;
6768
......@@ -72,14 +73,17 @@ pub const XADD = 0xc0;
7273// alu/jmp fields
7374/// mov reg to reg
7475pub const MOV = 0xb0;
76
7577/// sign extending arithmetic shift right */
7678pub const ARSH = 0xc0;
7779
7880// change endianness of a register
7981/// flags for endianness conversion:
8082pub const END = 0xd0;
83
8184/// convert to little-endian */
8285pub const TO_LE = 0x00;
86
8387/// convert to big-endian
8488pub const TO_BE = 0x08;
8589pub const FROM_LE = TO_LE;
......@@ -88,29 +92,39 @@ pub const FROM_BE = TO_BE;
8892// jmp encodings
8993/// jump != *
9094pub const JNE = 0x50;
95
9196/// LT is unsigned, '<'
9297pub const JLT = 0xa0;
98
9399/// LE is unsigned, '<=' *
94100pub const JLE = 0xb0;
101
95102/// SGT is signed '>', GT in x86
96103pub const JSGT = 0x60;
104
97105/// SGE is signed '>=', GE in x86
98106pub const JSGE = 0x70;
107
99108/// SLT is signed, '<'
100109pub const JSLT = 0xc0;
110
101111/// SLE is signed, '<='
102112pub const JSLE = 0xd0;
113
103114/// function call
104115pub const CALL = 0x80;
116
105117/// function return
106118pub const EXIT = 0x90;
107119
108120/// Flag for prog_attach command. If a sub-cgroup installs some bpf program, the
109121/// program in this cgroup yields to sub-cgroup program.
110122pub const F_ALLOW_OVERRIDE = 0x1;
123
111124/// Flag for prog_attach command. If a sub-cgroup installs some bpf program,
112125/// that cgroup program gets run in addition to the program in this cgroup.
113126pub const F_ALLOW_MULTI = 0x2;
127
114128/// Flag for prog_attach command.
115129pub const F_REPLACE = 0x4;
116130
......@@ -164,47 +178,61 @@ pub const PSEUDO_CALL = 1;
164178
165179/// flag for BPF_MAP_UPDATE_ELEM command. create new element or update existing
166180pub const ANY = 0;
181
167182/// flag for BPF_MAP_UPDATE_ELEM command. create new element if it didn't exist
168183pub const NOEXIST = 1;
184
169185/// flag for BPF_MAP_UPDATE_ELEM command. update existing element
170186pub const EXIST = 2;
187
171188/// flag for BPF_MAP_UPDATE_ELEM command. spin_lock-ed map_lookup/map_update
172189pub const F_LOCK = 4;
173190
174191/// flag for BPF_MAP_CREATE command */
175192pub const BPF_F_NO_PREALLOC = 0x1;
193
176194/// flag for BPF_MAP_CREATE command. Instead of having one common LRU list in
177195/// the BPF_MAP_TYPE_LRU_[PERCPU_]HASH map, use a percpu LRU list which can
178196/// scale and perform better. Note, the LRU nodes (including free nodes) cannot
179197/// be moved across different LRU lists.
180198pub const BPF_F_NO_COMMON_LRU = 0x2;
199
181200/// flag for BPF_MAP_CREATE command. Specify numa node during map creation
182201pub const BPF_F_NUMA_NODE = 0x4;
202
183203/// flag for BPF_MAP_CREATE command. Flags for BPF object read access from
184204/// syscall side
185205pub const BPF_F_RDONLY = 0x8;
206
186207/// flag for BPF_MAP_CREATE command. Flags for BPF object write access from
187208/// syscall side
188209pub const BPF_F_WRONLY = 0x10;
210
189211/// flag for BPF_MAP_CREATE command. Flag for stack_map, store build_id+offset
190212/// instead of pointer
191213pub const BPF_F_STACK_BUILD_ID = 0x20;
214
192215/// flag for BPF_MAP_CREATE command. Zero-initialize hash function seed. This
193216/// should only be used for testing.
194217pub const BPF_F_ZERO_SEED = 0x40;
218
195219/// flag for BPF_MAP_CREATE command Flags for accessing BPF object from program
196220/// side.
197221pub const BPF_F_RDONLY_PROG = 0x80;
222
198223/// flag for BPF_MAP_CREATE command. Flags for accessing BPF object from program
199224/// side.
200225pub const BPF_F_WRONLY_PROG = 0x100;
226
201227/// flag for BPF_MAP_CREATE command. Clone map from listener for newly accepted
202228/// socket
203229pub const BPF_F_CLONE = 0x200;
230
204231/// flag for BPF_MAP_CREATE command. Enable memory-mapping BPF map
205232pub const BPF_F_MMAPABLE = 0x400;
206233
207/// These values correspond to "syscalls" within the BPF program's environment
234/// These values correspond to "syscalls" within the BPF program's environment,
235/// each one is documented in std.os.linux.BPF.kern
208236pub const Helper = enum(i32) {
209237 unspec,
210238 map_lookup_elem,
......@@ -325,6 +353,29 @@ pub const Helper = enum(i32) {
325353 tcp_send_ack,
326354 send_signal_thread,
327355 jiffies64,
356 read_branch_records,
357 get_ns_current_pid_tgid,
358 xdp_output,
359 get_netns_cookie,
360 get_current_ancestor_cgroup_id,
361 sk_assign,
362 ktime_get_boot_ns,
363 seq_printf,
364 seq_write,
365 sk_cgroup_id,
366 sk_ancestor_cgroup_id,
367 ringbuf_output,
368 ringbuf_reserve,
369 ringbuf_submit,
370 ringbuf_discard,
371 ringbuf_query,
372 csum_level,
373 skc_to_tcp6_sock,
374 skc_to_tcp_sock,
375 skc_to_tcp_timewait_sock,
376 skc_to_tcp_request_sock,
377 skc_to_udp6_sock,
378 get_task_stack,
328379 _,
329380};
330381
......@@ -797,39 +848,123 @@ test "opcodes" {
797848}
798849
799850pub const Cmd = extern enum(usize) {
851 /// Create a map and return a file descriptor that refers to the map. The
852 /// close-on-exec file descriptor flag is automatically enabled for the new
853 /// file descriptor.
854 ///
855 /// uses MapCreateAttr
800856 map_create,
857
858 /// Look up an element by key in a specified map and return its value.
859 ///
860 /// uses MapElemAttr
801861 map_lookup_elem,
862
863 /// Create or update an element (key/value pair) in a specified map.
864 ///
865 /// uses MapElemAttr
802866 map_update_elem,
867
868 /// Look up and delete an element by key in a specified map.
869 ///
870 /// uses MapElemAttr
803871 map_delete_elem,
872
873 /// Look up an element by key in a specified map and return the key of the
874 /// next element.
804875 map_get_next_key,
876
877 /// Verify and load an eBPF program, returning a new file descriptor
878 /// associated with the program. The close-on-exec file descriptor flag
879 /// is automatically enabled for the new file descriptor.
880 ///
881 /// uses ProgLoadAttr
805882 prog_load,
883
884 /// Pin a map or eBPF program to a path within the minimal BPF filesystem
885 ///
886 /// uses ObjAttr
806887 obj_pin,
888
889 /// Get the file descriptor of a BPF object pinned to a certain path
890 ///
891 /// uses ObjAttr
807892 obj_get,
893
894 /// uses ProgAttachAttr
808895 prog_attach,
896
897 /// uses ProgAttachAttr
809898 prog_detach,
899
900 /// uses TestRunAttr
810901 prog_test_run,
902
903 /// uses GetIdAttr
811904 prog_get_next_id,
905
906 /// uses GetIdAttr
812907 map_get_next_id,
908
909 /// uses GetIdAttr
813910 prog_get_fd_by_id,
911
912 /// uses GetIdAttr
814913 map_get_fd_by_id,
914
915 /// uses InfoAttr
815916 obj_get_info_by_fd,
917
918 /// uses QueryAttr
816919 prog_query,
920
921 /// uses RawTracepointAttr
817922 raw_tracepoint_open,
923
924 /// uses BtfLoadAttr
818925 btf_load,
926
927 /// uses GetIdAttr
819928 btf_get_fd_by_id,
929
930 /// uses TaskFdQueryAttr
820931 task_fd_query,
932
933 /// uses MapElemAttr
821934 map_lookup_and_delete_elem,
822935 map_freeze,
936
937 /// uses GetIdAttr
823938 btf_get_next_id,
939
940 /// uses MapBatchAttr
824941 map_lookup_batch,
942
943 /// uses MapBatchAttr
825944 map_lookup_and_delete_batch,
945
946 /// uses MapBatchAttr
826947 map_update_batch,
948
949 /// uses MapBatchAttr
827950 map_delete_batch,
951
952 /// uses LinkCreateAttr
828953 link_create,
954
955 /// uses LinkUpdateAttr
829956 link_update,
957
958 /// uses GetIdAttr
830959 link_get_fd_by_id,
960
961 /// uses GetIdAttr
831962 link_get_next_id,
963
964 /// uses EnableStatsAttr
832965 enable_stats,
966
967 /// uses IterCreateAttr
833968 iter_create,
834969 link_detach,
835970 _,
......@@ -863,42 +998,138 @@ pub const MapType = extern enum(u32) {
863998 sk_storage,
864999 devmap_hash,
8651000 struct_ops,
1001
1002 /// An ordered and shared CPU version of perf_event_array. They have
1003 /// similar semantics:
1004 /// - variable length records
1005 /// - no blocking: when full, reservation fails
1006 /// - memory mappable for ease and speed
1007 /// - epoll notifications for new data, but can busy poll
1008 ///
1009 /// Ringbufs give BPF programs two sets of APIs:
1010 /// - ringbuf_output() allows copy data from one place to a ring
1011 /// buffer, similar to bpf_perf_event_output()
1012 /// - ringbuf_reserve()/ringbuf_commit()/ringbuf_discard() split the
1013 /// process into two steps. First a fixed amount of space is reserved,
1014 /// if that is successful then the program gets a pointer to a chunk of
1015 /// memory and can be submitted with commit() or discarded with
1016 /// discard()
1017 ///
1018 /// ringbuf_output() will incurr an extra memory copy, but allows to submit
1019 /// records of the length that's not known beforehand, and is an easy
1020 /// replacement for perf_event_outptu().
1021 ///
1022 /// ringbuf_reserve() avoids the extra memory copy but requires a known size
1023 /// of memory beforehand.
1024 ///
1025 /// ringbuf_query() allows to query properties of the map, 4 are currently
1026 /// supported:
1027 /// - BPF_RB_AVAIL_DATA: amount of unconsumed data in ringbuf
1028 /// - BPF_RB_RING_SIZE: returns size of ringbuf
1029 /// - BPF_RB_CONS_POS/BPF_RB_PROD_POS returns current logical position
1030 /// of consumer and producer respectively
1031 ///
1032 /// key size: 0
1033 /// value size: 0
1034 /// max entries: size of ringbuf, must be power of 2
8661035 ringbuf,
1036
8671037 _,
8681038};
8691039
8701040pub const ProgType = extern enum(u32) {
8711041 unspec,
1042
1043 /// context type: __sk_buff
8721044 socket_filter,
1045
1046 /// context type: bpf_user_pt_regs_t
8731047 kprobe,
1048
1049 /// context type: __sk_buff
8741050 sched_cls,
1051
1052 /// context type: __sk_buff
8751053 sched_act,
1054
1055 /// context type: u64
8761056 tracepoint,
1057
1058 /// context type: xdp_md
8771059 xdp,
1060
1061 /// context type: bpf_perf_event_data
8781062 perf_event,
1063
1064 /// context type: __sk_buff
8791065 cgroup_skb,
1066
1067 /// context type: bpf_sock
8801068 cgroup_sock,
1069
1070 /// context type: __sk_buff
8811071 lwt_in,
1072
1073 /// context type: __sk_buff
8821074 lwt_out,
1075
1076 /// context type: __sk_buff
8831077 lwt_xmit,
1078
1079 /// context type: bpf_sock_ops
8841080 sock_ops,
1081
1082 /// context type: __sk_buff
8851083 sk_skb,
1084
1085 /// context type: bpf_cgroup_dev_ctx
8861086 cgroup_device,
1087
1088 /// context type: sk_msg_md
8871089 sk_msg,
1090
1091 /// context type: bpf_raw_tracepoint_args
8881092 raw_tracepoint,
1093
1094 /// context type: bpf_sock_addr
8891095 cgroup_sock_addr,
1096
1097 /// context type: __sk_buff
8901098 lwt_seg6local,
1099
1100 /// context type: u32
8911101 lirc_mode2,
1102
1103 /// context type: sk_reuseport_md
8921104 sk_reuseport,
1105
1106 /// context type: __sk_buff
8931107 flow_dissector,
1108
1109 /// context type: bpf_sysctl
8941110 cgroup_sysctl,
1111
1112 /// context type: bpf_raw_tracepoint_args
8951113 raw_tracepoint_writable,
1114
1115 /// context type: bpf_sockopt
8961116 cgroup_sockopt,
1117
1118 /// context type: void *
8971119 tracing,
1120
1121 /// context type: void *
8981122 struct_ops,
1123
1124 /// context type: void *
8991125 ext,
1126
1127 /// context type: void *
9001128 lsm,
1129
1130 /// context type: bpf_sk_lookup
9011131 sk_lookup,
1132 _,
9021133};
9031134
9041135pub const AttachType = extern enum(u32) {
......@@ -948,27 +1179,38 @@ const obj_name_len = 16;
9481179pub const MapCreateAttr = extern struct {
9491180 /// one of MapType
9501181 map_type: u32,
1182
9511183 /// size of key in bytes
9521184 key_size: u32,
1185
9531186 /// size of value in bytes
9541187 value_size: u32,
1188
9551189 /// max number of entries in a map
9561190 max_entries: u32,
1191
9571192 /// .map_create related flags
9581193 map_flags: u32,
1194
9591195 /// fd pointing to the inner map
9601196 inner_map_fd: fd_t,
1197
9611198 /// numa node (effective only if MapCreateFlags.numa_node is set)
9621199 numa_node: u32,
9631200 map_name: [obj_name_len]u8,
1201
9641202 /// ifindex of netdev to create on
9651203 map_ifindex: u32,
1204
9661205 /// fd pointing to a BTF type data
9671206 btf_fd: fd_t,
1207
9681208 /// BTF type_id of the key
9691209 btf_key_type_id: u32,
1210
9701211 /// BTF type_id of the value
9711212 bpf_value_type_id: u32,
1213
9721214 /// BTF type_id of a kernel struct stored as the map value
9731215 btf_vmlinux_value_type_id: u32,
9741216};
......@@ -988,10 +1230,12 @@ pub const MapElemAttr = extern struct {
9881230pub const MapBatchAttr = extern struct {
9891231 /// start batch, NULL to start from beginning
9901232 in_batch: u64,
1233
9911234 /// output: next start batch
9921235 out_batch: u64,
9931236 keys: u64,
9941237 values: u64,
1238
9951239 /// input/output:
9961240 /// input: # of key/value elements
9971241 /// output: # of filled elements
......@@ -1008,35 +1252,49 @@ pub const ProgLoadAttr = extern struct {
10081252 insn_cnt: u32,
10091253 insns: u64,
10101254 license: u64,
1255
10111256 /// verbosity level of verifier
10121257 log_level: u32,
1258
10131259 /// size of user buffer
10141260 log_size: u32,
1261
10151262 /// user supplied buffer
10161263 log_buf: u64,
1264
10171265 /// not used
10181266 kern_version: u32,
10191267 prog_flags: u32,
10201268 prog_name: [obj_name_len]u8,
1021 /// ifindex of netdev to prep for. For some prog types expected attach
1022 /// type must be known at load time to verify attach type specific parts
1023 /// of prog (context accesses, allowed helpers, etc).
1269
1270 /// ifindex of netdev to prep for.
10241271 prog_ifindex: u32,
1272
1273 /// For some prog types expected attach type must be known at load time to
1274 /// verify attach type specific parts of prog (context accesses, allowed
1275 /// helpers, etc).
10251276 expected_attach_type: u32,
1277
10261278 /// fd pointing to BTF type data
10271279 prog_btf_fd: fd_t,
1280
10281281 /// userspace bpf_func_info size
10291282 func_info_rec_size: u32,
10301283 func_info: u64,
1284
10311285 /// number of bpf_func_info records
10321286 func_info_cnt: u32,
1287
10331288 /// userspace bpf_line_info size
10341289 line_info_rec_size: u32,
10351290 line_info: u64,
1291
10361292 /// number of bpf_line_info records
10371293 line_info_cnt: u32,
1294
10381295 /// in-kernel BTF type id to attach to
10391296 attact_btf_id: u32,
1297
10401298 /// 0 to attach to vmlinux
10411299 attach_prog_id: u32,
10421300};
......@@ -1052,10 +1310,13 @@ pub const ObjAttr = extern struct {
10521310pub const ProgAttachAttr = extern struct {
10531311 /// container object to attach to
10541312 target_fd: fd_t,
1313
10551314 /// eBPF program to attach
10561315 attach_bpf_fd: fd_t,
1316
10571317 attach_type: u32,
10581318 attach_flags: u32,
1319
10591320 // TODO: BPF_F_REPLACE flags
10601321 /// previously attached eBPF program to replace if .replace is used
10611322 replace_bpf_fd: fd_t,
......@@ -1065,16 +1326,20 @@ pub const ProgAttachAttr = extern struct {
10651326pub const TestAttr = extern struct {
10661327 prog_fd: fd_t,
10671328 retval: u32,
1329
10681330 /// input: len of data_in
10691331 data_size_in: u32,
1332
10701333 /// input/output: len of data_out. returns ENOSPC if data_out is too small.
10711334 data_size_out: u32,
10721335 data_in: u64,
10731336 data_out: u64,
10741337 repeat: u32,
10751338 duration: u32,
1339
10761340 /// input: len of ctx_in
10771341 ctx_size_in: u32,
1342
10781343 /// input/output: len of ctx_out. returns ENOSPC if ctx_out is too small.
10791344 ctx_size_out: u32,
10801345 ctx_in: u64,
......@@ -1127,26 +1392,35 @@ pub const BtfLoadAttr = extern struct {
11271392 btf_log_level: u32,
11281393};
11291394
1395/// struct used by Cmd.task_fd_query
11301396pub const TaskFdQueryAttr = extern struct {
11311397 /// input: pid
11321398 pid: pid_t,
1399
11331400 /// input: fd
11341401 fd: fd_t,
1402
11351403 /// input: flags
11361404 flags: u32,
1405
11371406 /// input/output: buf len
11381407 buf_len: u32,
1408
11391409 /// input/output:
11401410 /// tp_name for tracepoint
11411411 /// symbol for kprobe
11421412 /// filename for uprobe
11431413 buf: u64,
1414
11441415 /// output: prod_id
11451416 prog_id: u32,
1417
11461418 /// output: BPF_FD_TYPE
11471419 fd_type: u32,
1420
11481421 /// output: probe_offset
11491422 probe_offset: u64,
1423
11501424 /// output: probe_addr
11511425 probe_addr: u64,
11521426};
......@@ -1155,9 +1429,11 @@ pub const TaskFdQueryAttr = extern struct {
11551429pub const LinkCreateAttr = extern struct {
11561430 /// eBPF program to attach
11571431 prog_fd: fd_t,
1432
11581433 /// object to attach to
11591434 target_fd: fd_t,
11601435 attach_type: u32,
1436
11611437 /// extra flags
11621438 flags: u32,
11631439};
......@@ -1165,10 +1441,13 @@ pub const LinkCreateAttr = extern struct {
11651441/// struct used by Cmd.link_update command
11661442pub const LinkUpdateAttr = extern struct {
11671443 link_fd: fd_t,
1444
11681445 /// new program to update link with
11691446 new_prog_fd: fd_t,
1447
11701448 /// extra flags
11711449 flags: u32,
1450
11721451 /// expected link's program fd, it is specified only if BPF_F_REPLACE is
11731452 /// set in flags
11741453 old_prog_fd: fd_t,
......@@ -1185,6 +1464,7 @@ pub const IterCreateAttr = extern struct {
11851464 flags: u32,
11861465};
11871466
1467/// Mega struct that is passed to the bpf() syscall
11881468pub const Attr = extern union {
11891469 map_create: MapCreateAttr,
11901470 map_elem: MapElemAttr,