1use crate::MapKey;
6use crate::maps::{Map, MapValueRef, RingBuffer, RingBufferWakeupPolicy};
7use ebpf::{BpfValue, EbpfBufferPtr, EbpfHelperImpl, EbpfProgramContext, FromBpfValue, HelperSet};
8use inspect_stubs::track_stub;
9use linux_uapi::{
10 BPF_SK_STORAGE_GET_F_CREATE, bpf_func_id_BPF_FUNC_get_current_pid_tgid,
11 bpf_func_id_BPF_FUNC_get_current_uid_gid, bpf_func_id_BPF_FUNC_get_netns_cookie,
12 bpf_func_id_BPF_FUNC_get_retval, bpf_func_id_BPF_FUNC_get_smp_processor_id,
13 bpf_func_id_BPF_FUNC_get_socket_cookie, bpf_func_id_BPF_FUNC_get_socket_uid,
14 bpf_func_id_BPF_FUNC_ktime_get_boot_ns, bpf_func_id_BPF_FUNC_ktime_get_coarse_ns,
15 bpf_func_id_BPF_FUNC_ktime_get_ns, bpf_func_id_BPF_FUNC_map_delete_elem,
16 bpf_func_id_BPF_FUNC_map_lookup_elem, bpf_func_id_BPF_FUNC_map_update_elem,
17 bpf_func_id_BPF_FUNC_probe_read_str, bpf_func_id_BPF_FUNC_probe_read_user,
18 bpf_func_id_BPF_FUNC_probe_read_user_str, bpf_func_id_BPF_FUNC_ringbuf_discard,
19 bpf_func_id_BPF_FUNC_ringbuf_reserve, bpf_func_id_BPF_FUNC_ringbuf_submit,
20 bpf_func_id_BPF_FUNC_set_retval, bpf_func_id_BPF_FUNC_sk_fullsock,
21 bpf_func_id_BPF_FUNC_sk_lookup_tcp, bpf_func_id_BPF_FUNC_sk_lookup_udp,
22 bpf_func_id_BPF_FUNC_sk_release, bpf_func_id_BPF_FUNC_sk_storage_get,
23 bpf_func_id_BPF_FUNC_skb_load_bytes, bpf_func_id_BPF_FUNC_skb_load_bytes_relative,
24 bpf_func_id_BPF_FUNC_trace_printk, bpf_map_type_BPF_MAP_TYPE_RINGBUF,
25 bpf_map_type_BPF_MAP_TYPE_SK_STORAGE, gid_t, pid_t, uid_t,
26};
27use smallvec::SmallVec;
28use std::slice;
29use zerocopy::IntoBytes as _;
30
31pub trait MapsContext<'a> {
32 fn on_map_access(&mut self, map: &Map);
33 fn add_value_ref(&mut self, map_ref: MapValueRef<'a>);
34}
35
36pub trait MapsProgramContext: EbpfProgramContext {
37 fn on_map_access(context: &mut Self::RunContext<'_>, map: &Map);
38 fn add_value_ref<'a>(context: &mut Self::RunContext<'a>, map_ref: MapValueRef<'a>);
39}
40
41impl<C: EbpfProgramContext> MapsProgramContext for C
42where
43 for<'a> C::RunContext<'a>: MapsContext<'a>,
44{
45 fn on_map_access(context: &mut Self::RunContext<'_>, map: &Map) {
46 context.on_map_access(map);
47 }
48
49 fn add_value_ref<'a>(context: &mut Self::RunContext<'a>, map_ref: MapValueRef<'a>) {
50 context.add_value_ref(map_ref);
51 }
52}
53
54fn bpf_map_lookup_elem<'a, C: MapsProgramContext>(
55 context: &mut C::RunContext<'a>,
56 map: BpfValue,
57 key: BpfValue,
58 _: BpfValue,
59 _: BpfValue,
60 _: BpfValue,
61) -> BpfValue {
62 let map: &Map = unsafe { &*map.as_ptr::<Map>() };
64
65 let key = unsafe { EbpfBufferPtr::new(key.as_ptr::<u8>(), map.schema.key_size as usize) };
67 let key: MapKey = key.load();
68
69 C::on_map_access(context, map);
70
71 let Some(value_ref) = map.lookup(&key) else {
72 return BpfValue::default();
73 };
74
75 let result: BpfValue = value_ref.ptr().raw_ptr().into();
76
77 if value_ref.is_ref_counted() {
80 C::add_value_ref(context, value_ref);
81 }
82
83 result
84}
85
86fn bpf_map_update_elem<C: MapsProgramContext>(
87 context: &mut C::RunContext<'_>,
88 map: BpfValue,
89 key: BpfValue,
90 value: BpfValue,
91 flags: BpfValue,
92 _: BpfValue,
93) -> BpfValue {
94 let map: &Map = unsafe { &*map.as_ptr::<Map>() };
96
97 if map.schema.map_type == bpf_map_type_BPF_MAP_TYPE_SK_STORAGE {
99 return BpfValue::default();
100 }
101
102 let key = unsafe { EbpfBufferPtr::new(key.as_ptr::<u8>(), map.schema.key_size as usize) };
104 let key: MapKey = key.load();
105
106 let value = unsafe { EbpfBufferPtr::new(value.as_ptr::<u8>(), map.schema.value_size as usize) };
108 let flags = flags.as_u64();
109
110 C::on_map_access(context, map);
111
112 map.update(&key, value, flags).map(|_| 0).unwrap_or(u64::MAX).into()
113}
114
115fn bpf_map_delete_elem<C: MapsProgramContext>(
116 context: &mut C::RunContext<'_>,
117 map: BpfValue,
118 key: BpfValue,
119 _: BpfValue,
120 _: BpfValue,
121 _: BpfValue,
122) -> BpfValue {
123 let map: &Map = unsafe { &*map.as_ptr::<Map>() };
125
126 if map.schema.map_type == bpf_map_type_BPF_MAP_TYPE_SK_STORAGE {
128 return BpfValue::default();
129 }
130
131 let key = unsafe { EbpfBufferPtr::new(key.as_ptr::<u8>(), map.schema.key_size as usize) };
133 let key: MapKey = key.load();
134
135 C::on_map_access(context, map);
136
137 map.delete(&key).map(|_| 0).unwrap_or(u64::MAX).into()
138}
139
140fn bpf_trace_printk<C: EbpfProgramContext>(
141 _context: &mut C::RunContext<'_>,
142 _fmt: BpfValue,
143 _fmt_size: BpfValue,
144 _: BpfValue,
145 _: BpfValue,
146 _: BpfValue,
147) -> BpfValue {
148 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_trace_printk");
149 0.into()
150}
151
152fn bpf_ktime_get_ns<C: EbpfProgramContext>(
153 _context: &mut C::RunContext<'_>,
154 _: BpfValue,
155 _: BpfValue,
156 _: BpfValue,
157 _: BpfValue,
158 _: BpfValue,
159) -> BpfValue {
160 zx::MonotonicInstant::get().into_nanos().into()
161}
162
163fn bpf_ringbuf_reserve<C: EbpfProgramContext>(
164 _context: &mut C::RunContext<'_>,
165 map: BpfValue,
166 size: BpfValue,
167 flags: BpfValue,
168 _: BpfValue,
169 _: BpfValue,
170) -> BpfValue {
171 let map: &Map = unsafe { &*map.as_ptr::<Map>() };
174
175 assert!(map.schema.map_type == bpf_map_type_BPF_MAP_TYPE_RINGBUF);
177
178 let size = u32::from(size);
179 let flags = u64::from(flags);
180 map.ringbuf_reserve(size, flags).map(BpfValue::from).unwrap_or_else(|_| BpfValue::default())
181}
182
183fn bpf_ringbuf_submit<C: EbpfProgramContext>(
184 _context: &mut C::RunContext<'_>,
185 data: BpfValue,
186 flags: BpfValue,
187 _: BpfValue,
188 _: BpfValue,
189 _: BpfValue,
190) -> BpfValue {
191 let flags = RingBufferWakeupPolicy::from(u32::from(flags));
192
193 unsafe {
196 RingBuffer::submit(u64::from(data), flags);
197 }
198 0.into()
199}
200
201fn bpf_ringbuf_discard<C: EbpfProgramContext>(
202 _context: &mut C::RunContext<'_>,
203 data: BpfValue,
204 flags: BpfValue,
205 _: BpfValue,
206 _: BpfValue,
207 _: BpfValue,
208) -> BpfValue {
209 let flags = RingBufferWakeupPolicy::from(u32::from(flags));
210
211 unsafe {
214 RingBuffer::discard(u64::from(data), flags);
215 }
216 0.into()
217}
218
219fn bpf_ktime_get_boot_ns<C: EbpfProgramContext>(
220 _context: &mut C::RunContext<'_>,
221 _: BpfValue,
222 _: BpfValue,
223 _: BpfValue,
224 _: BpfValue,
225 _: BpfValue,
226) -> BpfValue {
227 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_ktime_get_boot_ns");
228 0.into()
229}
230
231fn bpf_probe_read_user<C: EbpfProgramContext>(
232 _context: &mut C::RunContext<'_>,
233 _: BpfValue,
234 _: BpfValue,
235 _: BpfValue,
236 _: BpfValue,
237 _: BpfValue,
238) -> BpfValue {
239 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_probe_read_user");
240 0.into()
241}
242
243fn bpf_probe_read_user_str<C: EbpfProgramContext>(
244 _context: &mut C::RunContext<'_>,
245 _: BpfValue,
246 _: BpfValue,
247 _: BpfValue,
248 _: BpfValue,
249 _: BpfValue,
250) -> BpfValue {
251 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_probe_read_user_str");
252 0.into()
253}
254
255fn bpf_ktime_get_coarse_ns<C: EbpfProgramContext>(
256 _context: &mut C::RunContext<'_>,
257 _: BpfValue,
258 _: BpfValue,
259 _: BpfValue,
260 _: BpfValue,
261 _: BpfValue,
262) -> BpfValue {
263 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_ktime_get_coarse_ns");
264 0.into()
265}
266
267fn bpf_probe_read_str<C: EbpfProgramContext>(
268 _context: &mut C::RunContext<'_>,
269 _: BpfValue,
270 _: BpfValue,
271 _: BpfValue,
272 _: BpfValue,
273 _: BpfValue,
274) -> BpfValue {
275 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_probe_read_str");
276 0.into()
277}
278
279fn bpf_get_smp_processor_id<C: EbpfProgramContext>(
280 _context: &mut C::RunContext<'_>,
281 _: BpfValue,
282 _: BpfValue,
283 _: BpfValue,
284 _: BpfValue,
285 _: BpfValue,
286) -> BpfValue {
287 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_get_smp_processor_id");
288 0.into()
289}
290
291pub trait CurrentTaskContext {
292 fn get_uid_gid(&self) -> (uid_t, gid_t);
293 fn get_tid_tgid(&self) -> (pid_t, pid_t);
294}
295
296pub trait CurrentTaskProgramContext: EbpfProgramContext {
297 fn get_uid_gid<'a>(context: &mut Self::RunContext<'a>) -> (uid_t, gid_t);
298 fn get_tid_tgid<'a>(context: &mut Self::RunContext<'a>) -> (pid_t, pid_t);
299}
300
301impl<C: EbpfProgramContext> CurrentTaskProgramContext for C
302where
303 for<'a> C::RunContext<'a>: CurrentTaskContext,
304{
305 fn get_uid_gid<'a>(context: &mut Self::RunContext<'a>) -> (uid_t, gid_t) {
306 context.get_uid_gid()
307 }
308 fn get_tid_tgid<'a>(context: &mut Self::RunContext<'a>) -> (pid_t, pid_t) {
309 context.get_tid_tgid()
310 }
311}
312
313fn bpf_get_current_uid_gid<C: CurrentTaskProgramContext>(
314 context: &mut C::RunContext<'_>,
315 _: BpfValue,
316 _: BpfValue,
317 _: BpfValue,
318 _: BpfValue,
319 _: BpfValue,
320) -> BpfValue {
321 let (uid, gid) = C::get_uid_gid(context);
322 (uid as u64 | (gid as u64) << 32).into()
323}
324
325fn bpf_get_current_pid_tgid<C: CurrentTaskProgramContext>(
326 context: &mut C::RunContext<'_>,
327 _: BpfValue,
328 _: BpfValue,
329 _: BpfValue,
330 _: BpfValue,
331 _: BpfValue,
332) -> BpfValue {
333 let (pid, tgid) = C::get_tid_tgid(context);
334 (pid as u64 | (tgid as u64) << 32).into()
335}
336
337pub trait Arg1IsSocketProgramContext: EbpfProgramContext {
340 type Arg1AsSocket<'a>: FromBpfValue<Self::RunContext<'a>> + SocketRef;
341}
342
343impl<C> Arg1IsSocketProgramContext for C
344where
345 C: EbpfProgramContext,
346 for<'a> Self::Arg1<'a>: FromBpfValue<Self::RunContext<'a>> + SocketRef,
347{
348 type Arg1AsSocket<'a> = Self::Arg1<'a>;
349}
350
351pub trait SocketCookieProgramContext: Arg1IsSocketProgramContext {}
353impl<C> SocketCookieProgramContext for C where C: Arg1IsSocketProgramContext {}
354
355fn bpf_get_socket_cookie<'a, C: SocketCookieProgramContext>(
356 context: &mut C::RunContext<'a>,
357 arg1: BpfValue,
358 _: BpfValue,
359 _: BpfValue,
360 _: BpfValue,
361 _: BpfValue,
362) -> BpfValue {
363 let arg1_as_socket = unsafe { C::Arg1AsSocket::from_bpf_value(context, arg1) };
366 arg1_as_socket.get_socket_cookie().unwrap_or(0).into()
367}
368
369pub trait SocketRef {
370 fn get_socket_cookie(&self) -> Option<u64>;
371 fn get_socket_uid(&self) -> Option<uid_t>;
372}
373
374pub trait BpfSockContext: Sized {
376 type BpfSockRef: SocketRef + FromBpfValue<Self>;
377}
378
379pub trait SkStorageProgramContext: EbpfProgramContext {
380 type BpfSockRef<'a>: SocketRef + FromBpfValue<Self::RunContext<'a>>;
381}
382
383impl<C> SkStorageProgramContext for C
384where
385 C: EbpfProgramContext,
386 for<'a> C::RunContext<'a>: BpfSockContext,
387{
388 type BpfSockRef<'a> = <C::RunContext<'a> as BpfSockContext>::BpfSockRef;
389}
390
391#[derive(Copy, Clone, Debug, PartialEq, Eq)]
392pub enum LoadBytesBase {
393 MacHeader,
394 NetworkHeader,
395}
396
397pub trait SocketUidProgramContext: Arg1IsSocketProgramContext {}
399impl<C> SocketUidProgramContext for C where C: Arg1IsSocketProgramContext {}
400
401fn bpf_get_socket_uid<'a, C: SocketUidProgramContext>(
402 context: &mut C::RunContext<'a>,
403 sk_buf: BpfValue,
404 _: BpfValue,
405 _: BpfValue,
406 _: BpfValue,
407 _: BpfValue,
408) -> BpfValue {
409 const OVERFLOW_UID: uid_t = 65534;
410 let sk_buf = unsafe { C::Arg1AsSocket::from_bpf_value(context, sk_buf) };
412 sk_buf.get_socket_uid().unwrap_or(OVERFLOW_UID).into()
413}
414
415pub trait PacketWithLoadBytes {
417 fn load_bytes_relative(&self, base: LoadBytesBase, offset: usize, buf: &mut [u8]) -> i64;
418}
419
420pub trait SkbLoadBytesProgramContext: EbpfProgramContext {
422 fn skb_load_bytes_relative<'a>(
423 context: &mut Self::RunContext<'a>,
424 sk_buf: BpfValue,
425 base: LoadBytesBase,
426 offset: usize,
427 buf: &mut [u8],
428 ) -> i64;
429}
430
431impl<C: EbpfProgramContext> SkbLoadBytesProgramContext for C
432where
433 for<'b> C::Arg1<'b>: FromBpfValue<C::RunContext<'b>>,
434 for<'b> C::Arg1<'b>: PacketWithLoadBytes,
435{
436 fn skb_load_bytes_relative<'a>(
437 context: &mut Self::RunContext<'a>,
438 sk_buf: BpfValue,
439 base: LoadBytesBase,
440 offset: usize,
441 buf: &mut [u8],
442 ) -> i64 {
443 let sk_buf = unsafe { C::Arg1::from_bpf_value(context, sk_buf) };
446 sk_buf.load_bytes_relative(base, offset, buf)
447 }
448}
449
450fn bpf_skb_load_bytes<'a, C: SkbLoadBytesProgramContext>(
451 context: &mut C::RunContext<'a>,
452 sk_buf: BpfValue,
453 offset: BpfValue,
454 to: BpfValue,
455 len: BpfValue,
456 _: BpfValue,
457) -> BpfValue {
458 let base = LoadBytesBase::NetworkHeader;
459
460 let Ok(offset) = offset.as_u64().try_into() else {
461 return u64::MAX.into();
462 };
463
464 let buf = unsafe { slice::from_raw_parts_mut(to.as_ptr::<u8>(), len.as_u64() as usize) };
467
468 C::skb_load_bytes_relative(context, sk_buf, base, offset, buf).into()
469}
470
471fn bpf_skb_load_bytes_relative<'a, C: SkbLoadBytesProgramContext>(
472 context: &mut C::RunContext<'a>,
473 sk_buf: BpfValue,
474 offset: BpfValue,
475 to: BpfValue,
476 len: BpfValue,
477 start_header: BpfValue,
478) -> BpfValue {
479 let base = match start_header.as_u32() {
480 0 => LoadBytesBase::MacHeader,
481 1 => LoadBytesBase::NetworkHeader,
482 _ => return u64::MAX.into(),
483 };
484
485 let Ok(offset) = offset.as_u64().try_into() else {
486 return u64::MAX.into();
487 };
488
489 let buf = unsafe { slice::from_raw_parts_mut(to.as_ptr::<u8>(), len.as_u64() as usize) };
492
493 C::skb_load_bytes_relative(context, sk_buf, base, offset, buf).into()
494}
495
496fn bpf_sk_storage_get<'a, C: SkStorageProgramContext + MapsProgramContext>(
497 context: &mut C::RunContext<'a>,
498 map: BpfValue,
499 sk: BpfValue,
500 value: BpfValue,
501 flags: BpfValue,
502 _: BpfValue,
503) -> BpfValue {
504 if sk.is_zero() {
505 return BpfValue::default();
506 }
507
508 let bpf_sock = unsafe { C::BpfSockRef::from_bpf_value(context, sk) };
511
512 let Some(socket_id) = bpf_sock.get_socket_cookie() else {
514 return BpfValue::default();
515 };
516
517 let key = socket_id.as_bytes();
518
519 let map: &Map = unsafe { &*map.as_ptr::<Map>() };
521
522 assert!(map.schema.map_type == bpf_map_type_BPF_MAP_TYPE_SK_STORAGE);
524
525 C::on_map_access(context, map);
526
527 if let Some(value_ref) = map.lookup(key) {
528 let result: BpfValue = value_ref.ptr().raw_ptr().into();
529 return result;
530 }
531
532 if flags.as_u32() & BPF_SK_STORAGE_GET_F_CREATE != 0 {
533 let mut vec;
534 let init_val = if value.as_u64() == 0 {
535 vec = SmallVec::<[u8; 128]>::new();
536 vec.resize(map.schema.value_size as usize, 0);
537 (&mut vec[..]).into()
538 } else {
539 unsafe { EbpfBufferPtr::new(value.as_ptr::<u8>(), map.schema.value_size as usize) }
541 };
542
543 let r = map.update(key, init_val, 0);
544 if r.is_ok() {
545 if let Some(value_ref) = map.lookup(key) {
546 let result: BpfValue = value_ref.ptr().raw_ptr().into();
547 return result;
548 }
549 }
550 }
551
552 BpfValue::default()
553}
554
555fn bpf_sk_fullsock<C: EbpfProgramContext>(
556 _context: &mut C::RunContext<'_>,
557 _: BpfValue,
558 _: BpfValue,
559 _: BpfValue,
560 _: BpfValue,
561 _: BpfValue,
562) -> BpfValue {
563 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_sk_fullsock");
564 0.into()
565}
566
567pub trait ReturnValueContext {
568 fn set_retval(&mut self, value: i32) -> i32;
569 fn get_retval(&self) -> i32;
570}
571
572pub trait ReturnValueProgramContext: EbpfProgramContext {
573 fn set_retval<'a>(context: &mut Self::RunContext<'a>, value: i32) -> i32;
574 fn get_retval<'a>(context: &mut Self::RunContext<'a>) -> i32;
575}
576
577impl<C: EbpfProgramContext> ReturnValueProgramContext for C
578where
579 for<'a> C::RunContext<'a>: ReturnValueContext,
580{
581 fn set_retval<'a>(context: &mut Self::RunContext<'a>, value: i32) -> i32 {
582 context.set_retval(value)
583 }
584 fn get_retval<'a>(context: &mut Self::RunContext<'a>) -> i32 {
585 context.get_retval()
586 }
587}
588
589fn bpf_set_retval<C: ReturnValueProgramContext>(
590 context: &mut C::RunContext<'_>,
591 value: BpfValue,
592 _: BpfValue,
593 _: BpfValue,
594 _: BpfValue,
595 _: BpfValue,
596) -> BpfValue {
597 C::set_retval(context, value.as_i32()).into()
598}
599
600fn bpf_get_retval<C: ReturnValueProgramContext>(
601 context: &mut C::RunContext<'_>,
602 _: BpfValue,
603 _: BpfValue,
604 _: BpfValue,
605 _: BpfValue,
606 _: BpfValue,
607) -> BpfValue {
608 C::get_retval(context).into()
609}
610
611fn bpf_sk_lookup_tcp<C: EbpfProgramContext>(
612 _context: &mut C::RunContext<'_>,
613 _: BpfValue,
614 _: BpfValue,
615 _: BpfValue,
616 _: BpfValue,
617 _: BpfValue,
618) -> BpfValue {
619 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_sk_lookup_tcp");
620 0.into()
621}
622
623fn bpf_sk_lookup_udp<C: EbpfProgramContext>(
624 _context: &mut C::RunContext<'_>,
625 _: BpfValue,
626 _: BpfValue,
627 _: BpfValue,
628 _: BpfValue,
629 _: BpfValue,
630) -> BpfValue {
631 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_sk_lookup_udp");
632 0.into()
633}
634
635fn bpf_sk_release<C: EbpfProgramContext>(
636 _context: &mut C::RunContext<'_>,
637 _: BpfValue,
638 _: BpfValue,
639 _: BpfValue,
640 _: BpfValue,
641 _: BpfValue,
642) -> BpfValue {
643 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_sk_release");
644 0.into()
645}
646
647fn bpf_get_netns_cookie<C: EbpfProgramContext>(
648 _context: &mut C::RunContext<'_>,
649 _: BpfValue,
650 _: BpfValue,
651 _: BpfValue,
652 _: BpfValue,
653 _: BpfValue,
654) -> BpfValue {
655 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_get_netns_cookie");
656 const DEFAULT_NETWORK_NAMESPACE_COOKIE: u64 = 1;
657 DEFAULT_NETWORK_NAMESPACE_COOKIE.into()
658}
659
660fn get_common_helpers<C: MapsProgramContext>() -> impl Iterator<Item = (u32, EbpfHelperImpl<C>)> {
661 [
662 (bpf_func_id_BPF_FUNC_ktime_get_boot_ns, EbpfHelperImpl(bpf_ktime_get_boot_ns)),
663 (bpf_func_id_BPF_FUNC_ktime_get_coarse_ns, EbpfHelperImpl(bpf_ktime_get_coarse_ns)),
664 (bpf_func_id_BPF_FUNC_ktime_get_ns, EbpfHelperImpl(bpf_ktime_get_ns)),
665 (bpf_func_id_BPF_FUNC_map_delete_elem, EbpfHelperImpl(bpf_map_delete_elem)),
666 (bpf_func_id_BPF_FUNC_map_lookup_elem, EbpfHelperImpl(bpf_map_lookup_elem)),
667 (bpf_func_id_BPF_FUNC_map_update_elem, EbpfHelperImpl(bpf_map_update_elem)),
668 (bpf_func_id_BPF_FUNC_probe_read_str, EbpfHelperImpl(bpf_probe_read_str)),
669 (bpf_func_id_BPF_FUNC_probe_read_user, EbpfHelperImpl(bpf_probe_read_user)),
670 (bpf_func_id_BPF_FUNC_probe_read_user_str, EbpfHelperImpl(bpf_probe_read_user_str)),
671 (bpf_func_id_BPF_FUNC_ringbuf_discard, EbpfHelperImpl(bpf_ringbuf_discard)),
672 (bpf_func_id_BPF_FUNC_ringbuf_reserve, EbpfHelperImpl(bpf_ringbuf_reserve)),
673 (bpf_func_id_BPF_FUNC_ringbuf_submit, EbpfHelperImpl(bpf_ringbuf_submit)),
674 (bpf_func_id_BPF_FUNC_trace_printk, EbpfHelperImpl(bpf_trace_printk)),
675 (bpf_func_id_BPF_FUNC_get_smp_processor_id, EbpfHelperImpl(bpf_get_smp_processor_id)),
676 ]
677 .into_iter()
678}
679
680fn get_current_task_helpers<C: CurrentTaskProgramContext>()
682-> impl Iterator<Item = (u32, EbpfHelperImpl<C>)> {
683 [
684 (bpf_func_id_BPF_FUNC_get_current_uid_gid, EbpfHelperImpl(bpf_get_current_uid_gid)),
685 (bpf_func_id_BPF_FUNC_get_current_pid_tgid, EbpfHelperImpl(bpf_get_current_pid_tgid)),
686 ]
687 .into_iter()
688}
689
690pub trait CgroupSockProgramContext:
693 MapsProgramContext
694 + SocketCookieProgramContext
695 + CurrentTaskProgramContext
696 + SkStorageProgramContext
697{
698 fn get_helpers() -> HelperSet<Self> {
699 [
700 (bpf_func_id_BPF_FUNC_get_netns_cookie, EbpfHelperImpl(bpf_get_netns_cookie)),
701 (bpf_func_id_BPF_FUNC_get_socket_cookie, EbpfHelperImpl(bpf_get_socket_cookie)),
702 (bpf_func_id_BPF_FUNC_sk_storage_get, EbpfHelperImpl(bpf_sk_storage_get)),
703 (bpf_func_id_BPF_FUNC_sk_lookup_tcp, EbpfHelperImpl(bpf_sk_lookup_tcp)),
704 (bpf_func_id_BPF_FUNC_sk_lookup_udp, EbpfHelperImpl(bpf_sk_lookup_udp)),
705 (bpf_func_id_BPF_FUNC_sk_release, EbpfHelperImpl(bpf_sk_release)),
706 ]
707 .into_iter()
708 .chain(get_common_helpers())
709 .chain(get_current_task_helpers())
710 .collect()
711 }
712}
713
714pub trait CgroupSockAddrProgramContext:
717 MapsProgramContext
718 + SocketCookieProgramContext
719 + CurrentTaskProgramContext
720 + SkStorageProgramContext
721{
722 fn get_helpers() -> HelperSet<Self> {
723 [
724 (bpf_func_id_BPF_FUNC_get_netns_cookie, EbpfHelperImpl(bpf_get_netns_cookie)),
725 (bpf_func_id_BPF_FUNC_get_socket_cookie, EbpfHelperImpl(bpf_get_socket_cookie)),
726 (bpf_func_id_BPF_FUNC_sk_storage_get, EbpfHelperImpl(bpf_sk_storage_get)),
727 (bpf_func_id_BPF_FUNC_sk_lookup_tcp, EbpfHelperImpl(bpf_sk_lookup_tcp)),
728 (bpf_func_id_BPF_FUNC_sk_lookup_udp, EbpfHelperImpl(bpf_sk_lookup_udp)),
729 (bpf_func_id_BPF_FUNC_sk_release, EbpfHelperImpl(bpf_sk_release)),
730 ]
731 .into_iter()
732 .chain(get_common_helpers())
733 .chain(get_current_task_helpers())
734 .collect()
735 }
736}
737
738pub trait CgroupSockOptProgramContext:
741 MapsProgramContext + CurrentTaskProgramContext + ReturnValueProgramContext + SkStorageProgramContext
742{
743 fn get_helpers() -> HelperSet<Self> {
744 [
745 (bpf_func_id_BPF_FUNC_get_netns_cookie, EbpfHelperImpl(bpf_get_netns_cookie)),
746 (bpf_func_id_BPF_FUNC_set_retval, EbpfHelperImpl(bpf_set_retval)),
747 (bpf_func_id_BPF_FUNC_get_retval, EbpfHelperImpl(bpf_get_retval)),
748 (bpf_func_id_BPF_FUNC_sk_storage_get, EbpfHelperImpl(bpf_sk_storage_get)),
749 (bpf_func_id_BPF_FUNC_sk_lookup_tcp, EbpfHelperImpl(bpf_sk_lookup_tcp)),
750 (bpf_func_id_BPF_FUNC_sk_lookup_udp, EbpfHelperImpl(bpf_sk_lookup_udp)),
751 (bpf_func_id_BPF_FUNC_sk_release, EbpfHelperImpl(bpf_sk_release)),
752 ]
753 .into_iter()
754 .chain(get_common_helpers())
755 .chain(get_current_task_helpers())
756 .collect()
757 }
758}
759
760pub trait SocketFilterProgramContext:
763 MapsProgramContext
764 + SocketUidProgramContext
765 + SocketCookieProgramContext
766 + SkbLoadBytesProgramContext
767{
768 fn get_helpers() -> HelperSet<Self> {
769 vec![
770 (bpf_func_id_BPF_FUNC_get_netns_cookie, EbpfHelperImpl(bpf_get_netns_cookie)),
771 (bpf_func_id_BPF_FUNC_get_socket_uid, EbpfHelperImpl(bpf_get_socket_uid)),
772 (bpf_func_id_BPF_FUNC_get_socket_cookie, EbpfHelperImpl(bpf_get_socket_cookie)),
773 (bpf_func_id_BPF_FUNC_skb_load_bytes, EbpfHelperImpl(bpf_skb_load_bytes)),
774 (
775 bpf_func_id_BPF_FUNC_skb_load_bytes_relative,
776 EbpfHelperImpl(bpf_skb_load_bytes_relative),
777 ),
778 ]
779 .into_iter()
780 .chain(get_common_helpers())
781 .collect()
782 }
783}
784
785pub trait CgroupSkbProgramContext:
788 MapsProgramContext
789 + SocketUidProgramContext
790 + SocketCookieProgramContext
791 + SkbLoadBytesProgramContext
792 + SkStorageProgramContext
793{
794 fn get_helpers() -> HelperSet<Self> {
795 vec![
796 (bpf_func_id_BPF_FUNC_get_netns_cookie, EbpfHelperImpl(bpf_get_netns_cookie)),
797 (bpf_func_id_BPF_FUNC_get_socket_uid, EbpfHelperImpl(bpf_get_socket_uid)),
798 (bpf_func_id_BPF_FUNC_get_socket_cookie, EbpfHelperImpl(bpf_get_socket_cookie)),
799 (bpf_func_id_BPF_FUNC_skb_load_bytes, EbpfHelperImpl(bpf_skb_load_bytes)),
800 (
801 bpf_func_id_BPF_FUNC_skb_load_bytes_relative,
802 EbpfHelperImpl(bpf_skb_load_bytes_relative),
803 ),
804 (bpf_func_id_BPF_FUNC_sk_storage_get, EbpfHelperImpl(bpf_sk_storage_get)),
805 (bpf_func_id_BPF_FUNC_sk_lookup_tcp, EbpfHelperImpl(bpf_sk_lookup_tcp)),
806 (bpf_func_id_BPF_FUNC_sk_lookup_udp, EbpfHelperImpl(bpf_sk_lookup_udp)),
807 (bpf_func_id_BPF_FUNC_sk_release, EbpfHelperImpl(bpf_sk_release)),
808 (bpf_func_id_BPF_FUNC_sk_fullsock, EbpfHelperImpl(bpf_sk_fullsock)),
809 ]
810 .into_iter()
811 .chain(get_common_helpers())
812 .collect()
813 }
814}
815
816#[macro_export]
828macro_rules! ebpf_program_context_type {
829 ($context:ty, $subtrait:ty) => {
830 impl $subtrait for $context {}
831 ebpf::static_helper_set!($context, <$context as $subtrait>::get_helpers());
832 };
833}