air_sys_types/ebpf.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Types purs de la famille `ebpf` (couche 0).
6//!
7//! Cf. `docs/specs/layer-0/family-ebpf.md`. Ce module ne fait **aucun**
8//! syscall : il décrit le miroir d'instruction `BpfInstruction`, les
9//! énumérations typées (`BpfMapType`, `BpfProgramType`, `BpfAttachType`…), les
10//! bitflags, le miroir `PerfEventAttr`, les portées `PerfEventScope`, et les
11//! structs-requête passées aux wrappers de `air-sys-syscall::ebpf`.
12//!
13//! Frontière couche 0/1 : on **charge** des programmes/BTF déjà assemblés ; on
14//! n'assemble, ne compile, ni ne relocalise rien (logique → couche 1).
15
16use core::ffi::CStr;
17
18use bitflags::bitflags;
19
20use crate::fd::BorrowedFd;
21use crate::process::Pid;
22
23// ─────────────────────────────────────────────────────────────────────────
24// Instruction.
25// ─────────────────────────────────────────────────────────────────────────
26
27/// Miroir `#[repr(C)]` de `struct bpf_insn` (8 octets).
28///
29/// Type « miroir » : nom de type explicite (ADR-029), champs aux noms kernel.
30#[repr(C)]
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
32pub struct BpfInstruction {
33 /// Opcode.
34 pub code: u8,
35 /// 4 bits `dst_reg` (poids faible) + 4 bits `src_reg` (poids fort).
36 pub registers: u8,
37 /// Décalage signé (saut, accès mémoire).
38 pub offset: i16,
39 /// Immédiat 32 bits.
40 pub immediate: i32,
41}
42
43impl BpfInstruction {
44 /// Construit une instruction depuis ses champs.
45 #[must_use]
46 pub const fn new(code: u8, dst_reg: u8, src_reg: u8, offset: i16, immediate: i32) -> Self {
47 let registers = (dst_reg & 0x0f) | ((src_reg & 0x0f) << 4);
48 Self {
49 code,
50 registers,
51 offset,
52 immediate,
53 }
54 }
55
56 /// Registre destination (4 bits de poids faible de `registers`).
57 #[must_use]
58 pub const fn dst_reg(self) -> u8 {
59 self.registers & 0x0f
60 }
61
62 /// Registre source (4 bits de poids fort de `registers`).
63 #[must_use]
64 pub const fn src_reg(self) -> u8 {
65 self.registers >> 4
66 }
67}
68
69// ─────────────────────────────────────────────────────────────────────────
70// Énumérations typées.
71// ─────────────────────────────────────────────────────────────────────────
72
73/// `enum bpf_map_type`. Variante `Other(u32)` pour les types non nommés.
74#[derive(Debug, Clone, Copy, PartialEq, Eq)]
75#[allow(missing_docs)]
76pub enum BpfMapType {
77 Hash,
78 Array,
79 ProgramArray,
80 PerfEventArray,
81 PercpuHash,
82 PercpuArray,
83 StackTrace,
84 CgroupArray,
85 LruHash,
86 LruPercpuHash,
87 LpmTrie,
88 ArrayOfMaps,
89 HashOfMaps,
90 DevMap,
91 SockMap,
92 Cpumap,
93 XskMap,
94 SockHash,
95 CgroupStorage,
96 ReuseportSockArray,
97 PercpuCgroupStorage,
98 Queue,
99 Stack,
100 SkStorage,
101 DevmapHash,
102 StructOps,
103 RingBuf,
104 InodeStorage,
105 TaskStorage,
106 BloomFilter,
107 UserRingBuf,
108 CgrpStorage,
109 Arena,
110 /// Type ajouté par un kernel postérieur à 6.12.
111 Other(u32),
112}
113
114impl BpfMapType {
115 /// Valeur kernel `BPF_MAP_TYPE_*`.
116 #[must_use]
117 pub const fn to_raw(self) -> u32 {
118 match self {
119 Self::Hash => 1,
120 Self::Array => 2,
121 Self::ProgramArray => 3,
122 Self::PerfEventArray => 4,
123 Self::PercpuHash => 5,
124 Self::PercpuArray => 6,
125 Self::StackTrace => 7,
126 Self::CgroupArray => 8,
127 Self::LruHash => 9,
128 Self::LruPercpuHash => 10,
129 Self::LpmTrie => 11,
130 Self::ArrayOfMaps => 12,
131 Self::HashOfMaps => 13,
132 Self::DevMap => 14,
133 Self::SockMap => 15,
134 Self::Cpumap => 16,
135 Self::XskMap => 17,
136 Self::SockHash => 18,
137 Self::CgroupStorage => 19,
138 Self::ReuseportSockArray => 20,
139 Self::PercpuCgroupStorage => 21,
140 Self::Queue => 22,
141 Self::Stack => 23,
142 Self::SkStorage => 24,
143 Self::DevmapHash => 25,
144 Self::StructOps => 26,
145 Self::RingBuf => 27,
146 Self::InodeStorage => 28,
147 Self::TaskStorage => 29,
148 Self::BloomFilter => 30,
149 Self::UserRingBuf => 31,
150 Self::CgrpStorage => 32,
151 Self::Arena => 33,
152 Self::Other(value) => value,
153 }
154 }
155}
156
157/// `enum bpf_prog_type`. Variante `Other(u32)` de repli.
158#[derive(Debug, Clone, Copy, PartialEq, Eq)]
159#[allow(missing_docs)]
160pub enum BpfProgramType {
161 SocketFilter,
162 Kprobe,
163 SchedCls,
164 SchedAct,
165 Tracepoint,
166 Xdp,
167 PerfEvent,
168 CgroupSkb,
169 CgroupSock,
170 LwtIn,
171 LwtOut,
172 LwtXmit,
173 SockOps,
174 SkSkb,
175 CgroupDevice,
176 SkMsg,
177 RawTracepoint,
178 CgroupSockAddr,
179 LwtSeg6local,
180 LircMode2,
181 SkReuseport,
182 FlowDissector,
183 CgroupSysctl,
184 RawTracepointWritable,
185 CgroupSockopt,
186 Tracing,
187 StructOps,
188 Ext,
189 Lsm,
190 SkLookup,
191 Syscall,
192 Netfilter,
193 /// Type ajouté par un kernel postérieur à 6.12.
194 Other(u32),
195}
196
197impl BpfProgramType {
198 /// Valeur kernel `BPF_PROG_TYPE_*`.
199 #[must_use]
200 pub const fn to_raw(self) -> u32 {
201 match self {
202 Self::SocketFilter => 1,
203 Self::Kprobe => 2,
204 Self::SchedCls => 3,
205 Self::SchedAct => 4,
206 Self::Tracepoint => 5,
207 Self::Xdp => 6,
208 Self::PerfEvent => 7,
209 Self::CgroupSkb => 8,
210 Self::CgroupSock => 9,
211 Self::LwtIn => 10,
212 Self::LwtOut => 11,
213 Self::LwtXmit => 12,
214 Self::SockOps => 13,
215 Self::SkSkb => 14,
216 Self::CgroupDevice => 15,
217 Self::SkMsg => 16,
218 Self::RawTracepoint => 17,
219 Self::CgroupSockAddr => 18,
220 Self::LwtSeg6local => 19,
221 Self::LircMode2 => 20,
222 Self::SkReuseport => 21,
223 Self::FlowDissector => 22,
224 Self::CgroupSysctl => 23,
225 Self::RawTracepointWritable => 24,
226 Self::CgroupSockopt => 25,
227 Self::Tracing => 26,
228 Self::StructOps => 27,
229 Self::Ext => 28,
230 Self::Lsm => 29,
231 Self::SkLookup => 30,
232 Self::Syscall => 31,
233 Self::Netfilter => 32,
234 Self::Other(value) => value,
235 }
236 }
237}
238
239/// `enum bpf_attach_type` (sous-ensemble typé + repli).
240#[derive(Debug, Clone, Copy, PartialEq, Eq)]
241#[allow(missing_docs)]
242pub enum BpfAttachType {
243 CgroupInetIngress,
244 CgroupInetEgress,
245 CgroupInetSockCreate,
246 CgroupSockOps,
247 SkSkbStreamParser,
248 SkSkbStreamVerdict,
249 CgroupDevice,
250 SkMsgVerdict,
251 CgroupInet4Bind,
252 CgroupInet6Bind,
253 CgroupInet4Connect,
254 CgroupInet6Connect,
255 TraceFentry,
256 TraceFexit,
257 ModifyReturn,
258 LsmMac,
259 TraceIter,
260 XdpDevmap,
261 XdpCpumap,
262 SkLookup,
263 Xdp,
264 /// Type d'attache ajouté par un kernel postérieur à 6.12.
265 Other(u32),
266}
267
268impl BpfAttachType {
269 /// Valeur kernel `BPF_*` (`bpf_attach_type`).
270 #[must_use]
271 pub const fn to_raw(self) -> u32 {
272 match self {
273 Self::CgroupInetIngress => 0,
274 Self::CgroupInetEgress => 1,
275 Self::CgroupInetSockCreate => 2,
276 Self::CgroupSockOps => 3,
277 Self::SkSkbStreamParser => 4,
278 Self::SkSkbStreamVerdict => 5,
279 Self::CgroupDevice => 6,
280 Self::SkMsgVerdict => 7,
281 Self::CgroupInet4Bind => 8,
282 Self::CgroupInet6Bind => 9,
283 Self::CgroupInet4Connect => 10,
284 Self::CgroupInet6Connect => 11,
285 Self::TraceFentry => 24,
286 Self::TraceFexit => 25,
287 Self::ModifyReturn => 26,
288 Self::LsmMac => 27,
289 Self::TraceIter => 28,
290 Self::XdpDevmap => 33,
291 Self::XdpCpumap => 35,
292 Self::SkLookup => 36,
293 Self::Xdp => 37,
294 Self::Other(value) => value,
295 }
296 }
297}
298
299/// Type de statistiques `BPF_ENABLE_STATS`.
300#[derive(Debug, Clone, Copy, PartialEq, Eq)]
301pub enum BpfStatsType {
302 /// `BPF_STATS_RUN_TIME` — temps CPU passé dans les programmes.
303 RunTime,
304}
305
306impl BpfStatsType {
307 /// Valeur kernel `BPF_STATS_*`.
308 #[must_use]
309 pub const fn to_raw(self) -> u32 {
310 match self {
311 Self::RunTime => 0,
312 }
313 }
314}
315
316/// Niveau de verbosité du log du vérifieur (`log_level`).
317#[derive(Debug, Clone, Copy, PartialEq, Eq)]
318pub enum BpfVerifierLogLevel {
319 /// Aucun log.
320 Disabled,
321 /// Log de base (`BPF_LOG_LEVEL1`).
322 Basic,
323 /// Log détaillé (`BPF_LOG_LEVEL2`).
324 Verbose,
325 /// Statistiques (`BPF_LOG_STATS`).
326 Stats,
327}
328
329impl BpfVerifierLogLevel {
330 /// Bits `log_level` kernel.
331 #[must_use]
332 pub const fn to_raw(self) -> u32 {
333 match self {
334 Self::Disabled => 0,
335 Self::Basic => 1,
336 Self::Verbose => 2,
337 Self::Stats => 4,
338 }
339 }
340}
341
342// ─────────────────────────────────────────────────────────────────────────
343// Bitflags.
344// ─────────────────────────────────────────────────────────────────────────
345
346bitflags! {
347 /// Drapeaux de création de carte (`BPF_F_*`).
348 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
349 pub struct BpfMapCreateFlags: u32 {
350 /// `BPF_F_NO_PREALLOC`.
351 const NO_PREALLOC = 1 << 0;
352 /// `BPF_F_NO_COMMON_LRU`.
353 const NO_COMMON_LRU = 1 << 1;
354 /// `BPF_F_NUMA_NODE`.
355 const NUMA_NODE = 1 << 2;
356 /// `BPF_F_RDONLY`.
357 const READ_ONLY = 1 << 3;
358 /// `BPF_F_WRONLY`.
359 const WRITE_ONLY = 1 << 4;
360 /// `BPF_F_STACK_BUILD_ID`.
361 const STACK_BUILD_ID = 1 << 5;
362 /// `BPF_F_ZERO_SEED`.
363 const ZERO_SEED = 1 << 6;
364 /// `BPF_F_RDONLY_PROG`.
365 const READ_ONLY_PROG = 1 << 7;
366 /// `BPF_F_WRONLY_PROG`.
367 const WRITE_ONLY_PROG = 1 << 8;
368 /// `BPF_F_CLONE`.
369 const CLONE = 1 << 9;
370 /// `BPF_F_MMAPABLE`.
371 const MMAPABLE = 1 << 10;
372 /// `BPF_F_PRESERVE_ELEMS`.
373 const PRESERVE_ELEMS = 1 << 11;
374 /// `BPF_F_INNER_MAP`.
375 const INNER_LOCK = 1 << 12;
376 }
377}
378
379bitflags! {
380 /// Drapeaux de mise à jour d'élément (`BPF_*`).
381 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
382 pub struct BpfMapUpdateFlags: u64 {
383 /// `BPF_ANY` — créer ou remplacer.
384 const ANY = 0;
385 /// `BPF_NOEXIST` — créer seulement si absent.
386 const NO_EXIST = 1;
387 /// `BPF_EXIST` — remplacer seulement si présent.
388 const EXIST = 2;
389 /// `BPF_F_LOCK` — verrou spin de l'entrée.
390 const F_LOCK = 4;
391 }
392}
393
394bitflags! {
395 /// Drapeaux de lookup d'élément (`BPF_F_*`).
396 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
397 pub struct BpfMapLookupFlags: u64 {
398 /// `BPF_F_LOCK`.
399 const F_LOCK = 4;
400 }
401}
402
403bitflags! {
404 /// Drapeaux de chargement de programme (`BPF_F_*`).
405 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
406 pub struct BpfProgramLoadFlags: u32 {
407 /// `BPF_F_STRICT_ALIGNMENT`.
408 const STRICT_ALIGNMENT = 1 << 0;
409 /// `BPF_F_ANY_ALIGNMENT`.
410 const ANY_ALIGNMENT = 1 << 1;
411 /// `BPF_F_TEST_RND_HI32`.
412 const TEST_RND_HI32 = 1 << 2;
413 /// `BPF_F_TEST_STATE_FREQ`.
414 const TEST_STATE_FREQ = 1 << 3;
415 /// `BPF_F_SLEEPABLE`.
416 const SLEEPABLE = 1 << 4;
417 /// `BPF_F_XDP_HAS_FRAGS`.
418 const XDP_HAS_FRAGS = 1 << 5;
419 }
420}
421
422bitflags! {
423 /// Drapeaux d'attache historique (`BPF_F_*`).
424 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
425 pub struct BpfAttachFlags: u32 {
426 /// `BPF_F_ALLOW_OVERRIDE`.
427 const ALLOW_OVERRIDE = 1 << 0;
428 /// `BPF_F_ALLOW_MULTI`.
429 const ALLOW_MULTI = 1 << 1;
430 /// `BPF_F_REPLACE`.
431 const REPLACE = 1 << 2;
432 }
433}
434
435bitflags! {
436 /// Drapeaux de récupération d'objet épinglé (`BPF_F_*`).
437 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
438 pub struct BpfObjectGetFlags: u32 {
439 /// `BPF_F_RDONLY`.
440 const RDONLY = 1 << 3;
441 /// `BPF_F_WRONLY`.
442 const WRONLY = 1 << 4;
443 }
444}
445
446bitflags! {
447 /// Drapeaux de chargement BTF (`BPF_F_*`).
448 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
449 pub struct BpfBtfLoadFlags: u32 {
450 /// `BPF_F_TOKEN_FD`.
451 const TOKEN_FD = 1 << 0;
452 }
453}
454
455bitflags! {
456 /// Drapeaux de `perf_event_open` (`PERF_FLAG_*`).
457 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
458 pub struct PerfEventOpenFlags: u64 {
459 /// `PERF_FLAG_FD_NO_GROUP`.
460 const FD_NO_GROUP = 1 << 0;
461 /// `PERF_FLAG_FD_OUTPUT`.
462 const FD_OUTPUT = 1 << 1;
463 /// `PERF_FLAG_FD_CLOEXEC` (toujours posé par le wrapper).
464 const FD_CLOEXEC = 1 << 3;
465 }
466}
467
468// ─────────────────────────────────────────────────────────────────────────
469// perf_event — type/config et miroir d'attributs.
470// ─────────────────────────────────────────────────────────────────────────
471
472/// Valeurs courantes du champ `perf_event_attr.type` (`PERF_TYPE_*`).
473#[derive(Debug, Clone, Copy, PartialEq, Eq)]
474pub enum PerfTypeId {
475 /// `PERF_TYPE_HARDWARE`.
476 Hardware,
477 /// `PERF_TYPE_SOFTWARE`.
478 Software,
479 /// `PERF_TYPE_TRACEPOINT`.
480 Tracepoint,
481 /// `PERF_TYPE_HW_CACHE`.
482 HwCache,
483 /// `PERF_TYPE_RAW`.
484 Raw,
485 /// `PERF_TYPE_BREAKPOINT`.
486 Breakpoint,
487}
488
489impl PerfTypeId {
490 /// Valeur kernel `PERF_TYPE_*`.
491 #[must_use]
492 pub const fn to_raw(self) -> u32 {
493 match self {
494 Self::Hardware => 0,
495 Self::Software => 1,
496 Self::Tracepoint => 2,
497 Self::HwCache => 3,
498 Self::Raw => 4,
499 Self::Breakpoint => 5,
500 }
501 }
502}
503
504/// Compteurs matériels courants (`PERF_COUNT_HW_*`), champ `config`.
505#[derive(Debug, Clone, Copy, PartialEq, Eq)]
506pub enum PerfHardwareCounter {
507 /// `PERF_COUNT_HW_CPU_CYCLES`.
508 CpuCycles,
509 /// `PERF_COUNT_HW_INSTRUCTIONS`.
510 Instructions,
511 /// `PERF_COUNT_HW_CACHE_REFERENCES`.
512 CacheReferences,
513 /// `PERF_COUNT_HW_CACHE_MISSES`.
514 CacheMisses,
515 /// `PERF_COUNT_HW_BRANCH_INSTRUCTIONS`.
516 BranchInstructions,
517 /// `PERF_COUNT_HW_BRANCH_MISSES`.
518 BranchMisses,
519 /// `PERF_COUNT_HW_BUS_CYCLES`.
520 BusCycles,
521 /// `PERF_COUNT_HW_REF_CPU_CYCLES`.
522 RefCpuCycles,
523}
524
525impl PerfHardwareCounter {
526 /// Valeur kernel `PERF_COUNT_HW_*`.
527 #[must_use]
528 pub const fn to_raw(self) -> u64 {
529 match self {
530 Self::CpuCycles => 0,
531 Self::Instructions => 1,
532 Self::CacheReferences => 2,
533 Self::CacheMisses => 3,
534 Self::BranchInstructions => 4,
535 Self::BranchMisses => 5,
536 Self::BusCycles => 6,
537 Self::RefCpuCycles => 9,
538 }
539 }
540}
541
542/// Compteurs logiciels courants (`PERF_COUNT_SW_*`), champ `config`.
543#[derive(Debug, Clone, Copy, PartialEq, Eq)]
544pub enum PerfSoftwareCounter {
545 /// `PERF_COUNT_SW_CPU_CLOCK`.
546 CpuClock,
547 /// `PERF_COUNT_SW_TASK_CLOCK`.
548 TaskClock,
549 /// `PERF_COUNT_SW_PAGE_FAULTS`.
550 PageFaults,
551 /// `PERF_COUNT_SW_CONTEXT_SWITCHES`.
552 ContextSwitches,
553 /// `PERF_COUNT_SW_CPU_MIGRATIONS`.
554 CpuMigrations,
555}
556
557impl PerfSoftwareCounter {
558 /// Valeur kernel `PERF_COUNT_SW_*`.
559 #[must_use]
560 pub const fn to_raw(self) -> u64 {
561 match self {
562 Self::CpuClock => 0,
563 Self::TaskClock => 1,
564 Self::PageFaults => 2,
565 Self::ContextSwitches => 3,
566 Self::CpuMigrations => 4,
567 }
568 }
569}
570
571/// Miroir `#[repr(C)]` de `struct perf_event_attr` (136 octets, ver. 6.12).
572///
573/// Champs aux noms kernel ; `Default` (tout à zéro) est un attribut valide.
574/// Le champ `flags` agrège les bitfields kernel (`disabled`, `inherit`,
575/// `exclude_kernel`…) — voir les constantes associées. Un builder ergonomique
576/// relève de la couche 1.
577#[repr(C)]
578#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
579pub struct PerfEventAttr {
580 /// `type` — famille de l'événement (`PERF_TYPE_*`).
581 pub kind: u32,
582 /// `size` — taille de la structure (renseignée par le wrapper).
583 pub size: u32,
584 /// `config` — événement précis dans la famille.
585 pub config: u64,
586 /// `sample_period` / `sample_freq`.
587 pub sample_period_or_freq: u64,
588 /// `sample_type` — champs échantillonnés (`PERF_SAMPLE_*`).
589 pub sample_type: u64,
590 /// `read_format` — format de lecture (`PERF_FORMAT_*`).
591 pub read_format: u64,
592 /// Bitfields agrégés (`disabled`, `inherit`, `exclude_kernel`…).
593 pub flags: u64,
594 /// `wakeup_events` / `wakeup_watermark`.
595 pub wakeup: u32,
596 /// `bp_type`.
597 pub bp_type: u32,
598 /// `bp_addr` / `config1`.
599 pub config1: u64,
600 /// `bp_len` / `config2`.
601 pub config2: u64,
602 /// `branch_sample_type`.
603 pub branch_sample_type: u64,
604 /// `sample_regs_user`.
605 pub sample_regs_user: u64,
606 /// `sample_stack_user`.
607 pub sample_stack_user: u32,
608 /// `clockid`.
609 pub clockid: i32,
610 /// `sample_regs_intr`.
611 pub sample_regs_intr: u64,
612 /// `aux_watermark`.
613 pub aux_watermark: u32,
614 /// `sample_max_stack`.
615 pub sample_max_stack: u16,
616 /// `__reserved_2`.
617 pub reserved_2: u16,
618 /// `aux_sample_size`.
619 pub aux_sample_size: u32,
620 /// `__reserved_3`.
621 pub reserved_3: u32,
622 /// `sig_data`.
623 pub sig_data: u64,
624 /// `config3`.
625 pub config3: u64,
626}
627
628impl PerfEventAttr {
629 /// `disabled:1` — démarre désactivé.
630 pub const FLAG_DISABLED: u64 = 1 << 0;
631 /// `inherit:1` — hérité par les tâches filles.
632 pub const FLAG_INHERIT: u64 = 1 << 1;
633 /// `pinned:1`.
634 pub const FLAG_PINNED: u64 = 1 << 2;
635 /// `exclusive:1`.
636 pub const FLAG_EXCLUSIVE: u64 = 1 << 3;
637 /// `exclude_user:1`.
638 pub const FLAG_EXCLUDE_USER: u64 = 1 << 4;
639 /// `exclude_kernel:1`.
640 pub const FLAG_EXCLUDE_KERNEL: u64 = 1 << 5;
641 /// `exclude_hv:1`.
642 pub const FLAG_EXCLUDE_HV: u64 = 1 << 6;
643 /// `exclude_idle:1`.
644 pub const FLAG_EXCLUDE_IDLE: u64 = 1 << 7;
645}
646
647/// Portée d'un `perf_event_open` : `pid`/`cpu` sans sentinelle `-1`.
648#[derive(Debug, Clone, Copy)]
649pub enum PerfEventScope<'a> {
650 /// Processus courant, n'importe quel CPU (`pid=0, cpu=-1`).
651 CallingProcessAnyCpu,
652 /// Processus courant sur un CPU précis (`pid=0, cpu=N`).
653 CallingProcessOnCpu(u32),
654 /// Un processus précis, n'importe quel CPU (`pid=P, cpu=-1`).
655 ProcessAnyCpu(Pid),
656 /// Un processus précis sur un CPU précis.
657 ProcessOnCpu {
658 /// PID cible.
659 process: Pid,
660 /// CPU cible.
661 cpu: u32,
662 },
663 /// Tous les processus sur un CPU (`pid=-1, cpu=N`).
664 AllProcessesOnCpu(u32),
665 /// Surveillance par cgroup (`flags |= PID_CGROUP`, `pid = cgroup_fd`).
666 Cgroup {
667 /// FD du cgroup à surveiller.
668 cgroup: BorrowedFd<'a>,
669 /// CPU cible.
670 cpu: u32,
671 },
672}
673
674// ─────────────────────────────────────────────────────────────────────────
675// Structs-requête (agrégats purs passés aux wrappers).
676// ─────────────────────────────────────────────────────────────────────────
677
678/// Infos BTF optionnelles pour une carte (clé/valeur typées).
679#[derive(Debug, Clone, Copy)]
680pub struct BpfMapBtfInfo<'a> {
681 /// FD de l'objet BTF décrivant les types.
682 pub btf_fd: BorrowedFd<'a>,
683 /// Id du type de clé dans le BTF.
684 pub key_type_id: u32,
685 /// Id du type de valeur dans le BTF.
686 pub value_type_id: u32,
687}
688
689/// Requête de création de carte (`BPF_MAP_CREATE`).
690#[derive(Debug, Clone, Copy)]
691pub struct BpfMapCreateRequest<'a> {
692 /// Type de carte.
693 pub map_type: BpfMapType,
694 /// Taille de clé en octets.
695 pub key_size: u32,
696 /// Taille de valeur en octets.
697 pub value_size: u32,
698 /// Nombre maximal d'entrées.
699 pub max_entries: u32,
700 /// Drapeaux de création.
701 pub flags: BpfMapCreateFlags,
702 /// Nom (≤ 15 octets utiles + NUL) ou `None` (anonyme).
703 pub name: Option<&'a CStr>,
704 /// Pour map-of-maps : le gabarit de carte interne.
705 pub inner_map: Option<BorrowedFd<'a>>,
706 /// Nœud NUMA préféré.
707 pub numa_node: Option<u32>,
708 /// Infos BTF optionnelles.
709 pub btf: Option<BpfMapBtfInfo<'a>>,
710}
711
712/// Requête de chargement de programme (`BPF_PROG_LOAD`).
713#[derive(Debug, Clone, Copy)]
714pub struct BpfProgramLoadRequest<'a> {
715 /// Type de programme.
716 pub program_type: BpfProgramType,
717 /// Programme **déjà assemblé**.
718 pub instructions: &'a [BpfInstruction],
719 /// Licence (`GPL`, `Dual BSD/GPL`…).
720 pub license: &'a CStr,
721 /// Nom du programme (introspection).
722 pub name: Option<&'a CStr>,
723 /// Type d'attache attendu.
724 pub expected_attach_type: Option<BpfAttachType>,
725 /// BTF cible (fentry/fexit/LSM/tracing).
726 pub attach_btf: Option<BorrowedFd<'a>>,
727 /// Id du point d'attache dans le BTF cible.
728 pub attach_btf_id: Option<u32>,
729 /// Programme à étendre (`Ext` / freplace).
730 pub attach_program: Option<BorrowedFd<'a>>,
731 /// Drapeaux de chargement.
732 pub flags: BpfProgramLoadFlags,
733 /// Verbosité du vérifieur.
734 pub log_level: BpfVerifierLogLevel,
735}
736
737/// Requête de création de lien moderne (`BPF_LINK_CREATE`).
738#[derive(Debug, Clone, Copy)]
739pub struct BpfLinkCreateRequest<'a> {
740 /// Programme à attacher.
741 pub program: BorrowedFd<'a>,
742 /// Cible (cgroup, ifindex encodé, BTF…) ; `None` pour les attaches sans
743 /// FD cible (tracing).
744 pub target: Option<BorrowedFd<'a>>,
745 /// Type d'attache.
746 pub attach_type: BpfAttachType,
747 /// Drapeaux (selon le type d'attache).
748 pub flags: u32,
749}
750
751/// Requête d'exécution de test (`BPF_PROG_TEST_RUN`).
752#[derive(Debug)]
753pub struct BpfProgramTestRunRequest<'a> {
754 /// Données d'entrée fournies au programme.
755 pub data_in: &'a [u8],
756 /// Tampon de sortie (rempli par le kernel).
757 pub data_out: &'a mut [u8],
758 /// Contexte d'entrée optionnel.
759 pub context_in: &'a [u8],
760 /// Tampon de contexte de sortie optionnel.
761 pub context_out: &'a mut [u8],
762 /// Nombre de répétitions.
763 pub repeat: u32,
764 /// Drapeaux.
765 pub flags: u32,
766}
767
768/// Résultat d'une exécution de test.
769#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
770pub struct BpfProgramTestRunResult {
771 /// Valeur de retour du programme.
772 pub return_value: u32,
773 /// Durée moyenne d'exécution (ns).
774 pub duration: u32,
775 /// Octets de données de sortie effectivement écrits.
776 pub data_size_out: u32,
777 /// Octets de contexte de sortie effectivement écrits.
778 pub context_size_out: u32,
779}
780
781/// Requête d'opération batch en lecture (`BPF_MAP_LOOKUP_BATCH`…).
782#[derive(Debug)]
783pub struct BpfMapBatchRequest<'a> {
784 /// Curseur d'entrée opaque (`None` = début).
785 pub in_batch: Option<u64>,
786 /// Curseur de sortie opaque, écrit par le kernel.
787 pub out_batch: u64,
788 /// Tampon de clés.
789 pub keys: &'a mut [u8],
790 /// Tampon de valeurs.
791 pub values: &'a mut [u8],
792 /// Nombre d'éléments demandés.
793 pub count: u32,
794 /// Drapeaux élément.
795 pub elem_flags: u64,
796 /// Drapeaux opération.
797 pub flags: u64,
798}
799
800/// Requête d'opération batch en écriture (`BPF_MAP_UPDATE_BATCH`…).
801#[derive(Debug, Clone, Copy)]
802pub struct BpfMapBatchInput<'a> {
803 /// Tampon de clés.
804 pub keys: &'a [u8],
805 /// Tampon de valeurs (vide pour `delete_batch`).
806 pub values: &'a [u8],
807 /// Nombre d'éléments.
808 pub count: u32,
809 /// Drapeaux élément.
810 pub elem_flags: u64,
811 /// Drapeaux opération.
812 pub flags: u64,
813}
814
815/// Requête d'interrogation des programmes attachés (`BPF_PROG_QUERY`).
816#[derive(Debug)]
817pub struct BpfProgramQueryRequest<'a> {
818 /// Cible (cgroup…).
819 pub target: BorrowedFd<'a>,
820 /// Type d'attache interrogé.
821 pub attach_type: BpfAttachType,
822 /// Drapeaux de requête.
823 pub query_flags: u32,
824 /// Tampon d'ids de programmes (rempli par le kernel).
825 pub program_ids: &'a mut [u32],
826}
827
828/// Requête d'introspection d'un fd perf/tracepoint (`BPF_TASK_FD_QUERY`).
829#[derive(Debug)]
830pub struct BpfTaskFdQueryRequest<'a> {
831 /// PID de la tâche.
832 pub pid: Pid,
833 /// FD perf/tracepoint dans la tâche.
834 pub fd: BorrowedFd<'a>,
835 /// Tampon recevant le nom du point d'attache.
836 pub name_buffer: &'a mut [u8],
837}
838
839#[cfg(test)]
840mod tests;
841
842#[cfg(test)]
843// Sous `tests/`, et pas à côté : le filtre par défaut de `cargo-llvm-cov` écarte
844// `tests.rs`, `*_tests.rs` et les répertoires `tests/` — mais PAS un `proptests.rs`
845// posé en voisin, dont les lignes retomberaient dans la mesure de production.
846// `#[path]` déplace le FICHIER sans toucher l'arbre des modules : `super::` désigne
847// toujours le parent, et le contenu n'a pas à changer.
848#[path = "ebpf/tests/proptests.rs"]
849mod proptests;