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