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