1use ebpf::{
6 CallingContext, CbpfConfig, CbpfLenInstruction, FieldDescriptor, FieldType, FunctionSignature,
7 MapSchema, MemoryId, MemoryParameterSize, StructDescriptor, Type,
8};
9use linux_uapi::{
10 __sk_buff, bpf_attach_type_BPF_CGROUP_DEVICE, bpf_attach_type_BPF_CGROUP_GETSOCKOPT,
11 bpf_attach_type_BPF_CGROUP_INET_EGRESS, bpf_attach_type_BPF_CGROUP_INET_INGRESS,
12 bpf_attach_type_BPF_CGROUP_INET_SOCK_CREATE, bpf_attach_type_BPF_CGROUP_INET_SOCK_RELEASE,
13 bpf_attach_type_BPF_CGROUP_INET4_BIND, bpf_attach_type_BPF_CGROUP_INET4_CONNECT,
14 bpf_attach_type_BPF_CGROUP_INET4_GETPEERNAME, bpf_attach_type_BPF_CGROUP_INET4_GETSOCKNAME,
15 bpf_attach_type_BPF_CGROUP_INET4_POST_BIND, bpf_attach_type_BPF_CGROUP_INET6_BIND,
16 bpf_attach_type_BPF_CGROUP_INET6_CONNECT, bpf_attach_type_BPF_CGROUP_INET6_GETPEERNAME,
17 bpf_attach_type_BPF_CGROUP_INET6_GETSOCKNAME, bpf_attach_type_BPF_CGROUP_INET6_POST_BIND,
18 bpf_attach_type_BPF_CGROUP_SETSOCKOPT, bpf_attach_type_BPF_CGROUP_SOCK_OPS,
19 bpf_attach_type_BPF_CGROUP_SYSCTL, bpf_attach_type_BPF_CGROUP_UDP4_RECVMSG,
20 bpf_attach_type_BPF_CGROUP_UDP4_SENDMSG, bpf_attach_type_BPF_CGROUP_UDP6_RECVMSG,
21 bpf_attach_type_BPF_CGROUP_UDP6_SENDMSG, bpf_attach_type_BPF_CGROUP_UNIX_CONNECT,
22 bpf_attach_type_BPF_CGROUP_UNIX_GETPEERNAME, bpf_attach_type_BPF_CGROUP_UNIX_GETSOCKNAME,
23 bpf_attach_type_BPF_CGROUP_UNIX_RECVMSG, bpf_attach_type_BPF_CGROUP_UNIX_SENDMSG,
24 bpf_attach_type_BPF_FLOW_DISSECTOR, bpf_attach_type_BPF_LIRC_MODE2,
25 bpf_attach_type_BPF_LSM_CGROUP, bpf_attach_type_BPF_LSM_MAC, bpf_attach_type_BPF_MODIFY_RETURN,
26 bpf_attach_type_BPF_NETFILTER, bpf_attach_type_BPF_NETKIT_PEER,
27 bpf_attach_type_BPF_NETKIT_PRIMARY, bpf_attach_type_BPF_PERF_EVENT,
28 bpf_attach_type_BPF_SK_LOOKUP, bpf_attach_type_BPF_SK_MSG_VERDICT,
29 bpf_attach_type_BPF_SK_REUSEPORT_SELECT, bpf_attach_type_BPF_SK_REUSEPORT_SELECT_OR_MIGRATE,
30 bpf_attach_type_BPF_SK_SKB_STREAM_PARSER, bpf_attach_type_BPF_SK_SKB_STREAM_VERDICT,
31 bpf_attach_type_BPF_SK_SKB_VERDICT, bpf_attach_type_BPF_STRUCT_OPS,
32 bpf_attach_type_BPF_TCX_EGRESS, bpf_attach_type_BPF_TCX_INGRESS,
33 bpf_attach_type_BPF_TRACE_FENTRY, bpf_attach_type_BPF_TRACE_FEXIT,
34 bpf_attach_type_BPF_TRACE_ITER, bpf_attach_type_BPF_TRACE_KPROBE_MULTI,
35 bpf_attach_type_BPF_TRACE_KPROBE_SESSION, bpf_attach_type_BPF_TRACE_RAW_TP,
36 bpf_attach_type_BPF_TRACE_UPROBE_MULTI, bpf_attach_type_BPF_XDP,
37 bpf_attach_type_BPF_XDP_CPUMAP, bpf_attach_type_BPF_XDP_DEVMAP,
38 bpf_func_id_BPF_FUNC_csum_update, bpf_func_id_BPF_FUNC_get_current_pid_tgid,
39 bpf_func_id_BPF_FUNC_get_current_uid_gid, bpf_func_id_BPF_FUNC_get_smp_processor_id,
40 bpf_func_id_BPF_FUNC_get_socket_cookie, bpf_func_id_BPF_FUNC_get_socket_uid,
41 bpf_func_id_BPF_FUNC_ktime_get_boot_ns, bpf_func_id_BPF_FUNC_ktime_get_coarse_ns,
42 bpf_func_id_BPF_FUNC_ktime_get_ns, bpf_func_id_BPF_FUNC_l3_csum_replace,
43 bpf_func_id_BPF_FUNC_l4_csum_replace, bpf_func_id_BPF_FUNC_map_delete_elem,
44 bpf_func_id_BPF_FUNC_map_lookup_elem, bpf_func_id_BPF_FUNC_map_update_elem,
45 bpf_func_id_BPF_FUNC_probe_read_str, bpf_func_id_BPF_FUNC_probe_read_user,
46 bpf_func_id_BPF_FUNC_probe_read_user_str, bpf_func_id_BPF_FUNC_redirect,
47 bpf_func_id_BPF_FUNC_ringbuf_discard, bpf_func_id_BPF_FUNC_ringbuf_reserve,
48 bpf_func_id_BPF_FUNC_ringbuf_submit, bpf_func_id_BPF_FUNC_sk_fullsock,
49 bpf_func_id_BPF_FUNC_sk_storage_get, bpf_func_id_BPF_FUNC_skb_adjust_room,
50 bpf_func_id_BPF_FUNC_skb_change_head, bpf_func_id_BPF_FUNC_skb_change_proto,
51 bpf_func_id_BPF_FUNC_skb_load_bytes_relative, bpf_func_id_BPF_FUNC_skb_pull_data,
52 bpf_func_id_BPF_FUNC_skb_store_bytes, bpf_func_id_BPF_FUNC_trace_printk,
53 bpf_prog_type_BPF_PROG_TYPE_CGROUP_DEVICE, bpf_prog_type_BPF_PROG_TYPE_CGROUP_SKB,
54 bpf_prog_type_BPF_PROG_TYPE_CGROUP_SOCK, bpf_prog_type_BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
55 bpf_prog_type_BPF_PROG_TYPE_CGROUP_SOCKOPT, bpf_prog_type_BPF_PROG_TYPE_CGROUP_SYSCTL,
56 bpf_prog_type_BPF_PROG_TYPE_EXT, bpf_prog_type_BPF_PROG_TYPE_FLOW_DISSECTOR,
57 bpf_prog_type_BPF_PROG_TYPE_KPROBE, bpf_prog_type_BPF_PROG_TYPE_LIRC_MODE2,
58 bpf_prog_type_BPF_PROG_TYPE_LSM, bpf_prog_type_BPF_PROG_TYPE_LWT_IN,
59 bpf_prog_type_BPF_PROG_TYPE_LWT_OUT, bpf_prog_type_BPF_PROG_TYPE_LWT_SEG6LOCAL,
60 bpf_prog_type_BPF_PROG_TYPE_LWT_XMIT, bpf_prog_type_BPF_PROG_TYPE_NETFILTER,
61 bpf_prog_type_BPF_PROG_TYPE_PERF_EVENT, bpf_prog_type_BPF_PROG_TYPE_RAW_TRACEPOINT,
62 bpf_prog_type_BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, bpf_prog_type_BPF_PROG_TYPE_SCHED_ACT,
63 bpf_prog_type_BPF_PROG_TYPE_SCHED_CLS, bpf_prog_type_BPF_PROG_TYPE_SK_LOOKUP,
64 bpf_prog_type_BPF_PROG_TYPE_SK_MSG, bpf_prog_type_BPF_PROG_TYPE_SK_REUSEPORT,
65 bpf_prog_type_BPF_PROG_TYPE_SK_SKB, bpf_prog_type_BPF_PROG_TYPE_SOCK_OPS,
66 bpf_prog_type_BPF_PROG_TYPE_SOCKET_FILTER, bpf_prog_type_BPF_PROG_TYPE_STRUCT_OPS,
67 bpf_prog_type_BPF_PROG_TYPE_SYSCALL, bpf_prog_type_BPF_PROG_TYPE_TRACEPOINT,
68 bpf_prog_type_BPF_PROG_TYPE_TRACING, bpf_prog_type_BPF_PROG_TYPE_UNSPEC,
69 bpf_prog_type_BPF_PROG_TYPE_XDP, bpf_sock, bpf_sock_addr, bpf_sockopt, bpf_user_pt_regs_t,
70 fuse_bpf_arg, fuse_bpf_args, fuse_entry_bpf_out, fuse_entry_out, seccomp_data, xdp_md,
71};
72use std::collections::HashMap;
73use std::mem::{offset_of, size_of};
74use std::sync::{Arc, LazyLock};
75use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
76
77pub const BPF_PROG_TYPE_FUSE: u32 = 0x77777777;
78
79pub struct EbpfHelperDefinition {
80 pub index: u32,
81 pub name: &'static str,
82 pub signature: FunctionSignature,
83}
84
85#[derive(Clone, Default, Debug)]
86pub struct BpfTypeFilter(Vec<ProgramType>);
87
88impl<T: IntoIterator<Item = ProgramType>> From<T> for BpfTypeFilter {
89 fn from(types: T) -> Self {
90 Self(types.into_iter().collect())
91 }
92}
93
94impl BpfTypeFilter {
95 pub fn accept(&self, program_type: ProgramType) -> bool {
96 self.0.is_empty() || self.0.iter().find(|v| **v == program_type).is_some()
97 }
98}
99
100static BPF_HELPERS_DEFINITIONS: LazyLock<Vec<(BpfTypeFilter, EbpfHelperDefinition)>> =
101 LazyLock::new(|| {
102 vec![
103 (
104 BpfTypeFilter::default(),
105 EbpfHelperDefinition {
106 index: bpf_func_id_BPF_FUNC_map_lookup_elem,
107 name: "map_lookup_elem",
108 signature: FunctionSignature {
109 args: vec![
110 Type::ConstPtrToMapParameter,
111 Type::MapKeyParameter { map_ptr_index: 0 },
112 ],
113 return_value: Type::NullOrParameter(Box::new(Type::MapValueParameter {
114 map_ptr_index: 0,
115 })),
116 invalidate_array_bounds: false,
117 },
118 },
119 ),
120 (
121 BpfTypeFilter::default(),
122 EbpfHelperDefinition {
123 index: bpf_func_id_BPF_FUNC_map_update_elem,
124 name: "map_update_elem",
125 signature: FunctionSignature {
126 args: vec![
127 Type::ConstPtrToMapParameter,
128 Type::MapKeyParameter { map_ptr_index: 0 },
129 Type::MapValueParameter { map_ptr_index: 0 },
130 Type::ScalarValueParameter,
131 ],
132 return_value: Type::UNKNOWN_SCALAR,
133 invalidate_array_bounds: false,
134 },
135 },
136 ),
137 (
138 BpfTypeFilter::default(),
139 EbpfHelperDefinition {
140 index: bpf_func_id_BPF_FUNC_map_delete_elem,
141 name: "map_delete_elem",
142 signature: FunctionSignature {
143 args: vec![
144 Type::ConstPtrToMapParameter,
145 Type::MapKeyParameter { map_ptr_index: 0 },
146 ],
147 return_value: Type::UNKNOWN_SCALAR,
148 invalidate_array_bounds: false,
149 },
150 },
151 ),
152 (
153 BpfTypeFilter::default(),
154 EbpfHelperDefinition {
155 index: bpf_func_id_BPF_FUNC_trace_printk,
156 name: "trace_printk",
157 signature: FunctionSignature {
158 args: vec![],
160 return_value: Type::UNKNOWN_SCALAR,
161 invalidate_array_bounds: false,
162 },
163 },
164 ),
165 (
166 BpfTypeFilter::default(),
167 EbpfHelperDefinition {
168 index: bpf_func_id_BPF_FUNC_ktime_get_ns,
169 name: "ktime_get_ns",
170 signature: FunctionSignature {
171 args: vec![],
172 return_value: Type::UNKNOWN_SCALAR,
173 invalidate_array_bounds: false,
174 },
175 },
176 ),
177 (
178 BpfTypeFilter::default(),
179 EbpfHelperDefinition {
180 index: bpf_func_id_BPF_FUNC_probe_read_user,
181 name: "probe_read_user",
182 signature: FunctionSignature {
183 args: vec![
184 Type::MemoryParameter {
185 size: MemoryParameterSize::Reference { index: 1 },
186 input: false,
187 output: true,
188 },
189 Type::ScalarValueParameter,
190 Type::AnyParameter,
191 ],
192 return_value: Type::UNKNOWN_SCALAR,
193 invalidate_array_bounds: false,
194 },
195 },
196 ),
197 (
198 BpfTypeFilter::default(),
199 EbpfHelperDefinition {
200 index: bpf_func_id_BPF_FUNC_probe_read_user_str,
201 name: "probe_read_user_str",
202 signature: FunctionSignature {
203 args: vec![
204 Type::MemoryParameter {
205 size: MemoryParameterSize::Reference { index: 1 },
206 input: false,
207 output: true,
208 },
209 Type::ScalarValueParameter,
210 Type::ScalarValueParameter,
211 ],
212 return_value: Type::UNKNOWN_SCALAR,
213 invalidate_array_bounds: false,
214 },
215 },
216 ),
217 (
218 vec![
219 ProgramType::CgroupSkb,
220 ProgramType::SchedAct,
221 ProgramType::SchedCls,
222 ProgramType::SocketFilter,
223 ]
224 .into(),
225 EbpfHelperDefinition {
226 index: bpf_func_id_BPF_FUNC_get_socket_uid,
227 name: "get_socket_uid",
228 signature: FunctionSignature {
229 args: vec![Type::StructParameter { id: SK_BUF_ID.clone() }],
230 return_value: Type::UNKNOWN_SCALAR,
231 invalidate_array_bounds: false,
232 },
233 },
234 ),
235 (
236 vec![
237 ProgramType::CgroupSock,
238 ProgramType::CgroupSockAddr,
239 ProgramType::CgroupSockopt,
240 ProgramType::Fuse,
241 ProgramType::Kprobe,
242 ProgramType::Tracepoint,
243 ]
244 .into(),
245 EbpfHelperDefinition {
246 index: bpf_func_id_BPF_FUNC_get_current_uid_gid,
247 name: "get_current_uid_gid",
248 signature: FunctionSignature {
249 args: vec![],
250 return_value: Type::UNKNOWN_SCALAR,
251 invalidate_array_bounds: false,
252 },
253 },
254 ),
255 (
256 vec![
257 ProgramType::CgroupSock,
258 ProgramType::CgroupSockAddr,
259 ProgramType::CgroupSockopt,
260 ProgramType::Fuse,
261 ProgramType::Kprobe,
262 ProgramType::Tracepoint,
263 ]
264 .into(),
265 EbpfHelperDefinition {
266 index: bpf_func_id_BPF_FUNC_get_current_pid_tgid,
267 name: "get_current_pid_tgid",
268 signature: FunctionSignature {
269 args: vec![],
270 return_value: Type::UNKNOWN_SCALAR,
271 invalidate_array_bounds: false,
272 },
273 },
274 ),
275 (
276 vec![ProgramType::SchedAct, ProgramType::SchedCls].into(),
277 EbpfHelperDefinition {
278 index: bpf_func_id_BPF_FUNC_skb_pull_data,
279 name: "skb_pull_data",
280 signature: FunctionSignature {
281 args: vec![
282 Type::StructParameter { id: SK_BUF_ID.clone() },
283 Type::ScalarValueParameter,
284 ],
285 return_value: Type::UNKNOWN_SCALAR,
286 invalidate_array_bounds: true,
287 },
288 },
289 ),
290 (
291 BpfTypeFilter::default(),
292 EbpfHelperDefinition {
293 index: bpf_func_id_BPF_FUNC_ringbuf_reserve,
294 name: "ringbuf_reserve",
295 signature: FunctionSignature {
296 args: vec![
297 Type::ConstPtrToMapParameter,
298 Type::ScalarValueParameter,
299 Type::ScalarValueParameter,
300 ],
301 return_value: Type::NullOrParameter(Box::new(Type::ReleasableParameter {
302 id: RING_BUFFER_RESERVATION.clone(),
303 inner: Box::new(Type::MemoryParameter {
304 size: MemoryParameterSize::Reference { index: 1 },
305 input: false,
306 output: false,
307 }),
308 })),
309 invalidate_array_bounds: false,
310 },
311 },
312 ),
313 (
314 BpfTypeFilter::default(),
315 EbpfHelperDefinition {
316 index: bpf_func_id_BPF_FUNC_ringbuf_submit,
317 name: "ringbuf_submit",
318 signature: FunctionSignature {
319 args: vec![
320 Type::ReleaseParameter { id: RING_BUFFER_RESERVATION.clone() },
321 Type::ScalarValueParameter,
322 ],
323 return_value: Type::default(),
324 invalidate_array_bounds: false,
325 },
326 },
327 ),
328 (
329 BpfTypeFilter::default(),
330 EbpfHelperDefinition {
331 index: bpf_func_id_BPF_FUNC_ringbuf_discard,
332 name: "ringbuf_discard",
333 signature: FunctionSignature {
334 args: vec![
335 Type::ReleaseParameter { id: RING_BUFFER_RESERVATION.clone() },
336 Type::ScalarValueParameter,
337 ],
338 return_value: Type::default(),
339 invalidate_array_bounds: false,
340 },
341 },
342 ),
343 (
344 vec![ProgramType::SchedAct, ProgramType::SchedCls].into(),
345 EbpfHelperDefinition {
346 index: bpf_func_id_BPF_FUNC_skb_change_proto,
347 name: "skb_change_proto",
348 signature: FunctionSignature {
349 args: vec![
350 Type::StructParameter { id: SK_BUF_ID.clone() },
351 Type::ScalarValueParameter,
352 Type::ScalarValueParameter,
353 ],
354 return_value: Type::UNKNOWN_SCALAR,
355 invalidate_array_bounds: true,
356 },
357 },
358 ),
359 (
360 vec![ProgramType::SchedAct, ProgramType::SchedCls].into(),
361 EbpfHelperDefinition {
362 index: bpf_func_id_BPF_FUNC_csum_update,
363 name: "csum_update",
364 signature: FunctionSignature {
365 args: vec![
366 Type::StructParameter { id: SK_BUF_ID.clone() },
367 Type::ScalarValueParameter,
368 ],
369 return_value: Type::UNKNOWN_SCALAR,
370 invalidate_array_bounds: false,
371 },
372 },
373 ),
374 (
375 vec![ProgramType::Kprobe, ProgramType::Tracepoint].into(),
376 EbpfHelperDefinition {
377 index: bpf_func_id_BPF_FUNC_probe_read_str,
378 name: "probe_read_str",
379 signature: FunctionSignature {
380 args: vec![],
382 return_value: Type::UNKNOWN_SCALAR,
383 invalidate_array_bounds: false,
384 },
385 },
386 ),
387 (
388 vec![
389 ProgramType::CgroupSkb,
390 ProgramType::SchedAct,
391 ProgramType::SchedCls,
392 ProgramType::SocketFilter,
393 ]
394 .into(),
395 EbpfHelperDefinition {
396 index: bpf_func_id_BPF_FUNC_get_socket_cookie,
397 name: "get_socket_cookie",
398 signature: FunctionSignature {
399 args: vec![Type::StructParameter { id: SK_BUF_ID.clone() }],
400 return_value: Type::UNKNOWN_SCALAR,
401 invalidate_array_bounds: false,
402 },
403 },
404 ),
405 (
406 vec![ProgramType::CgroupSock].into(),
407 EbpfHelperDefinition {
408 index: bpf_func_id_BPF_FUNC_get_socket_cookie,
409 name: "get_socket_cookie",
410 signature: FunctionSignature {
411 args: vec![Type::StructParameter { id: BPF_SOCK_ID.clone() }],
412 return_value: Type::UNKNOWN_SCALAR,
413 invalidate_array_bounds: false,
414 },
415 },
416 ),
417 (
418 vec![ProgramType::CgroupSockAddr].into(),
419 EbpfHelperDefinition {
420 index: bpf_func_id_BPF_FUNC_get_socket_cookie,
421 name: "get_socket_cookie",
422 signature: FunctionSignature {
423 args: vec![Type::StructParameter { id: BPF_SOCK_ADDR_ID.clone() }],
424 return_value: Type::UNKNOWN_SCALAR,
425 invalidate_array_bounds: false,
426 },
427 },
428 ),
429 (
430 vec![ProgramType::SchedAct, ProgramType::SchedCls].into(),
431 EbpfHelperDefinition {
432 index: bpf_func_id_BPF_FUNC_redirect,
433 name: "redirect",
434 signature: FunctionSignature {
435 args: vec![Type::ScalarValueParameter, Type::ScalarValueParameter],
436 return_value: Type::UNKNOWN_SCALAR,
437 invalidate_array_bounds: false,
438 },
439 },
440 ),
441 (
442 vec![ProgramType::SchedAct, ProgramType::SchedCls].into(),
443 EbpfHelperDefinition {
444 index: bpf_func_id_BPF_FUNC_skb_adjust_room,
445 name: "skb_adjust_room",
446 signature: FunctionSignature {
447 args: vec![
448 Type::StructParameter { id: SK_BUF_ID.clone() },
449 Type::ScalarValueParameter,
450 Type::ScalarValueParameter,
451 Type::ScalarValueParameter,
452 ],
453 return_value: Type::UNKNOWN_SCALAR,
454 invalidate_array_bounds: true,
455 },
456 },
457 ),
458 (
459 vec![ProgramType::SchedAct, ProgramType::SchedCls].into(),
460 EbpfHelperDefinition {
461 index: bpf_func_id_BPF_FUNC_l3_csum_replace,
462 name: "l3_csum_replace",
463 signature: FunctionSignature {
464 args: vec![
465 Type::StructParameter { id: SK_BUF_ID.clone() },
466 Type::ScalarValueParameter,
467 Type::ScalarValueParameter,
468 Type::ScalarValueParameter,
469 Type::ScalarValueParameter,
470 ],
471 return_value: Type::UNKNOWN_SCALAR,
472 invalidate_array_bounds: true,
473 },
474 },
475 ),
476 (
477 vec![ProgramType::SchedAct, ProgramType::SchedCls].into(),
478 EbpfHelperDefinition {
479 index: bpf_func_id_BPF_FUNC_l4_csum_replace,
480 name: "l4_csum_replace",
481 signature: FunctionSignature {
482 args: vec![
483 Type::StructParameter { id: SK_BUF_ID.clone() },
484 Type::ScalarValueParameter,
485 Type::ScalarValueParameter,
486 Type::ScalarValueParameter,
487 Type::ScalarValueParameter,
488 ],
489 return_value: Type::UNKNOWN_SCALAR,
490 invalidate_array_bounds: true,
491 },
492 },
493 ),
494 (
495 vec![ProgramType::SchedAct, ProgramType::SchedCls].into(),
496 EbpfHelperDefinition {
497 index: bpf_func_id_BPF_FUNC_skb_store_bytes,
498 name: "skb_store_bytes",
499 signature: FunctionSignature {
500 args: vec![
501 Type::StructParameter { id: SK_BUF_ID.clone() },
502 Type::ScalarValueParameter,
503 Type::MemoryParameter {
504 size: MemoryParameterSize::Reference { index: 3 },
505 input: true,
506 output: false,
507 },
508 Type::ScalarValueParameter,
509 Type::ScalarValueParameter,
510 ],
511 return_value: Type::UNKNOWN_SCALAR,
512 invalidate_array_bounds: true,
513 },
514 },
515 ),
516 (
517 vec![ProgramType::SchedAct, ProgramType::SchedCls].into(),
518 EbpfHelperDefinition {
519 index: bpf_func_id_BPF_FUNC_skb_change_head,
520 name: "skb_change_head",
521 signature: FunctionSignature {
522 args: vec![
523 Type::StructParameter { id: SK_BUF_ID.clone() },
524 Type::ScalarValueParameter,
525 Type::ScalarValueParameter,
526 ],
527 return_value: Type::UNKNOWN_SCALAR,
528 invalidate_array_bounds: true,
529 },
530 },
531 ),
532 (
533 vec![
534 ProgramType::CgroupSkb,
535 ProgramType::SchedAct,
536 ProgramType::SchedCls,
537 ProgramType::SocketFilter,
538 ]
539 .into(),
540 EbpfHelperDefinition {
541 index: bpf_func_id_BPF_FUNC_skb_load_bytes_relative,
542 name: "skb_load_bytes_relative",
543 signature: FunctionSignature {
544 args: vec![
545 Type::StructParameter { id: SK_BUF_ID.clone() },
546 Type::ScalarValueParameter,
547 Type::MemoryParameter {
548 size: MemoryParameterSize::Reference { index: 3 },
549 input: false,
550 output: true,
551 },
552 Type::ScalarValueParameter,
553 Type::ScalarValueParameter,
554 ],
555 return_value: Type::UNKNOWN_SCALAR,
556 invalidate_array_bounds: false,
557 },
558 },
559 ),
560 (
561 BpfTypeFilter::default(),
562 EbpfHelperDefinition {
563 index: bpf_func_id_BPF_FUNC_ktime_get_boot_ns,
564 name: "ktime_get_boot_ns",
565 signature: FunctionSignature {
566 args: vec![],
567 return_value: Type::UNKNOWN_SCALAR,
568 invalidate_array_bounds: false,
569 },
570 },
571 ),
572 (
573 BpfTypeFilter::default(),
574 EbpfHelperDefinition {
575 index: bpf_func_id_BPF_FUNC_ktime_get_coarse_ns,
576 name: "ktime_get_coarse_ns",
577 signature: FunctionSignature {
578 args: vec![],
579 return_value: Type::UNKNOWN_SCALAR,
580 invalidate_array_bounds: false,
581 },
582 },
583 ),
584 (
585 vec![ProgramType::CgroupSock].into(),
586 EbpfHelperDefinition {
587 index: bpf_func_id_BPF_FUNC_sk_storage_get,
588 name: "sk_storage_get",
589 signature: FunctionSignature {
590 args: vec![
591 Type::ConstPtrToMapParameter,
592 Type::StructParameter { id: BPF_SOCK_ID.clone() },
593 Type::NullOrParameter(Box::new(Type::MapValueParameter {
594 map_ptr_index: 0,
595 })),
596 Type::ScalarValueParameter,
597 ],
598 return_value: Type::NullOrParameter(Box::new(Type::MapValueParameter {
599 map_ptr_index: 0,
600 })),
601 invalidate_array_bounds: false,
602 },
603 },
604 ),
605 (
606 BpfTypeFilter::default(),
607 EbpfHelperDefinition {
608 index: bpf_func_id_BPF_FUNC_get_smp_processor_id,
609 name: "get_smp_processor_id",
610 signature: FunctionSignature {
611 args: vec![],
612 return_value: Type::UNKNOWN_SCALAR,
613 invalidate_array_bounds: false,
614 },
615 },
616 ),
617 (
618 vec![ProgramType::CgroupSkb, ProgramType::SchedAct, ProgramType::SchedCls].into(),
619 EbpfHelperDefinition {
620 index: bpf_func_id_BPF_FUNC_sk_fullsock,
621 name: "sk_fullsock",
622 signature: FunctionSignature {
623 args: vec![Type::StructParameter { id: BPF_SOCK_ID.clone() }],
624 return_value: Type::NullOrParameter(Box::new(ptr_to_mem_type::<bpf_sock>(
625 BPF_SOCK_ID.clone(),
626 ))),
627 invalidate_array_bounds: false,
628 },
629 },
630 ),
631 ]
632 });
633
634fn scalar_field(offset: usize, size: usize) -> FieldDescriptor {
635 FieldDescriptor { offset, field_type: FieldType::Scalar { size } }
636}
637
638fn scalar_range(offset: usize, end_offset: usize) -> FieldDescriptor {
639 FieldDescriptor { offset, field_type: FieldType::Scalar { size: end_offset - offset } }
640}
641
642fn scalar_mut_range(offset: usize, end_offset: usize) -> FieldDescriptor {
643 FieldDescriptor { offset, field_type: FieldType::MutableScalar { size: end_offset - offset } }
644}
645
646fn scalar_u32_field(offset: usize) -> FieldDescriptor {
647 FieldDescriptor { offset, field_type: FieldType::Scalar { size: std::mem::size_of::<u32>() } }
648}
649
650fn scalar_u32_mut_field(offset: usize) -> FieldDescriptor {
651 FieldDescriptor {
652 offset,
653 field_type: FieldType::MutableScalar { size: std::mem::size_of::<u32>() },
654 }
655}
656
657fn scalar_u64_field(offset: usize) -> FieldDescriptor {
658 FieldDescriptor { offset, field_type: FieldType::Scalar { size: std::mem::size_of::<u64>() } }
659}
660
661fn array_start_field(offset: usize, id: MemoryId) -> FieldDescriptor {
662 FieldDescriptor { offset, field_type: FieldType::PtrToArray { id, is_32_bit: false } }
663}
664
665fn array_end_field(offset: usize, id: MemoryId) -> FieldDescriptor {
666 FieldDescriptor { offset, field_type: FieldType::PtrToEndArray { id, is_32_bit: false } }
667}
668
669fn array_start_32_field(offset: usize, id: MemoryId) -> FieldDescriptor {
670 FieldDescriptor { offset, field_type: FieldType::PtrToArray { id, is_32_bit: true } }
671}
672
673fn array_end_32_field(offset: usize, id: MemoryId) -> FieldDescriptor {
674 FieldDescriptor { offset, field_type: FieldType::PtrToEndArray { id, is_32_bit: true } }
675}
676
677fn ptr_to_mem_field<T: IntoBytes>(offset: usize, id: MemoryId) -> FieldDescriptor {
678 FieldDescriptor {
679 offset,
680 field_type: FieldType::PtrToMemory {
681 id,
682 buffer_size: std::mem::size_of::<T>(),
683 is_32_bit: false,
684 },
685 }
686}
687
688fn nullable_ptr_to_mem_field<T: IntoBytes>(offset: usize, id: MemoryId) -> FieldDescriptor {
689 FieldDescriptor {
690 offset,
691 field_type: FieldType::NullablePtrToMemory {
692 is_32_bit: false,
693 id,
694 buffer_size: std::mem::size_of::<T>(),
695 },
696 }
697}
698
699fn ptr_to_struct_type(id: MemoryId, fields: Vec<FieldDescriptor>) -> Type {
700 Type::PtrToStruct { id, offset: 0.into(), descriptor: Arc::new(StructDescriptor { fields }) }
701}
702
703fn ptr_to_mem_type<T: IntoBytes>(id: MemoryId) -> Type {
704 Type::PtrToMemory { id, offset: 0.into(), buffer_size: std::mem::size_of::<T>() as u64 }
705}
706
707static RING_BUFFER_RESERVATION: LazyLock<MemoryId> = LazyLock::new(MemoryId::new);
708
709pub static SK_BUF_ID: LazyLock<MemoryId> = LazyLock::new(MemoryId::new);
710
711pub static SOCKET_FILTER_SK_BUF_TYPE: LazyLock<Type> = LazyLock::new(|| {
713 ptr_to_struct_type(
714 SK_BUF_ID.clone(),
715 vec![
716 scalar_range(0, offset_of!(__sk_buff, cb)),
718 scalar_mut_range(offset_of!(__sk_buff, cb), offset_of!(__sk_buff, hash)),
720 scalar_u32_field(offset_of!(__sk_buff, hash)),
721 scalar_u32_field(offset_of!(__sk_buff, napi_id)),
722 scalar_u32_field(offset_of!(__sk_buff, tstamp)),
723 scalar_u32_field(offset_of!(__sk_buff, gso_segs)),
724 scalar_u32_field(offset_of!(__sk_buff, gso_size)),
725 ],
726 )
727});
728pub static SOCKET_FILTER_ARGS: LazyLock<Vec<Type>> =
729 LazyLock::new(|| vec![SOCKET_FILTER_SK_BUF_TYPE.clone()]);
730
731pub static SCHED_ARG_TYPE: LazyLock<Type> = LazyLock::new(|| {
734 let data_id = MemoryId::new();
735 ptr_to_struct_type(
736 SK_BUF_ID.clone(),
737 vec![
738 scalar_range(0, offset_of!(__sk_buff, mark)),
741 scalar_u32_mut_field(offset_of!(__sk_buff, mark)),
742 scalar_range(offset_of!(__sk_buff, queue_mapping), offset_of!(__sk_buff, cb)),
743 scalar_mut_range(offset_of!(__sk_buff, cb), offset_of!(__sk_buff, hash)),
745 scalar_u32_field(offset_of!(__sk_buff, hash)),
746 scalar_u32_field(offset_of!(__sk_buff, tc_classid)),
747 array_start_32_field(offset_of!(__sk_buff, data), data_id.clone()),
748 array_end_32_field(offset_of!(__sk_buff, data_end), data_id),
749 scalar_u32_field(offset_of!(__sk_buff, napi_id)),
750 scalar_u32_field(offset_of!(__sk_buff, data_meta)),
751 scalar_range(offset_of!(__sk_buff, tstamp), size_of::<__sk_buff>()),
752 ],
753 )
754});
755pub static SCHED_ARGS: LazyLock<Vec<Type>> = LazyLock::new(|| vec![SCHED_ARG_TYPE.clone()]);
756
757pub static CGROUP_SKB_SK_BUF_TYPE: LazyLock<Type> = LazyLock::new(|| {
759 let data_id = MemoryId::new();
760 assert!(offset_of!(__sk_buff, __bindgen_anon_2) == 168);
761 ptr_to_struct_type(
762 SK_BUF_ID.clone(),
763 vec![
764 scalar_range(0, offset_of!(__sk_buff, mark)),
767 scalar_u32_mut_field(offset_of!(__sk_buff, mark)),
768 scalar_range(offset_of!(__sk_buff, queue_mapping), offset_of!(__sk_buff, cb)),
769 scalar_mut_range(offset_of!(__sk_buff, cb), offset_of!(__sk_buff, hash)),
771 scalar_u32_field(offset_of!(__sk_buff, hash)),
772 array_start_32_field(offset_of!(__sk_buff, data), data_id.clone()),
773 array_end_32_field(offset_of!(__sk_buff, data_end), data_id),
774 scalar_range(offset_of!(__sk_buff, napi_id), offset_of!(__sk_buff, data_meta)),
775 scalar_u64_field(offset_of!(__sk_buff, tstamp)),
776 scalar_u32_field(offset_of!(__sk_buff, gso_segs)),
777 nullable_ptr_to_mem_field::<bpf_sock>(
779 offset_of!(__sk_buff, __bindgen_anon_2),
780 BPF_SOCK_ID.clone(),
781 ),
782 scalar_u32_field(offset_of!(__sk_buff, gso_size)),
783 scalar_u64_field(offset_of!(__sk_buff, hwtstamp)),
784 ],
785 )
786});
787pub static CGROUP_SKB_ARGS: LazyLock<Vec<Type>> =
788 LazyLock::new(|| vec![CGROUP_SKB_SK_BUF_TYPE.clone()]);
789
790static XDP_MD_ID: LazyLock<MemoryId> = LazyLock::new(MemoryId::new);
791static XDP_MD_TYPE: LazyLock<Type> = LazyLock::new(|| {
792 let data_id = MemoryId::new();
793
794 ptr_to_struct_type(
795 XDP_MD_ID.clone(),
796 vec![
797 array_start_32_field(offset_of!(xdp_md, data), data_id.clone()),
798 array_end_32_field(offset_of!(xdp_md, data_end), data_id),
799 {
801 let data_meta_offset = offset_of!(xdp_md, data_meta);
802 scalar_field(data_meta_offset, std::mem::size_of::<xdp_md>() - data_meta_offset)
803 },
804 ],
805 )
806});
807static XDP_MD_ARGS: LazyLock<Vec<Type>> = LazyLock::new(|| vec![XDP_MD_TYPE.clone()]);
808
809pub static BPF_USER_PT_REGS_T_ID: LazyLock<MemoryId> = LazyLock::new(MemoryId::new);
810pub static BPF_USER_PT_REGS_T_ARGS: LazyLock<Vec<Type>> =
811 LazyLock::new(|| vec![ptr_to_mem_type::<bpf_user_pt_regs_t>(BPF_USER_PT_REGS_T_ID.clone())]);
812
813pub static BPF_SOCK_ID: LazyLock<MemoryId> = LazyLock::new(MemoryId::new);
814pub static BPF_SOCK_TYPE: LazyLock<Type> =
815 LazyLock::new(|| ptr_to_mem_type::<bpf_sock>(BPF_SOCK_ID.clone()));
816pub static BPF_SOCK_ARGS: LazyLock<Vec<Type>> = LazyLock::new(|| vec![BPF_SOCK_TYPE.clone()]);
817
818pub static BPF_SOCKOPT_ID: LazyLock<MemoryId> = LazyLock::new(MemoryId::new);
819pub static BPF_SOCKOPT_TYPE: LazyLock<Type> = LazyLock::new(|| {
820 let optval_id = MemoryId::new();
821 ptr_to_struct_type(
822 BPF_SOCKOPT_ID.clone(),
823 vec![
824 ptr_to_mem_field::<bpf_sock>(
826 offset_of!(bpf_sockopt, __bindgen_anon_1),
827 BPF_SOCK_ID.clone(),
828 ),
829 array_start_field(offset_of!(bpf_sockopt, __bindgen_anon_2), optval_id.clone()),
831 array_end_field(offset_of!(bpf_sockopt, __bindgen_anon_3), optval_id),
833 scalar_u32_field(offset_of!(bpf_sockopt, level)),
834 scalar_u32_mut_field(offset_of!(bpf_sockopt, optname)),
835 scalar_u32_mut_field(offset_of!(bpf_sockopt, optlen)),
836 scalar_u32_mut_field(offset_of!(bpf_sockopt, retval)),
837 ],
838 )
839});
840pub static BPF_SOCKOPT_ARGS: LazyLock<Vec<Type>> = LazyLock::new(|| vec![BPF_SOCKOPT_TYPE.clone()]);
841
842pub static BPF_SOCK_ADDR_ID: LazyLock<MemoryId> = LazyLock::new(MemoryId::new);
851pub static BPF_SOCK_ADDR_TYPE: LazyLock<Type> = LazyLock::new(|| {
852 ptr_to_struct_type(
853 BPF_SOCK_ADDR_ID.clone(),
854 vec![
855 scalar_u32_field(offset_of!(bpf_sock_addr, user_family)),
856 scalar_u32_field(offset_of!(bpf_sock_addr, user_ip4)),
857 scalar_field(offset_of!(bpf_sock_addr, user_ip6), 16),
858 scalar_u32_field(offset_of!(bpf_sock_addr, user_port)),
859 scalar_u32_field(offset_of!(bpf_sock_addr, family)),
860 scalar_u32_field(offset_of!(bpf_sock_addr, type_)),
861 scalar_u32_field(offset_of!(bpf_sock_addr, protocol)),
862 scalar_u32_field(offset_of!(bpf_sock_addr, msg_src_ip4)),
863 scalar_field(offset_of!(bpf_sock_addr, msg_src_ip6), 16),
864 ],
865 )
866});
867
868pub static BPF_SOCK_ADDR_INET4_TYPE: LazyLock<Type> = LazyLock::new(|| {
869 ptr_to_struct_type(
870 BPF_SOCK_ADDR_ID.clone(),
871 vec![
872 scalar_u32_field(offset_of!(bpf_sock_addr, user_family)),
873 scalar_u32_field(offset_of!(bpf_sock_addr, user_ip4)),
874 scalar_u32_field(offset_of!(bpf_sock_addr, user_port)),
875 scalar_u32_field(offset_of!(bpf_sock_addr, family)),
876 scalar_u32_field(offset_of!(bpf_sock_addr, type_)),
877 scalar_u32_field(offset_of!(bpf_sock_addr, protocol)),
878 ],
879 )
880});
881pub static BPF_SOCK_ADDR_INET4_ARGS: LazyLock<Vec<Type>> =
882 LazyLock::new(|| vec![BPF_SOCK_ADDR_INET4_TYPE.clone()]);
883
884pub static BPF_SOCK_ADDR_INET6_TYPE: LazyLock<Type> = LazyLock::new(|| {
885 ptr_to_struct_type(
886 BPF_SOCK_ADDR_ID.clone(),
887 vec![
888 scalar_u32_field(offset_of!(bpf_sock_addr, user_family)),
889 scalar_field(offset_of!(bpf_sock_addr, user_ip6), 16),
890 scalar_u32_field(offset_of!(bpf_sock_addr, user_port)),
891 scalar_u32_field(offset_of!(bpf_sock_addr, family)),
892 scalar_u32_field(offset_of!(bpf_sock_addr, type_)),
893 scalar_u32_field(offset_of!(bpf_sock_addr, protocol)),
894 ],
895 )
896});
897pub static BPF_SOCK_ADDR_INET6_ARGS: LazyLock<Vec<Type>> =
898 LazyLock::new(|| vec![BPF_SOCK_ADDR_INET6_TYPE.clone()]);
899
900static BPF_FUSE_ID: LazyLock<MemoryId> = LazyLock::new(MemoryId::new);
901static BPF_FUSE_TYPE: LazyLock<Type> = LazyLock::new(|| {
902 ptr_to_struct_type(
903 BPF_FUSE_ID.clone(),
904 vec![
905 scalar_field(0, offset_of!(fuse_bpf_args, out_args)),
906 ptr_to_mem_field::<fuse_entry_out>(
907 offset_of!(fuse_bpf_args, out_args) + offset_of!(fuse_bpf_arg, value),
908 MemoryId::new(),
909 ),
910 ptr_to_mem_field::<fuse_entry_bpf_out>(
911 offset_of!(fuse_bpf_args, out_args)
912 + std::mem::size_of::<fuse_bpf_arg>()
913 + offset_of!(fuse_bpf_arg, value),
914 MemoryId::new(),
915 ),
916 ],
917 )
918});
919static BPF_FUSE_ARGS: LazyLock<Vec<Type>> = LazyLock::new(|| vec![BPF_FUSE_TYPE.clone()]);
920
921#[repr(C)]
922#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
923struct TraceEntry {
924 type_: u16,
925 flags: u8,
926 preemp_count: u8,
927 pid: u32,
928}
929
930#[repr(C)]
931#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
932struct TraceEvent {
933 trace_entry: TraceEntry,
934 id: u64,
935 args: [u64; 16],
939}
940
941#[repr(C)]
942#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
943struct RawTraceEvent {
944 args: [u64; 2],
948}
949
950static BPF_TRACEPOINT_ID: LazyLock<MemoryId> = LazyLock::new(MemoryId::new);
951static BPF_TRACEPOINT_ARGS: LazyLock<Vec<Type>> =
952 LazyLock::new(|| vec![ptr_to_mem_type::<TraceEvent>(BPF_TRACEPOINT_ID.clone())]);
953
954static BPF_RAW_TRACEPOINT_ID: LazyLock<MemoryId> = LazyLock::new(MemoryId::new);
955static BPF_RAW_TRACEPOINT_ARGS: LazyLock<Vec<Type>> =
956 LazyLock::new(|| vec![ptr_to_mem_type::<RawTraceEvent>(BPF_RAW_TRACEPOINT_ID.clone())]);
957
958#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
960pub enum ProgramType {
961 CgroupDevice,
962 CgroupSkb,
963 CgroupSock,
964 CgroupSockAddr,
965 CgroupSockopt,
966 CgroupSysctl,
967 Ext,
968 FlowDissector,
969 Kprobe,
970 LircMode2,
971 Lsm,
972 LwtIn,
973 LwtOut,
974 LwtSeg6Local,
975 LwtXmit,
976 Netfilter,
977 PerfEvent,
978 RawTracepoint,
979 RawTracepointWritable,
980 SchedAct,
981 SchedCls,
982 SkLookup,
983 SkMsg,
984 SkReuseport,
985 SkSkb,
986 SocketFilter,
987 SockOps,
988 StructOps,
989 Syscall,
990 Tracepoint,
991 Tracing,
992 Unspec,
993 Xdp,
994 Fuse,
996}
997
998#[derive(thiserror::Error, Debug, PartialEq, Eq)]
999pub enum EbpfApiError {
1000 #[error("Invalid program type: 0x{0:x}")]
1001 InvalidProgramType(u32),
1002
1003 #[error("Unsupported program type: {0:?}")]
1004 UnsupportedProgramType(ProgramType),
1005
1006 #[error("Invalid expected_attach_type: 0x{0:?}")]
1007 InvalidExpectedAttachType(AttachType),
1008}
1009
1010impl TryFrom<u32> for ProgramType {
1011 type Error = EbpfApiError;
1012
1013 fn try_from(program_type: u32) -> Result<Self, Self::Error> {
1014 match program_type {
1015 #![allow(non_upper_case_globals)]
1016 bpf_prog_type_BPF_PROG_TYPE_CGROUP_DEVICE => Ok(Self::CgroupDevice),
1017 bpf_prog_type_BPF_PROG_TYPE_CGROUP_SKB => Ok(Self::CgroupSkb),
1018 bpf_prog_type_BPF_PROG_TYPE_CGROUP_SOCK => Ok(Self::CgroupSock),
1019 bpf_prog_type_BPF_PROG_TYPE_CGROUP_SOCK_ADDR => Ok(Self::CgroupSockAddr),
1020 bpf_prog_type_BPF_PROG_TYPE_CGROUP_SOCKOPT => Ok(Self::CgroupSockopt),
1021 bpf_prog_type_BPF_PROG_TYPE_CGROUP_SYSCTL => Ok(Self::CgroupSysctl),
1022 bpf_prog_type_BPF_PROG_TYPE_EXT => Ok(Self::Ext),
1023 bpf_prog_type_BPF_PROG_TYPE_FLOW_DISSECTOR => Ok(Self::FlowDissector),
1024 bpf_prog_type_BPF_PROG_TYPE_KPROBE => Ok(Self::Kprobe),
1025 bpf_prog_type_BPF_PROG_TYPE_LIRC_MODE2 => Ok(Self::LircMode2),
1026 bpf_prog_type_BPF_PROG_TYPE_LSM => Ok(Self::Lsm),
1027 bpf_prog_type_BPF_PROG_TYPE_LWT_IN => Ok(Self::LwtIn),
1028 bpf_prog_type_BPF_PROG_TYPE_LWT_OUT => Ok(Self::LwtOut),
1029 bpf_prog_type_BPF_PROG_TYPE_LWT_SEG6LOCAL => Ok(Self::LwtSeg6Local),
1030 bpf_prog_type_BPF_PROG_TYPE_LWT_XMIT => Ok(Self::LwtXmit),
1031 bpf_prog_type_BPF_PROG_TYPE_NETFILTER => Ok(Self::Netfilter),
1032 bpf_prog_type_BPF_PROG_TYPE_PERF_EVENT => Ok(Self::PerfEvent),
1033 bpf_prog_type_BPF_PROG_TYPE_RAW_TRACEPOINT => Ok(Self::RawTracepoint),
1034 bpf_prog_type_BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE => Ok(Self::RawTracepointWritable),
1035 bpf_prog_type_BPF_PROG_TYPE_SCHED_ACT => Ok(Self::SchedAct),
1036 bpf_prog_type_BPF_PROG_TYPE_SCHED_CLS => Ok(Self::SchedCls),
1037 bpf_prog_type_BPF_PROG_TYPE_SK_LOOKUP => Ok(Self::SkLookup),
1038 bpf_prog_type_BPF_PROG_TYPE_SK_MSG => Ok(Self::SkMsg),
1039 bpf_prog_type_BPF_PROG_TYPE_SK_REUSEPORT => Ok(Self::SkReuseport),
1040 bpf_prog_type_BPF_PROG_TYPE_SK_SKB => Ok(Self::SkSkb),
1041 bpf_prog_type_BPF_PROG_TYPE_SOCK_OPS => Ok(Self::SockOps),
1042 bpf_prog_type_BPF_PROG_TYPE_SOCKET_FILTER => Ok(Self::SocketFilter),
1043 bpf_prog_type_BPF_PROG_TYPE_STRUCT_OPS => Ok(Self::StructOps),
1044 bpf_prog_type_BPF_PROG_TYPE_SYSCALL => Ok(Self::Syscall),
1045 bpf_prog_type_BPF_PROG_TYPE_TRACEPOINT => Ok(Self::Tracepoint),
1046 bpf_prog_type_BPF_PROG_TYPE_TRACING => Ok(Self::Tracing),
1047 bpf_prog_type_BPF_PROG_TYPE_UNSPEC => Ok(Self::Unspec),
1048 bpf_prog_type_BPF_PROG_TYPE_XDP => Ok(Self::Xdp),
1049 BPF_PROG_TYPE_FUSE => Ok(Self::Fuse),
1050 program_type @ _ => Err(EbpfApiError::InvalidProgramType(program_type)),
1051 }
1052 }
1053}
1054
1055impl From<ProgramType> for u32 {
1056 fn from(program_type: ProgramType) -> u32 {
1057 match program_type {
1058 ProgramType::CgroupDevice => bpf_prog_type_BPF_PROG_TYPE_CGROUP_DEVICE,
1059 ProgramType::CgroupSkb => bpf_prog_type_BPF_PROG_TYPE_CGROUP_SKB,
1060 ProgramType::CgroupSock => bpf_prog_type_BPF_PROG_TYPE_CGROUP_SOCK,
1061 ProgramType::CgroupSockAddr => bpf_prog_type_BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
1062 ProgramType::CgroupSockopt => bpf_prog_type_BPF_PROG_TYPE_CGROUP_SOCKOPT,
1063 ProgramType::CgroupSysctl => bpf_prog_type_BPF_PROG_TYPE_CGROUP_SYSCTL,
1064 ProgramType::Ext => bpf_prog_type_BPF_PROG_TYPE_EXT,
1065 ProgramType::FlowDissector => bpf_prog_type_BPF_PROG_TYPE_FLOW_DISSECTOR,
1066 ProgramType::Kprobe => bpf_prog_type_BPF_PROG_TYPE_KPROBE,
1067 ProgramType::LircMode2 => bpf_prog_type_BPF_PROG_TYPE_LIRC_MODE2,
1068 ProgramType::Lsm => bpf_prog_type_BPF_PROG_TYPE_LSM,
1069 ProgramType::LwtIn => bpf_prog_type_BPF_PROG_TYPE_LWT_IN,
1070 ProgramType::LwtOut => bpf_prog_type_BPF_PROG_TYPE_LWT_OUT,
1071 ProgramType::LwtSeg6Local => bpf_prog_type_BPF_PROG_TYPE_LWT_SEG6LOCAL,
1072 ProgramType::LwtXmit => bpf_prog_type_BPF_PROG_TYPE_LWT_XMIT,
1073 ProgramType::Netfilter => bpf_prog_type_BPF_PROG_TYPE_NETFILTER,
1074 ProgramType::PerfEvent => bpf_prog_type_BPF_PROG_TYPE_PERF_EVENT,
1075 ProgramType::RawTracepoint => bpf_prog_type_BPF_PROG_TYPE_RAW_TRACEPOINT,
1076 ProgramType::RawTracepointWritable => {
1077 bpf_prog_type_BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE
1078 }
1079 ProgramType::SchedAct => bpf_prog_type_BPF_PROG_TYPE_SCHED_ACT,
1080 ProgramType::SchedCls => bpf_prog_type_BPF_PROG_TYPE_SCHED_CLS,
1081 ProgramType::SkLookup => bpf_prog_type_BPF_PROG_TYPE_SK_LOOKUP,
1082 ProgramType::SkMsg => bpf_prog_type_BPF_PROG_TYPE_SK_MSG,
1083 ProgramType::SkReuseport => bpf_prog_type_BPF_PROG_TYPE_SK_REUSEPORT,
1084 ProgramType::SkSkb => bpf_prog_type_BPF_PROG_TYPE_SK_SKB,
1085 ProgramType::SockOps => bpf_prog_type_BPF_PROG_TYPE_SOCK_OPS,
1086 ProgramType::SocketFilter => bpf_prog_type_BPF_PROG_TYPE_SOCKET_FILTER,
1087 ProgramType::StructOps => bpf_prog_type_BPF_PROG_TYPE_STRUCT_OPS,
1088 ProgramType::Syscall => bpf_prog_type_BPF_PROG_TYPE_SYSCALL,
1089 ProgramType::Tracepoint => bpf_prog_type_BPF_PROG_TYPE_TRACEPOINT,
1090 ProgramType::Tracing => bpf_prog_type_BPF_PROG_TYPE_TRACING,
1091 ProgramType::Unspec => bpf_prog_type_BPF_PROG_TYPE_UNSPEC,
1092 ProgramType::Xdp => bpf_prog_type_BPF_PROG_TYPE_XDP,
1093 ProgramType::Fuse => BPF_PROG_TYPE_FUSE,
1094 }
1095 }
1096}
1097
1098impl ProgramType {
1099 pub fn get_helpers(self) -> HashMap<u32, FunctionSignature> {
1100 BPF_HELPERS_DEFINITIONS
1101 .iter()
1102 .filter_map(|(filter, helper)| {
1103 filter.accept(self).then_some((helper.index, helper.signature.clone()))
1104 })
1105 .collect()
1106 }
1107
1108 pub fn get_args(
1109 self,
1110 expected_attach_type: AttachType,
1111 ) -> Result<&'static [Type], EbpfApiError> {
1112 let args = match self {
1113 Self::SocketFilter => &SOCKET_FILTER_ARGS,
1114 Self::SchedAct | Self::SchedCls => &SCHED_ARGS,
1115 Self::CgroupSkb => match expected_attach_type {
1116 AttachType::Unspecified
1117 | AttachType::CgroupInetIngress
1118 | AttachType::CgroupInetEgress => &CGROUP_SKB_ARGS,
1119 _ => return Err(EbpfApiError::InvalidExpectedAttachType(expected_attach_type)),
1120 },
1121
1122 Self::Xdp => &XDP_MD_ARGS,
1123 Self::Kprobe => &BPF_USER_PT_REGS_T_ARGS,
1124 Self::Tracepoint => &BPF_TRACEPOINT_ARGS,
1125 Self::RawTracepoint => &BPF_RAW_TRACEPOINT_ARGS,
1126
1127 Self::CgroupSock => match expected_attach_type {
1128 AttachType::Unspecified
1129 | AttachType::CgroupInetIngress
1130 | AttachType::CgroupInetSockCreate
1131 | AttachType::CgroupInet4PostBind
1132 | AttachType::CgroupInet6PostBind
1133 | AttachType::CgroupInetSockRelease => &BPF_SOCK_ARGS,
1134 _ => return Err(EbpfApiError::InvalidExpectedAttachType(expected_attach_type)),
1135 },
1136
1137 Self::CgroupSockopt => match expected_attach_type {
1138 AttachType::CgroupGetsockopt | AttachType::CgroupSetsockopt => &BPF_SOCKOPT_ARGS,
1139 _ => return Err(EbpfApiError::InvalidExpectedAttachType(expected_attach_type)),
1140 },
1141
1142 Self::CgroupSockAddr => match expected_attach_type {
1143 AttachType::CgroupInet4Bind
1144 | AttachType::CgroupInet4Connect
1145 | AttachType::CgroupUdp4Sendmsg
1146 | AttachType::CgroupUdp4Recvmsg
1147 | AttachType::CgroupInet4Getpeername
1148 | AttachType::CgroupInet4Getsockname => &BPF_SOCK_ADDR_INET4_ARGS,
1149
1150 AttachType::CgroupInet6Bind
1151 | AttachType::CgroupInet6Connect
1152 | AttachType::CgroupUdp6Sendmsg
1153 | AttachType::CgroupUdp6Recvmsg
1154 | AttachType::CgroupInet6Getpeername
1155 | AttachType::CgroupInet6Getsockname => &BPF_SOCK_ADDR_INET6_ARGS,
1156
1157 _ => return Err(EbpfApiError::InvalidExpectedAttachType(expected_attach_type)),
1158 },
1159
1160 Self::Fuse => &BPF_FUSE_ARGS,
1161
1162 Self::CgroupDevice
1163 | Self::CgroupSysctl
1164 | Self::Ext
1165 | Self::FlowDissector
1166 | Self::LircMode2
1167 | Self::Lsm
1168 | Self::LwtIn
1169 | Self::LwtOut
1170 | Self::LwtSeg6Local
1171 | Self::LwtXmit
1172 | Self::Netfilter
1173 | Self::PerfEvent
1174 | Self::RawTracepointWritable
1175 | Self::SkLookup
1176 | Self::SkMsg
1177 | Self::SkReuseport
1178 | Self::SkSkb
1179 | Self::SockOps
1180 | Self::StructOps
1181 | Self::Syscall
1182 | Self::Tracing
1183 | Self::Unspec => return Err(EbpfApiError::UnsupportedProgramType(self)),
1184 };
1185 Ok(args)
1186 }
1187
1188 pub fn create_calling_context(
1189 self,
1190 expected_attach_type: AttachType,
1191 maps: Vec<MapSchema>,
1192 ) -> Result<CallingContext, EbpfApiError> {
1193 let args = self.get_args(expected_attach_type)?.to_vec();
1194 let packet_type = match self {
1195 Self::SocketFilter => Some(SOCKET_FILTER_SK_BUF_TYPE.clone()),
1196 Self::SchedAct | Self::SchedCls => Some(SCHED_ARG_TYPE.clone()),
1197 _ => None,
1198 };
1199 Ok(CallingContext { maps, helpers: self.get_helpers(), args, packet_type })
1200 }
1201}
1202
1203#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1204pub enum AttachType {
1205 CgroupInetIngress,
1206 CgroupInetEgress,
1207 CgroupInetSockCreate,
1208 CgroupSockOps,
1209 SkSkbStreamParser,
1210 SkSkbStreamVerdict,
1211 CgroupDevice,
1212 SkMsgVerdict,
1213 CgroupInet4Bind,
1214 CgroupInet6Bind,
1215 CgroupInet4Connect,
1216 CgroupInet6Connect,
1217 CgroupInet4PostBind,
1218 CgroupInet6PostBind,
1219 CgroupUdp4Sendmsg,
1220 CgroupUdp6Sendmsg,
1221 LircMode2,
1222 FlowDissector,
1223 CgroupSysctl,
1224 CgroupUdp4Recvmsg,
1225 CgroupUdp6Recvmsg,
1226 CgroupGetsockopt,
1227 CgroupSetsockopt,
1228 TraceRawTp,
1229 TraceFentry,
1230 TraceFexit,
1231 ModifyReturn,
1232 LsmMac,
1233 TraceIter,
1234 CgroupInet4Getpeername,
1235 CgroupInet6Getpeername,
1236 CgroupInet4Getsockname,
1237 CgroupInet6Getsockname,
1238 XdpDevmap,
1239 CgroupInetSockRelease,
1240 XdpCpumap,
1241 SkLookup,
1242 Xdp,
1243 SkSkbVerdict,
1244 SkReuseportSelect,
1245 SkReuseportSelectOrMigrate,
1246 PerfEvent,
1247 TraceKprobeMulti,
1248 LsmCgroup,
1249 StructOps,
1250 Netfilter,
1251 TcxIngress,
1252 TcxEgress,
1253 TraceUprobeMulti,
1254 CgroupUnixConnect,
1255 CgroupUnixSendmsg,
1256 CgroupUnixRecvmsg,
1257 CgroupUnixGetpeername,
1258 CgroupUnixGetsockname,
1259 NetkitPrimary,
1260 NetkitPeer,
1261 TraceKprobeSession,
1262
1263 Unspecified,
1266
1267 Invalid(u32),
1270}
1271
1272impl From<u32> for AttachType {
1273 fn from(attach_type: u32) -> Self {
1274 match attach_type {
1275 #![allow(non_upper_case_globals)]
1276 bpf_attach_type_BPF_CGROUP_INET_INGRESS => Self::CgroupInetIngress,
1277 bpf_attach_type_BPF_CGROUP_INET_EGRESS => Self::CgroupInetEgress,
1278 bpf_attach_type_BPF_CGROUP_INET_SOCK_CREATE => Self::CgroupInetSockCreate,
1279 bpf_attach_type_BPF_CGROUP_SOCK_OPS => Self::CgroupSockOps,
1280 bpf_attach_type_BPF_SK_SKB_STREAM_PARSER => Self::SkSkbStreamParser,
1281 bpf_attach_type_BPF_SK_SKB_STREAM_VERDICT => Self::SkSkbStreamVerdict,
1282 bpf_attach_type_BPF_CGROUP_DEVICE => Self::CgroupDevice,
1283 bpf_attach_type_BPF_SK_MSG_VERDICT => Self::SkMsgVerdict,
1284 bpf_attach_type_BPF_CGROUP_INET4_BIND => Self::CgroupInet4Bind,
1285 bpf_attach_type_BPF_CGROUP_INET6_BIND => Self::CgroupInet6Bind,
1286 bpf_attach_type_BPF_CGROUP_INET4_CONNECT => Self::CgroupInet4Connect,
1287 bpf_attach_type_BPF_CGROUP_INET6_CONNECT => Self::CgroupInet6Connect,
1288 bpf_attach_type_BPF_CGROUP_INET4_POST_BIND => Self::CgroupInet4PostBind,
1289 bpf_attach_type_BPF_CGROUP_INET6_POST_BIND => Self::CgroupInet6PostBind,
1290 bpf_attach_type_BPF_CGROUP_UDP4_SENDMSG => Self::CgroupUdp4Sendmsg,
1291 bpf_attach_type_BPF_CGROUP_UDP6_SENDMSG => Self::CgroupUdp6Sendmsg,
1292 bpf_attach_type_BPF_LIRC_MODE2 => Self::LircMode2,
1293 bpf_attach_type_BPF_FLOW_DISSECTOR => Self::FlowDissector,
1294 bpf_attach_type_BPF_CGROUP_SYSCTL => Self::CgroupSysctl,
1295 bpf_attach_type_BPF_CGROUP_UDP4_RECVMSG => Self::CgroupUdp4Recvmsg,
1296 bpf_attach_type_BPF_CGROUP_UDP6_RECVMSG => Self::CgroupUdp6Recvmsg,
1297 bpf_attach_type_BPF_CGROUP_GETSOCKOPT => Self::CgroupGetsockopt,
1298 bpf_attach_type_BPF_CGROUP_SETSOCKOPT => Self::CgroupSetsockopt,
1299 bpf_attach_type_BPF_TRACE_RAW_TP => Self::TraceRawTp,
1300 bpf_attach_type_BPF_TRACE_FENTRY => Self::TraceFentry,
1301 bpf_attach_type_BPF_TRACE_FEXIT => Self::TraceFexit,
1302 bpf_attach_type_BPF_MODIFY_RETURN => Self::ModifyReturn,
1303 bpf_attach_type_BPF_LSM_MAC => Self::LsmMac,
1304 bpf_attach_type_BPF_TRACE_ITER => Self::TraceIter,
1305 bpf_attach_type_BPF_CGROUP_INET4_GETPEERNAME => Self::CgroupInet4Getpeername,
1306 bpf_attach_type_BPF_CGROUP_INET6_GETPEERNAME => Self::CgroupInet6Getpeername,
1307 bpf_attach_type_BPF_CGROUP_INET4_GETSOCKNAME => Self::CgroupInet4Getsockname,
1308 bpf_attach_type_BPF_CGROUP_INET6_GETSOCKNAME => Self::CgroupInet6Getsockname,
1309 bpf_attach_type_BPF_XDP_DEVMAP => Self::XdpDevmap,
1310 bpf_attach_type_BPF_CGROUP_INET_SOCK_RELEASE => Self::CgroupInetSockRelease,
1311 bpf_attach_type_BPF_XDP_CPUMAP => Self::XdpCpumap,
1312 bpf_attach_type_BPF_SK_LOOKUP => Self::SkLookup,
1313 bpf_attach_type_BPF_XDP => Self::Xdp,
1314 bpf_attach_type_BPF_SK_SKB_VERDICT => Self::SkSkbVerdict,
1315 bpf_attach_type_BPF_SK_REUSEPORT_SELECT => Self::SkReuseportSelect,
1316 bpf_attach_type_BPF_SK_REUSEPORT_SELECT_OR_MIGRATE => Self::SkReuseportSelectOrMigrate,
1317 bpf_attach_type_BPF_PERF_EVENT => Self::PerfEvent,
1318 bpf_attach_type_BPF_TRACE_KPROBE_MULTI => Self::TraceKprobeMulti,
1319 bpf_attach_type_BPF_LSM_CGROUP => Self::LsmCgroup,
1320 bpf_attach_type_BPF_STRUCT_OPS => Self::StructOps,
1321 bpf_attach_type_BPF_NETFILTER => Self::Netfilter,
1322 bpf_attach_type_BPF_TCX_INGRESS => Self::TcxIngress,
1323 bpf_attach_type_BPF_TCX_EGRESS => Self::TcxEgress,
1324 bpf_attach_type_BPF_TRACE_UPROBE_MULTI => Self::TraceUprobeMulti,
1325 bpf_attach_type_BPF_CGROUP_UNIX_CONNECT => Self::CgroupUnixConnect,
1326 bpf_attach_type_BPF_CGROUP_UNIX_SENDMSG => Self::CgroupUnixSendmsg,
1327 bpf_attach_type_BPF_CGROUP_UNIX_RECVMSG => Self::CgroupUnixRecvmsg,
1328 bpf_attach_type_BPF_CGROUP_UNIX_GETPEERNAME => Self::CgroupUnixGetpeername,
1329 bpf_attach_type_BPF_CGROUP_UNIX_GETSOCKNAME => Self::CgroupUnixGetsockname,
1330 bpf_attach_type_BPF_NETKIT_PRIMARY => Self::NetkitPrimary,
1331 bpf_attach_type_BPF_NETKIT_PEER => Self::NetkitPeer,
1332 bpf_attach_type_BPF_TRACE_KPROBE_SESSION => Self::TraceKprobeSession,
1333
1334 u32::MAX => Self::Unspecified,
1335 _ => Self::Invalid(attach_type),
1336 }
1337 }
1338}
1339
1340impl From<AttachType> for u32 {
1341 fn from(attach_type: AttachType) -> Self {
1342 match attach_type {
1343 AttachType::CgroupInetIngress => bpf_attach_type_BPF_CGROUP_INET_INGRESS,
1344 AttachType::CgroupInetEgress => bpf_attach_type_BPF_CGROUP_INET_EGRESS,
1345 AttachType::CgroupInetSockCreate => bpf_attach_type_BPF_CGROUP_INET_SOCK_CREATE,
1346 AttachType::CgroupSockOps => bpf_attach_type_BPF_CGROUP_SOCK_OPS,
1347 AttachType::SkSkbStreamParser => bpf_attach_type_BPF_SK_SKB_STREAM_PARSER,
1348 AttachType::SkSkbStreamVerdict => bpf_attach_type_BPF_SK_SKB_STREAM_VERDICT,
1349 AttachType::CgroupDevice => bpf_attach_type_BPF_CGROUP_DEVICE,
1350 AttachType::SkMsgVerdict => bpf_attach_type_BPF_SK_MSG_VERDICT,
1351 AttachType::CgroupInet4Bind => bpf_attach_type_BPF_CGROUP_INET4_BIND,
1352 AttachType::CgroupInet6Bind => bpf_attach_type_BPF_CGROUP_INET6_BIND,
1353 AttachType::CgroupInet4Connect => bpf_attach_type_BPF_CGROUP_INET4_CONNECT,
1354 AttachType::CgroupInet6Connect => bpf_attach_type_BPF_CGROUP_INET6_CONNECT,
1355 AttachType::CgroupInet4PostBind => bpf_attach_type_BPF_CGROUP_INET4_POST_BIND,
1356 AttachType::CgroupInet6PostBind => bpf_attach_type_BPF_CGROUP_INET6_POST_BIND,
1357 AttachType::CgroupUdp4Sendmsg => bpf_attach_type_BPF_CGROUP_UDP4_SENDMSG,
1358 AttachType::CgroupUdp6Sendmsg => bpf_attach_type_BPF_CGROUP_UDP6_SENDMSG,
1359 AttachType::LircMode2 => bpf_attach_type_BPF_LIRC_MODE2,
1360 AttachType::FlowDissector => bpf_attach_type_BPF_FLOW_DISSECTOR,
1361 AttachType::CgroupSysctl => bpf_attach_type_BPF_CGROUP_SYSCTL,
1362 AttachType::CgroupUdp4Recvmsg => bpf_attach_type_BPF_CGROUP_UDP4_RECVMSG,
1363 AttachType::CgroupUdp6Recvmsg => bpf_attach_type_BPF_CGROUP_UDP6_RECVMSG,
1364 AttachType::CgroupGetsockopt => bpf_attach_type_BPF_CGROUP_GETSOCKOPT,
1365 AttachType::CgroupSetsockopt => bpf_attach_type_BPF_CGROUP_SETSOCKOPT,
1366 AttachType::TraceRawTp => bpf_attach_type_BPF_TRACE_RAW_TP,
1367 AttachType::TraceFentry => bpf_attach_type_BPF_TRACE_FENTRY,
1368 AttachType::TraceFexit => bpf_attach_type_BPF_TRACE_FEXIT,
1369 AttachType::ModifyReturn => bpf_attach_type_BPF_MODIFY_RETURN,
1370 AttachType::LsmMac => bpf_attach_type_BPF_LSM_MAC,
1371 AttachType::TraceIter => bpf_attach_type_BPF_TRACE_ITER,
1372 AttachType::CgroupInet4Getpeername => bpf_attach_type_BPF_CGROUP_INET4_GETPEERNAME,
1373 AttachType::CgroupInet6Getpeername => bpf_attach_type_BPF_CGROUP_INET6_GETPEERNAME,
1374 AttachType::CgroupInet4Getsockname => bpf_attach_type_BPF_CGROUP_INET4_GETSOCKNAME,
1375 AttachType::CgroupInet6Getsockname => bpf_attach_type_BPF_CGROUP_INET6_GETSOCKNAME,
1376 AttachType::XdpDevmap => bpf_attach_type_BPF_XDP_DEVMAP,
1377 AttachType::CgroupInetSockRelease => bpf_attach_type_BPF_CGROUP_INET_SOCK_RELEASE,
1378 AttachType::XdpCpumap => bpf_attach_type_BPF_XDP_CPUMAP,
1379 AttachType::SkLookup => bpf_attach_type_BPF_SK_LOOKUP,
1380 AttachType::Xdp => bpf_attach_type_BPF_XDP,
1381 AttachType::SkSkbVerdict => bpf_attach_type_BPF_SK_SKB_VERDICT,
1382 AttachType::SkReuseportSelect => bpf_attach_type_BPF_SK_REUSEPORT_SELECT,
1383 AttachType::SkReuseportSelectOrMigrate => {
1384 bpf_attach_type_BPF_SK_REUSEPORT_SELECT_OR_MIGRATE
1385 }
1386 AttachType::PerfEvent => bpf_attach_type_BPF_PERF_EVENT,
1387 AttachType::TraceKprobeMulti => bpf_attach_type_BPF_TRACE_KPROBE_MULTI,
1388 AttachType::LsmCgroup => bpf_attach_type_BPF_LSM_CGROUP,
1389 AttachType::StructOps => bpf_attach_type_BPF_STRUCT_OPS,
1390 AttachType::Netfilter => bpf_attach_type_BPF_NETFILTER,
1391 AttachType::TcxIngress => bpf_attach_type_BPF_TCX_INGRESS,
1392 AttachType::TcxEgress => bpf_attach_type_BPF_TCX_EGRESS,
1393 AttachType::TraceUprobeMulti => bpf_attach_type_BPF_TRACE_UPROBE_MULTI,
1394 AttachType::CgroupUnixConnect => bpf_attach_type_BPF_CGROUP_UNIX_CONNECT,
1395 AttachType::CgroupUnixSendmsg => bpf_attach_type_BPF_CGROUP_UNIX_SENDMSG,
1396 AttachType::CgroupUnixRecvmsg => bpf_attach_type_BPF_CGROUP_UNIX_RECVMSG,
1397 AttachType::CgroupUnixGetpeername => bpf_attach_type_BPF_CGROUP_UNIX_GETPEERNAME,
1398 AttachType::CgroupUnixGetsockname => bpf_attach_type_BPF_CGROUP_UNIX_GETSOCKNAME,
1399 AttachType::NetkitPrimary => bpf_attach_type_BPF_NETKIT_PRIMARY,
1400 AttachType::NetkitPeer => bpf_attach_type_BPF_NETKIT_PEER,
1401 AttachType::TraceKprobeSession => bpf_attach_type_BPF_TRACE_KPROBE_SESSION,
1402 AttachType::Unspecified => u32::MAX,
1403 AttachType::Invalid(attach_type) => attach_type,
1404 }
1405 }
1406}
1407
1408impl From<AttachType> for u64 {
1409 fn from(attach_type: AttachType) -> Self {
1410 (u32::from(attach_type)).into()
1411 }
1412}
1413
1414impl AttachType {
1415 pub fn is_cgroup(&self) -> bool {
1416 match self {
1417 Self::CgroupInetIngress
1418 | Self::CgroupInetEgress
1419 | Self::CgroupInetSockCreate
1420 | Self::CgroupSockOps
1421 | Self::CgroupDevice
1422 | Self::CgroupInet4Bind
1423 | Self::CgroupInet6Bind
1424 | Self::CgroupInet4Connect
1425 | Self::CgroupInet6Connect
1426 | Self::CgroupInet4PostBind
1427 | Self::CgroupInet6PostBind
1428 | Self::CgroupUdp4Sendmsg
1429 | Self::CgroupUdp6Sendmsg
1430 | Self::CgroupSysctl
1431 | Self::CgroupUdp4Recvmsg
1432 | Self::CgroupUdp6Recvmsg
1433 | Self::CgroupGetsockopt
1434 | Self::CgroupSetsockopt
1435 | Self::CgroupInet4Getpeername
1436 | Self::CgroupInet6Getpeername
1437 | Self::CgroupInet4Getsockname
1438 | Self::CgroupInet6Getsockname
1439 | Self::CgroupInetSockRelease
1440 | Self::CgroupUnixConnect
1441 | Self::CgroupUnixSendmsg
1442 | Self::CgroupUnixRecvmsg
1443 | Self::CgroupUnixGetpeername
1444 | Self::CgroupUnixGetsockname => true,
1445 _ => false,
1446 }
1447 }
1448
1449 pub fn get_program_type(&self) -> ProgramType {
1450 match self {
1451 Self::CgroupInetIngress | Self::CgroupInetEgress => ProgramType::CgroupSkb,
1452 Self::CgroupInetSockCreate
1453 | Self::CgroupInet4PostBind
1454 | Self::CgroupInet6PostBind
1455 | Self::CgroupInetSockRelease => ProgramType::CgroupSock,
1456 Self::CgroupSockOps | Self::CgroupGetsockopt | Self::CgroupSetsockopt => {
1457 ProgramType::CgroupSockopt
1458 }
1459 Self::CgroupDevice => ProgramType::CgroupDevice,
1460 Self::CgroupInet4Bind
1461 | Self::CgroupInet6Bind
1462 | Self::CgroupInet4Connect
1463 | Self::CgroupInet6Connect
1464 | Self::CgroupUdp4Sendmsg
1465 | Self::CgroupUdp6Sendmsg
1466 | Self::CgroupUdp4Recvmsg
1467 | Self::CgroupUdp6Recvmsg
1468 | Self::CgroupInet4Getpeername
1469 | Self::CgroupInet6Getpeername
1470 | Self::CgroupInet4Getsockname
1471 | Self::CgroupInet6Getsockname
1472 | Self::CgroupUnixConnect
1473 | Self::CgroupUnixSendmsg
1474 | Self::CgroupUnixRecvmsg
1475 | Self::CgroupUnixGetpeername
1476 | Self::CgroupUnixGetsockname => ProgramType::CgroupSockAddr,
1477 Self::CgroupSysctl => ProgramType::CgroupSysctl,
1478 Self::FlowDissector => ProgramType::FlowDissector,
1479 Self::LircMode2 => ProgramType::LircMode2,
1480 Self::LsmMac | Self::LsmCgroup => ProgramType::Lsm,
1481 Self::Netfilter => ProgramType::Netfilter,
1482 Self::PerfEvent => ProgramType::PerfEvent,
1483 Self::SkLookup => ProgramType::SkLookup,
1484 Self::SkMsgVerdict | Self::SkSkbVerdict => ProgramType::SkMsg,
1485 Self::SkReuseportSelect | Self::SkReuseportSelectOrMigrate => ProgramType::SkReuseport,
1486 Self::SkSkbStreamParser | Self::SkSkbStreamVerdict => ProgramType::SkSkb,
1487 Self::StructOps => ProgramType::StructOps,
1488 Self::TcxIngress | Self::TcxEgress | Self::NetkitPrimary | Self::NetkitPeer => {
1489 ProgramType::SchedCls
1490 }
1491 Self::TraceKprobeMulti | Self::TraceUprobeMulti | Self::TraceKprobeSession => {
1492 ProgramType::Kprobe
1493 }
1494 Self::TraceRawTp
1495 | Self::TraceFentry
1496 | Self::TraceFexit
1497 | Self::ModifyReturn
1498 | Self::TraceIter => ProgramType::Tracing,
1499 Self::XdpDevmap | Self::XdpCpumap | Self::Xdp => ProgramType::Xdp,
1500 Self::Unspecified | Self::Invalid(_) => ProgramType::Unspec,
1501 }
1502 }
1503
1504 pub fn is_compatible_with_expected_attach_type(self, expected: AttachType) -> bool {
1507 match self {
1509 Self::CgroupInetIngress | Self::CgroupInetEgress => matches!(
1512 expected,
1513 Self::Unspecified | Self::CgroupInetIngress | Self::CgroupInetEgress
1514 ),
1515
1516 Self::CgroupInetSockCreate | Self::CgroupSockOps => {
1519 self == expected || matches!(expected, Self::Unspecified | Self::CgroupInetIngress)
1520 }
1521
1522 Self::CgroupGetsockopt
1524 | Self::CgroupInet4Bind
1525 | Self::CgroupInet4Connect
1526 | Self::CgroupInet4Getpeername
1527 | Self::CgroupInet4Getsockname
1528 | Self::CgroupInet4PostBind
1529 | Self::CgroupInet6Bind
1530 | Self::CgroupInet6Connect
1531 | Self::CgroupInet6Getpeername
1532 | Self::CgroupInet6Getsockname
1533 | Self::CgroupInet6PostBind
1534 | Self::CgroupInetSockRelease
1535 | Self::CgroupSetsockopt
1536 | Self::CgroupUdp4Recvmsg
1537 | Self::CgroupUdp4Sendmsg
1538 | Self::CgroupUdp6Recvmsg
1539 | Self::CgroupUdp6Sendmsg
1540 | Self::CgroupUnixConnect
1541 | Self::CgroupUnixGetpeername
1542 | Self::CgroupUnixGetsockname
1543 | Self::CgroupUnixRecvmsg
1544 | Self::CgroupUnixSendmsg => self == expected,
1545
1546 _ => true,
1548 }
1549 }
1550}
1551
1552pub const SKF_AD_OFF: i32 = linux_uapi::SKF_AD_OFF;
1554pub const SKF_AD_PROTOCOL: i32 = linux_uapi::SKF_AD_PROTOCOL as i32;
1555pub const SKF_AD_PKTTYPE: i32 = linux_uapi::SKF_AD_PKTTYPE as i32;
1556pub const SKF_AD_IFINDEX: i32 = linux_uapi::SKF_AD_IFINDEX as i32;
1557pub const SKF_AD_NLATTR: i32 = linux_uapi::SKF_AD_NLATTR as i32;
1558pub const SKF_AD_NLATTR_NEST: i32 = linux_uapi::SKF_AD_NLATTR_NEST as i32;
1559pub const SKF_AD_MARK: i32 = linux_uapi::SKF_AD_MARK as i32;
1560pub const SKF_AD_QUEUE: i32 = linux_uapi::SKF_AD_QUEUE as i32;
1561pub const SKF_AD_HATYPE: i32 = linux_uapi::SKF_AD_HATYPE as i32;
1562pub const SKF_AD_RXHASH: i32 = linux_uapi::SKF_AD_RXHASH as i32;
1563pub const SKF_AD_CPU: i32 = linux_uapi::SKF_AD_CPU as i32;
1564pub const SKF_AD_ALU_XOR_X: i32 = linux_uapi::SKF_AD_ALU_XOR_X as i32;
1565pub const SKF_AD_VLAN_TAG: i32 = linux_uapi::SKF_AD_VLAN_TAG as i32;
1566pub const SKF_AD_VLAN_TAG_PRESENT: i32 = linux_uapi::SKF_AD_VLAN_TAG_PRESENT as i32;
1567pub const SKF_AD_PAY_OFFSET: i32 = linux_uapi::SKF_AD_PAY_OFFSET as i32;
1568pub const SKF_AD_RANDOM: i32 = linux_uapi::SKF_AD_RANDOM as i32;
1569pub const SKF_AD_VLAN_TPID: i32 = linux_uapi::SKF_AD_VLAN_TPID as i32;
1570pub const SKF_AD_MAX: i32 = linux_uapi::SKF_AD_MAX as i32;
1571
1572pub const SKF_NET_OFF: i32 = linux_uapi::SKF_NET_OFF;
1574
1575pub const SKF_LL_OFF: i32 = linux_uapi::SKF_LL_OFF;
1577
1578pub const SECCOMP_CBPF_CONFIG: CbpfConfig = CbpfConfig {
1579 len: CbpfLenInstruction::Static { len: size_of::<seccomp_data>() as i32 },
1580 allow_msh: false,
1581};
1582
1583pub const SOCKET_FILTER_CBPF_CONFIG: CbpfConfig = CbpfConfig {
1584 len: CbpfLenInstruction::ContextField { offset: offset_of!(__sk_buff, len) as i16 },
1585 allow_msh: true,
1586};