1use crate::maps::{Map, MapKey, MapValueRef, RingBuffer, RingBufferWakeupPolicy};
6use ebpf::{BpfValue, EbpfHelperImpl, EbpfProgramContext, FromBpfValue, HelperSet};
7use inspect_stubs::track_stub;
8use linux_uapi::{
9 bpf_func_id_BPF_FUNC_get_current_pid_tgid, bpf_func_id_BPF_FUNC_get_current_uid_gid,
10 bpf_func_id_BPF_FUNC_get_retval, bpf_func_id_BPF_FUNC_get_smp_processor_id,
11 bpf_func_id_BPF_FUNC_get_socket_cookie, bpf_func_id_BPF_FUNC_get_socket_uid,
12 bpf_func_id_BPF_FUNC_ktime_get_boot_ns, bpf_func_id_BPF_FUNC_ktime_get_coarse_ns,
13 bpf_func_id_BPF_FUNC_ktime_get_ns, bpf_func_id_BPF_FUNC_map_delete_elem,
14 bpf_func_id_BPF_FUNC_map_lookup_elem, bpf_func_id_BPF_FUNC_map_update_elem,
15 bpf_func_id_BPF_FUNC_probe_read_str, bpf_func_id_BPF_FUNC_probe_read_user,
16 bpf_func_id_BPF_FUNC_probe_read_user_str, bpf_func_id_BPF_FUNC_ringbuf_discard,
17 bpf_func_id_BPF_FUNC_ringbuf_reserve, bpf_func_id_BPF_FUNC_ringbuf_submit,
18 bpf_func_id_BPF_FUNC_set_retval, bpf_func_id_BPF_FUNC_sk_fullsock,
19 bpf_func_id_BPF_FUNC_sk_storage_get, bpf_func_id_BPF_FUNC_skb_load_bytes_relative,
20 bpf_func_id_BPF_FUNC_trace_printk, gid_t, pid_t, uid_t,
21};
22use std::slice;
23
24pub trait MapsContext<'a> {
25 fn on_map_access(&mut self, map: &Map);
26 fn add_value_ref(&mut self, map_ref: MapValueRef<'a>);
27}
28
29pub trait MapsProgramContext: EbpfProgramContext {
30 fn on_map_access(context: &mut Self::RunContext<'_>, map: &Map);
31 fn add_value_ref<'a>(context: &mut Self::RunContext<'a>, map_ref: MapValueRef<'a>);
32}
33
34impl<C: EbpfProgramContext> MapsProgramContext for C
35where
36 for<'a> C::RunContext<'a>: MapsContext<'a>,
37{
38 fn on_map_access(context: &mut Self::RunContext<'_>, map: &Map) {
39 context.on_map_access(map);
40 }
41
42 fn add_value_ref<'a>(context: &mut Self::RunContext<'a>, map_ref: MapValueRef<'a>) {
43 context.add_value_ref(map_ref);
44 }
45}
46
47fn bpf_map_lookup_elem<'a, C: MapsProgramContext>(
48 context: &mut C::RunContext<'a>,
49 map: BpfValue,
50 key: BpfValue,
51 _: BpfValue,
52 _: BpfValue,
53 _: BpfValue,
54) -> BpfValue {
55 let map: &Map = unsafe { &*map.as_ptr::<Map>() };
57 let key =
59 unsafe { std::slice::from_raw_parts(key.as_ptr::<u8>(), map.schema.key_size as usize) };
60
61 C::on_map_access(context, map);
62
63 let Some(value_ref) = map.lookup(key) else {
64 return BpfValue::default();
65 };
66
67 let result: BpfValue = value_ref.ptr().raw_ptr().into();
68
69 if value_ref.is_ref_counted() {
72 C::add_value_ref(context, value_ref);
73 }
74
75 result
76}
77
78fn bpf_map_update_elem<C: MapsProgramContext>(
79 context: &mut C::RunContext<'_>,
80 map: BpfValue,
81 key: BpfValue,
82 value: BpfValue,
83 flags: BpfValue,
84 _: BpfValue,
85) -> BpfValue {
86 let map: &Map = unsafe { &*map.as_ptr::<Map>() };
88 let key =
90 unsafe { std::slice::from_raw_parts(key.as_ptr::<u8>(), map.schema.key_size as usize) };
91 let value =
93 unsafe { std::slice::from_raw_parts(value.as_ptr::<u8>(), map.schema.value_size as usize) };
94 let flags = flags.as_u64();
95
96 let key = MapKey::from_slice(key);
97
98 C::on_map_access(context, map);
99
100 map.update(key, value, flags).map(|_| 0).unwrap_or(u64::MAX).into()
101}
102
103fn bpf_map_delete_elem<C: MapsProgramContext>(
104 context: &mut C::RunContext<'_>,
105 map: BpfValue,
106 key: BpfValue,
107 _: BpfValue,
108 _: BpfValue,
109 _: BpfValue,
110) -> BpfValue {
111 let map: &Map = unsafe { &*map.as_ptr::<Map>() };
113 let key =
115 unsafe { std::slice::from_raw_parts(key.as_ptr::<u8>(), map.schema.key_size as usize) };
116
117 C::on_map_access(context, map);
118
119 map.delete(key).map(|_| 0).unwrap_or(u64::MAX).into()
120}
121
122fn bpf_trace_printk<C: EbpfProgramContext>(
123 _context: &mut C::RunContext<'_>,
124 _fmt: BpfValue,
125 _fmt_size: BpfValue,
126 _: BpfValue,
127 _: BpfValue,
128 _: BpfValue,
129) -> BpfValue {
130 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_trace_printk");
131 0.into()
132}
133
134fn bpf_ktime_get_ns<C: EbpfProgramContext>(
135 _context: &mut C::RunContext<'_>,
136 _: BpfValue,
137 _: BpfValue,
138 _: BpfValue,
139 _: BpfValue,
140 _: BpfValue,
141) -> BpfValue {
142 zx::MonotonicInstant::get().into_nanos().into()
143}
144
145fn bpf_ringbuf_reserve<C: EbpfProgramContext>(
146 _context: &mut C::RunContext<'_>,
147 map: BpfValue,
148 size: BpfValue,
149 flags: BpfValue,
150 _: BpfValue,
151 _: BpfValue,
152) -> BpfValue {
153 let map: &Map = unsafe { &*map.as_ptr::<Map>() };
156 let size = u32::from(size);
157 let flags = u64::from(flags);
158 map.ringbuf_reserve(size, flags).map(BpfValue::from).unwrap_or_else(|_| BpfValue::default())
159}
160
161fn bpf_ringbuf_submit<C: EbpfProgramContext>(
162 _context: &mut C::RunContext<'_>,
163 data: BpfValue,
164 flags: BpfValue,
165 _: BpfValue,
166 _: BpfValue,
167 _: BpfValue,
168) -> BpfValue {
169 let flags = RingBufferWakeupPolicy::from(u32::from(flags));
170
171 unsafe {
174 RingBuffer::submit(u64::from(data), flags);
175 }
176 0.into()
177}
178
179fn bpf_ringbuf_discard<C: EbpfProgramContext>(
180 _context: &mut C::RunContext<'_>,
181 data: BpfValue,
182 flags: BpfValue,
183 _: BpfValue,
184 _: BpfValue,
185 _: BpfValue,
186) -> BpfValue {
187 let flags = RingBufferWakeupPolicy::from(u32::from(flags));
188
189 unsafe {
192 RingBuffer::discard(u64::from(data), flags);
193 }
194 0.into()
195}
196
197fn bpf_ktime_get_boot_ns<C: EbpfProgramContext>(
198 _context: &mut C::RunContext<'_>,
199 _: BpfValue,
200 _: BpfValue,
201 _: BpfValue,
202 _: BpfValue,
203 _: BpfValue,
204) -> BpfValue {
205 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_ktime_get_boot_ns");
206 0.into()
207}
208
209fn bpf_probe_read_user<C: EbpfProgramContext>(
210 _context: &mut C::RunContext<'_>,
211 _: BpfValue,
212 _: BpfValue,
213 _: BpfValue,
214 _: BpfValue,
215 _: BpfValue,
216) -> BpfValue {
217 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_probe_read_user");
218 0.into()
219}
220
221fn bpf_probe_read_user_str<C: EbpfProgramContext>(
222 _context: &mut C::RunContext<'_>,
223 _: BpfValue,
224 _: BpfValue,
225 _: BpfValue,
226 _: BpfValue,
227 _: BpfValue,
228) -> BpfValue {
229 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_probe_read_user_str");
230 0.into()
231}
232
233fn bpf_ktime_get_coarse_ns<C: EbpfProgramContext>(
234 _context: &mut C::RunContext<'_>,
235 _: BpfValue,
236 _: BpfValue,
237 _: BpfValue,
238 _: BpfValue,
239 _: BpfValue,
240) -> BpfValue {
241 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_ktime_get_coarse_ns");
242 0.into()
243}
244
245fn bpf_probe_read_str<C: EbpfProgramContext>(
246 _context: &mut C::RunContext<'_>,
247 _: BpfValue,
248 _: BpfValue,
249 _: BpfValue,
250 _: BpfValue,
251 _: BpfValue,
252) -> BpfValue {
253 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_probe_read_str");
254 0.into()
255}
256
257fn bpf_get_smp_processor_id<C: EbpfProgramContext>(
258 _context: &mut C::RunContext<'_>,
259 _: BpfValue,
260 _: BpfValue,
261 _: BpfValue,
262 _: BpfValue,
263 _: BpfValue,
264) -> BpfValue {
265 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_get_smp_processor_id");
266 0.into()
267}
268
269pub trait CurrentTaskContext {
270 fn get_uid_gid(&self) -> (uid_t, gid_t);
271 fn get_tid_tgid(&self) -> (pid_t, pid_t);
272}
273
274pub trait CurrentTaskProgramContext: EbpfProgramContext {
275 fn get_uid_gid<'a>(context: &mut Self::RunContext<'a>) -> (uid_t, gid_t);
276 fn get_tid_tgid<'a>(context: &mut Self::RunContext<'a>) -> (pid_t, pid_t);
277}
278
279impl<C: EbpfProgramContext> CurrentTaskProgramContext for C
280where
281 for<'a> C::RunContext<'a>: CurrentTaskContext,
282{
283 fn get_uid_gid<'a>(context: &mut Self::RunContext<'a>) -> (uid_t, gid_t) {
284 context.get_uid_gid()
285 }
286 fn get_tid_tgid<'a>(context: &mut Self::RunContext<'a>) -> (pid_t, pid_t) {
287 context.get_tid_tgid()
288 }
289}
290
291fn bpf_get_current_uid_gid<C: CurrentTaskProgramContext>(
292 context: &mut C::RunContext<'_>,
293 _: BpfValue,
294 _: BpfValue,
295 _: BpfValue,
296 _: BpfValue,
297 _: BpfValue,
298) -> BpfValue {
299 let (uid, gid) = C::get_uid_gid(context);
300 (uid as u64 + (gid as u64) << 32).into()
301}
302
303fn bpf_get_current_pid_tgid<C: CurrentTaskProgramContext>(
304 context: &mut C::RunContext<'_>,
305 _: BpfValue,
306 _: BpfValue,
307 _: BpfValue,
308 _: BpfValue,
309 _: BpfValue,
310) -> BpfValue {
311 let (pid, tgid) = C::get_tid_tgid(context);
312 (pid as u64 + (tgid as u64) << 32).into()
313}
314
315pub trait SocketCookieContext<A> {
316 fn get_socket_cookie(&self, arg: A) -> u64;
317}
318
319pub trait SocketCookieProgramContext: EbpfProgramContext {
320 fn get_socket_cookie<'a>(context: &mut Self::RunContext<'a>, arg: BpfValue) -> u64;
321}
322
323impl<C: EbpfProgramContext> SocketCookieProgramContext for C
324where
325 for<'b, 'c> C::RunContext<'b>: SocketCookieContext<C::Arg1<'c>>,
326 for<'b> C::Arg1<'b>: FromBpfValue<C::RunContext<'b>>,
327{
328 fn get_socket_cookie<'a>(context: &mut Self::RunContext<'a>, arg: BpfValue) -> u64 {
329 let arg = unsafe { C::Arg1::from_bpf_value(context, arg) };
332 context.get_socket_cookie(arg)
333 }
334}
335
336fn bpf_get_socket_cookie<'a, C: SocketCookieProgramContext>(
337 context: &mut C::RunContext<'a>,
338 arg: BpfValue,
339 _: BpfValue,
340 _: BpfValue,
341 _: BpfValue,
342 _: BpfValue,
343) -> BpfValue {
344 C::get_socket_cookie(context, arg).into()
345}
346
347#[derive(Copy, Clone, Debug, PartialEq, Eq)]
348pub enum LoadBytesBase {
349 MacHeader,
350 NetworkHeader,
351}
352
353pub trait SocketUidContext<B> {
355 fn get_socket_uid(&self, sk_buf: B) -> Option<uid_t>;
356}
357
358pub trait SocketUidProgramContext: EbpfProgramContext {
360 fn get_socket_uid<'a>(context: &mut Self::RunContext<'a>, sk_buf: BpfValue) -> Option<uid_t>;
361}
362
363impl<C: EbpfProgramContext> SocketUidProgramContext for C
364where
365 for<'b, 'c> C::RunContext<'b>: SocketUidContext<C::Arg1<'c>>,
366 for<'b> C::Arg1<'b>: FromBpfValue<C::RunContext<'b>>,
367{
368 fn get_socket_uid<'a>(context: &mut Self::RunContext<'a>, sk_buf: BpfValue) -> Option<uid_t> {
369 let sk_buf = unsafe { C::Arg1::from_bpf_value(context, sk_buf) };
372 context.get_socket_uid(sk_buf)
373 }
374}
375
376fn bpf_get_socket_uid<'a, C: SocketUidProgramContext>(
377 context: &mut C::RunContext<'a>,
378 sk_buf: BpfValue,
379 _: BpfValue,
380 _: BpfValue,
381 _: BpfValue,
382 _: BpfValue,
383) -> BpfValue {
384 const OVERFLOW_UID: uid_t = 65534;
385 C::get_socket_uid(context, sk_buf).unwrap_or(OVERFLOW_UID).into()
386}
387
388pub trait PacketWithLoadBytes {
390 fn load_bytes_relative(&self, base: LoadBytesBase, offset: usize, buf: &mut [u8]) -> i64;
391}
392
393pub trait SkbLoadBytesProgramContext: EbpfProgramContext {
395 fn skb_load_bytes_relative<'a>(
396 context: &mut Self::RunContext<'a>,
397 sk_buf: BpfValue,
398 base: LoadBytesBase,
399 offset: usize,
400 buf: &mut [u8],
401 ) -> i64;
402}
403
404impl<C: EbpfProgramContext> SkbLoadBytesProgramContext for C
405where
406 for<'b> C::Arg1<'b>: FromBpfValue<C::RunContext<'b>>,
407 for<'b> C::Arg1<'b>: PacketWithLoadBytes,
408{
409 fn skb_load_bytes_relative<'a>(
410 context: &mut Self::RunContext<'a>,
411 sk_buf: BpfValue,
412 base: LoadBytesBase,
413 offset: usize,
414 buf: &mut [u8],
415 ) -> i64 {
416 let sk_buf = unsafe { C::Arg1::from_bpf_value(context, sk_buf) };
419 sk_buf.load_bytes_relative(base, offset, buf)
420 }
421}
422
423fn bpf_skb_load_bytes_relative<'a, C: SkbLoadBytesProgramContext>(
424 context: &mut C::RunContext<'a>,
425 sk_buf: BpfValue,
426 offset: BpfValue,
427 to: BpfValue,
428 len: BpfValue,
429 start_header: BpfValue,
430) -> BpfValue {
431 let base = match start_header.as_u32() {
432 0 => LoadBytesBase::MacHeader,
433 1 => LoadBytesBase::NetworkHeader,
434 _ => return u64::MAX.into(),
435 };
436
437 let Ok(offset) = offset.as_u64().try_into() else {
438 return u64::MAX.into();
439 };
440
441 let buf = unsafe { slice::from_raw_parts_mut(to.as_ptr::<u8>(), len.as_u64() as usize) };
444
445 C::skb_load_bytes_relative(context, sk_buf, base, offset, buf).into()
446}
447
448fn bpf_sk_storage_get<C: EbpfProgramContext>(
449 _context: &mut C::RunContext<'_>,
450 _: BpfValue,
451 _: BpfValue,
452 _: BpfValue,
453 _: BpfValue,
454 _: BpfValue,
455) -> BpfValue {
456 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_sk_storage_get");
457 0.into()
458}
459
460fn bpf_sk_fullsock<C: EbpfProgramContext>(
461 _context: &mut C::RunContext<'_>,
462 _: BpfValue,
463 _: BpfValue,
464 _: BpfValue,
465 _: BpfValue,
466 _: BpfValue,
467) -> BpfValue {
468 track_stub!(TODO("https://fxbug.dev/287120494"), "bpf_sk_fullsock");
469 0.into()
470}
471
472pub trait ReturnValueContext {
473 fn set_retval(&mut self, value: i32) -> i32;
474 fn get_retval(&self) -> i32;
475}
476
477pub trait ReturnValueProgramContext: EbpfProgramContext {
478 fn set_retval<'a>(context: &mut Self::RunContext<'a>, value: i32) -> i32;
479 fn get_retval<'a>(context: &mut Self::RunContext<'a>) -> i32;
480}
481
482impl<C: EbpfProgramContext> ReturnValueProgramContext for C
483where
484 for<'a> C::RunContext<'a>: ReturnValueContext,
485{
486 fn set_retval<'a>(context: &mut Self::RunContext<'a>, value: i32) -> i32 {
487 context.set_retval(value)
488 }
489 fn get_retval<'a>(context: &mut Self::RunContext<'a>) -> i32 {
490 context.get_retval()
491 }
492}
493
494fn bpf_set_retval<C: ReturnValueProgramContext>(
495 context: &mut C::RunContext<'_>,
496 value: BpfValue,
497 _: BpfValue,
498 _: BpfValue,
499 _: BpfValue,
500 _: BpfValue,
501) -> BpfValue {
502 C::set_retval(context, value.as_i32()).into()
503}
504
505fn bpf_get_retval<C: ReturnValueProgramContext>(
506 context: &mut C::RunContext<'_>,
507 _: BpfValue,
508 _: BpfValue,
509 _: BpfValue,
510 _: BpfValue,
511 _: BpfValue,
512) -> BpfValue {
513 C::get_retval(context).into()
514}
515
516fn get_common_helpers<C: MapsProgramContext>() -> impl Iterator<Item = (u32, EbpfHelperImpl<C>)> {
517 [
518 (bpf_func_id_BPF_FUNC_ktime_get_boot_ns, EbpfHelperImpl(bpf_ktime_get_boot_ns)),
519 (bpf_func_id_BPF_FUNC_ktime_get_coarse_ns, EbpfHelperImpl(bpf_ktime_get_coarse_ns)),
520 (bpf_func_id_BPF_FUNC_ktime_get_ns, EbpfHelperImpl(bpf_ktime_get_ns)),
521 (bpf_func_id_BPF_FUNC_map_delete_elem, EbpfHelperImpl(bpf_map_delete_elem)),
522 (bpf_func_id_BPF_FUNC_map_lookup_elem, EbpfHelperImpl(bpf_map_lookup_elem)),
523 (bpf_func_id_BPF_FUNC_map_update_elem, EbpfHelperImpl(bpf_map_update_elem)),
524 (bpf_func_id_BPF_FUNC_probe_read_str, EbpfHelperImpl(bpf_probe_read_str)),
525 (bpf_func_id_BPF_FUNC_probe_read_user, EbpfHelperImpl(bpf_probe_read_user)),
526 (bpf_func_id_BPF_FUNC_probe_read_user_str, EbpfHelperImpl(bpf_probe_read_user_str)),
527 (bpf_func_id_BPF_FUNC_ringbuf_discard, EbpfHelperImpl(bpf_ringbuf_discard)),
528 (bpf_func_id_BPF_FUNC_ringbuf_reserve, EbpfHelperImpl(bpf_ringbuf_reserve)),
529 (bpf_func_id_BPF_FUNC_ringbuf_submit, EbpfHelperImpl(bpf_ringbuf_submit)),
530 (bpf_func_id_BPF_FUNC_trace_printk, EbpfHelperImpl(bpf_trace_printk)),
531 (bpf_func_id_BPF_FUNC_get_smp_processor_id, EbpfHelperImpl(bpf_get_smp_processor_id)),
532 ]
533 .into_iter()
534}
535
536fn get_current_task_helpers<C: CurrentTaskProgramContext>()
538-> impl Iterator<Item = (u32, EbpfHelperImpl<C>)> {
539 [
540 (bpf_func_id_BPF_FUNC_get_current_uid_gid, EbpfHelperImpl(bpf_get_current_uid_gid)),
541 (bpf_func_id_BPF_FUNC_get_current_pid_tgid, EbpfHelperImpl(bpf_get_current_pid_tgid)),
542 ]
543 .into_iter()
544}
545
546pub trait CgroupSockProgramContext:
549 MapsProgramContext + SocketCookieProgramContext + CurrentTaskProgramContext
550{
551 fn get_helpers() -> HelperSet<Self> {
552 [
553 (bpf_func_id_BPF_FUNC_get_socket_cookie, EbpfHelperImpl(bpf_get_socket_cookie)),
554 (bpf_func_id_BPF_FUNC_sk_storage_get, EbpfHelperImpl(bpf_sk_storage_get)),
555 ]
556 .into_iter()
557 .chain(get_common_helpers())
558 .chain(get_current_task_helpers())
559 .collect()
560 }
561}
562
563pub trait CgroupSockAddrProgramContext:
566 MapsProgramContext + SocketCookieProgramContext + CurrentTaskProgramContext
567{
568 fn get_helpers() -> HelperSet<Self> {
569 [
570 (bpf_func_id_BPF_FUNC_get_socket_cookie, EbpfHelperImpl(bpf_get_socket_cookie)),
571 (bpf_func_id_BPF_FUNC_sk_storage_get, EbpfHelperImpl(bpf_sk_storage_get)),
572 ]
573 .into_iter()
574 .chain(get_common_helpers())
575 .chain(get_current_task_helpers())
576 .collect()
577 }
578}
579
580pub trait CgroupSockOptProgramContext:
583 MapsProgramContext + CurrentTaskProgramContext + ReturnValueProgramContext
584{
585 fn get_helpers() -> HelperSet<Self> {
586 [
587 (bpf_func_id_BPF_FUNC_set_retval, EbpfHelperImpl(bpf_set_retval)),
588 (bpf_func_id_BPF_FUNC_get_retval, EbpfHelperImpl(bpf_get_retval)),
589 ]
590 .into_iter()
591 .chain(get_common_helpers())
592 .chain(get_current_task_helpers())
593 .collect()
594 }
595}
596
597pub trait SocketFilterProgramContext:
600 MapsProgramContext
601 + SocketUidProgramContext
602 + SocketCookieProgramContext
603 + SkbLoadBytesProgramContext
604{
605 fn get_helpers() -> HelperSet<Self> {
606 vec![
607 (bpf_func_id_BPF_FUNC_get_socket_uid, EbpfHelperImpl(bpf_get_socket_uid)),
608 (bpf_func_id_BPF_FUNC_get_socket_cookie, EbpfHelperImpl(bpf_get_socket_cookie)),
609 (
610 bpf_func_id_BPF_FUNC_skb_load_bytes_relative,
611 EbpfHelperImpl(bpf_skb_load_bytes_relative),
612 ),
613 ]
614 .into_iter()
615 .chain(get_common_helpers())
616 .collect()
617 }
618}
619
620pub trait CgroupSkbProgramContext:
623 MapsProgramContext
624 + SocketUidProgramContext
625 + SocketCookieProgramContext
626 + SkbLoadBytesProgramContext
627{
628 fn get_helpers() -> HelperSet<Self> {
629 vec![
630 (bpf_func_id_BPF_FUNC_get_socket_uid, EbpfHelperImpl(bpf_get_socket_uid)),
631 (bpf_func_id_BPF_FUNC_get_socket_cookie, EbpfHelperImpl(bpf_get_socket_cookie)),
632 (
633 bpf_func_id_BPF_FUNC_skb_load_bytes_relative,
634 EbpfHelperImpl(bpf_skb_load_bytes_relative),
635 ),
636 (bpf_func_id_BPF_FUNC_sk_storage_get, EbpfHelperImpl(bpf_sk_storage_get)),
637 (bpf_func_id_BPF_FUNC_sk_fullsock, EbpfHelperImpl(bpf_sk_fullsock)),
638 ]
639 .into_iter()
640 .chain(get_common_helpers())
641 .collect()
642 }
643}
644
645#[macro_export]
657macro_rules! ebpf_program_context_type {
658 ($context:ty, $subtrait:ty) => {
659 impl $subtrait for $context {}
660 ebpf::static_helper_set!($context, <$context as $subtrait>::get_helpers());
661 };
662}