fidl_fuchsia_ebpf__common/
fidl_fuchsia_ebpf__common.rs

1// WARNING: This file is machine generated by fidlgen.
2
3#![warn(clippy::all)]
4#![allow(unused_parens, unused_mut, unused_imports, nonstandard_style)]
5
6use bitflags::bitflags;
7use fidl::encoding::{MessageBufFor, ProxyChannelBox, ResourceDialect};
8use futures::future::{self, MaybeDone, TryFutureExt};
9use zx_status;
10
11/// Maximum allowed number of instructions in an eBPF program.
12pub const MAX_PROGRAM_INSTRUCTIONS: u32 = 4096;
13
14/// Maximum number of maps an eBPF program can use.
15pub const MAX_PROGRAM_MAPS: u32 = 4096;
16
17/// The signal raised on a [`ProgramHandle`] to indicate that the program
18/// should be dropped.
19pub const PROGRAM_DEFUNCT_SIGNAL: u32 = 16777216;
20
21bitflags! {
22    /// Map flags.
23    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
24    pub struct MapFlags: u32 {
25        /// Memory is not pre-allocated.
26        const NO_PREALLOC = 1;
27        /// `bpf()` syscall can read from the map, but can't write to it.
28        const SYSCALL_READ_ONLY = 2;
29        /// `bpf()` syscall can write to the map, but can't read it.
30        const SYSCALL_WRITE_ONLY = 4;
31        /// The map can be mapped in a Starnix process's address space.
32        const MMAPABLE = 8;
33    }
34}
35
36impl MapFlags {
37    #[inline(always)]
38    pub fn from_bits_allow_unknown(bits: u32) -> Self {
39        Self::from_bits_retain(bits)
40    }
41
42    #[inline(always)]
43    pub fn has_unknown_bits(&self) -> bool {
44        self.get_unknown_bits() != 0
45    }
46
47    #[inline(always)]
48    pub fn get_unknown_bits(&self) -> u32 {
49        self.bits() & !Self::all().bits()
50    }
51}
52
53/// Type of an eBPF maps.
54#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
55#[repr(u32)]
56pub enum MapType {
57    /// An array map. Equivalent to `BPF_MAP_TYPE_ARRAY`.
58    Array = 1,
59    /// A hash map. Equivalent to `BPF_MAP_TYPE_HASH`.
60    HashMap = 2,
61    /// A hash map. Equivalent to `BPF_MAP_TYPE_RINGBUF`.
62    RingBuffer = 3,
63    /// A per-CPU array. Equivalent to `BPF_MAP_TYPE_PERCPU_ARRAY`.
64    PercpuArray = 4,
65    /// A per-CPU hash map. Equivalent to `BPF_MAP_TYPE_PERCPU_HASH`.
66    PercpuHash = 5,
67    /// A device-map that holds references to network devices. Equivalent to
68    /// `BPF_MAP_TYPE_DEVMAP`.
69    DevmapHash = 6,
70    /// A longest prefix match trie. Equivalent to `BPF_MAP_TYPE_LPM_TRIE`.
71    LpmTrie = 7,
72    /// A LRU hash map. Equivalent to `BPF_MAP_TYPE_LRU_HASH`.
73    LruHash = 8,
74    /// A socket storage map. Equivalent to `BPF_MAP_TYPE_SK_STORAGE`.
75    SkStorage = 9,
76}
77
78impl MapType {
79    #[inline]
80    pub fn from_primitive(prim: u32) -> Option<Self> {
81        match prim {
82            1 => Some(Self::Array),
83            2 => Some(Self::HashMap),
84            3 => Some(Self::RingBuffer),
85            4 => Some(Self::PercpuArray),
86            5 => Some(Self::PercpuHash),
87            6 => Some(Self::DevmapHash),
88            7 => Some(Self::LpmTrie),
89            8 => Some(Self::LruHash),
90            9 => Some(Self::SkStorage),
91            _ => None,
92        }
93    }
94
95    #[inline]
96    pub const fn into_primitive(self) -> u32 {
97        self as u32
98    }
99}
100
101/// Schema of an eBPF map.
102#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
103pub struct MapSchema {
104    /// Map type.
105    pub type_: MapType,
106    /// Key size in bytes.
107    pub key_size: u32,
108    /// Value size in bytes.
109    pub value_size: u32,
110    /// Maximum number of entries in the map.
111    pub max_entries: u32,
112    /// Map flags.
113    pub flags: MapFlags,
114}
115
116impl fidl::Persistable for MapSchema {}
117
118/// An ID used to uniquely identify an eBPF program. The ID is the KOID of the
119/// [`ProgramHandle`].
120#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
121#[repr(C)]
122pub struct ProgramId {
123    pub id: u64,
124}
125
126impl fidl::Persistable for ProgramId {}
127
128/// Describes location of an instruction that accesses a struct field.
129///
130/// This is used as auxiliary information passed from the verifier to the
131/// linker. The linker may update these instructions.
132#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
133pub struct StructAccess {
134    /// Index of the instruction in the program.
135    pub pc: u32,
136    /// Id of the struct being accessed.
137    pub struct_memory_id: u64,
138    /// Offset of the field being accessed.
139    pub field_offset: u32,
140    /// Indicates that the instruction loads a 32-bit pointer field. These
141    /// loads must be remapped to 64-bit fields.
142    pub is_32_bit_ptr_load: bool,
143}
144
145impl fidl::Persistable for StructAccess {}
146
147mod internal {
148    use super::*;
149    unsafe impl fidl::encoding::TypeMarker for MapFlags {
150        type Owned = Self;
151
152        #[inline(always)]
153        fn inline_align(_context: fidl::encoding::Context) -> usize {
154            4
155        }
156
157        #[inline(always)]
158        fn inline_size(_context: fidl::encoding::Context) -> usize {
159            4
160        }
161    }
162
163    impl fidl::encoding::ValueTypeMarker for MapFlags {
164        type Borrowed<'a> = Self;
165        #[inline(always)]
166        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
167            *value
168        }
169    }
170
171    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<Self, D> for MapFlags {
172        #[inline]
173        unsafe fn encode(
174            self,
175            encoder: &mut fidl::encoding::Encoder<'_, D>,
176            offset: usize,
177            _depth: fidl::encoding::Depth,
178        ) -> fidl::Result<()> {
179            encoder.debug_check_bounds::<Self>(offset);
180            encoder.write_num(self.bits(), offset);
181            Ok(())
182        }
183    }
184
185    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for MapFlags {
186        #[inline(always)]
187        fn new_empty() -> Self {
188            Self::empty()
189        }
190
191        #[inline]
192        unsafe fn decode(
193            &mut self,
194            decoder: &mut fidl::encoding::Decoder<'_, D>,
195            offset: usize,
196            _depth: fidl::encoding::Depth,
197        ) -> fidl::Result<()> {
198            decoder.debug_check_bounds::<Self>(offset);
199            let prim = decoder.read_num::<u32>(offset);
200            *self = Self::from_bits_allow_unknown(prim);
201            Ok(())
202        }
203    }
204    unsafe impl fidl::encoding::TypeMarker for MapType {
205        type Owned = Self;
206
207        #[inline(always)]
208        fn inline_align(_context: fidl::encoding::Context) -> usize {
209            std::mem::align_of::<u32>()
210        }
211
212        #[inline(always)]
213        fn inline_size(_context: fidl::encoding::Context) -> usize {
214            std::mem::size_of::<u32>()
215        }
216
217        #[inline(always)]
218        fn encode_is_copy() -> bool {
219            true
220        }
221
222        #[inline(always)]
223        fn decode_is_copy() -> bool {
224            false
225        }
226    }
227
228    impl fidl::encoding::ValueTypeMarker for MapType {
229        type Borrowed<'a> = Self;
230        #[inline(always)]
231        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
232            *value
233        }
234    }
235
236    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<Self, D> for MapType {
237        #[inline]
238        unsafe fn encode(
239            self,
240            encoder: &mut fidl::encoding::Encoder<'_, D>,
241            offset: usize,
242            _depth: fidl::encoding::Depth,
243        ) -> fidl::Result<()> {
244            encoder.debug_check_bounds::<Self>(offset);
245            encoder.write_num(self.into_primitive(), offset);
246            Ok(())
247        }
248    }
249
250    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for MapType {
251        #[inline(always)]
252        fn new_empty() -> Self {
253            Self::Array
254        }
255
256        #[inline]
257        unsafe fn decode(
258            &mut self,
259            decoder: &mut fidl::encoding::Decoder<'_, D>,
260            offset: usize,
261            _depth: fidl::encoding::Depth,
262        ) -> fidl::Result<()> {
263            decoder.debug_check_bounds::<Self>(offset);
264            let prim = decoder.read_num::<u32>(offset);
265
266            *self = Self::from_primitive(prim).ok_or(fidl::Error::InvalidEnumValue)?;
267            Ok(())
268        }
269    }
270
271    impl fidl::encoding::ValueTypeMarker for MapSchema {
272        type Borrowed<'a> = &'a Self;
273        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
274            value
275        }
276    }
277
278    unsafe impl fidl::encoding::TypeMarker for MapSchema {
279        type Owned = Self;
280
281        #[inline(always)]
282        fn inline_align(_context: fidl::encoding::Context) -> usize {
283            4
284        }
285
286        #[inline(always)]
287        fn inline_size(_context: fidl::encoding::Context) -> usize {
288            20
289        }
290    }
291
292    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<MapSchema, D>
293        for &MapSchema
294    {
295        #[inline]
296        unsafe fn encode(
297            self,
298            encoder: &mut fidl::encoding::Encoder<'_, D>,
299            offset: usize,
300            _depth: fidl::encoding::Depth,
301        ) -> fidl::Result<()> {
302            encoder.debug_check_bounds::<MapSchema>(offset);
303            // Delegate to tuple encoding.
304            fidl::encoding::Encode::<MapSchema, D>::encode(
305                (
306                    <MapType as fidl::encoding::ValueTypeMarker>::borrow(&self.type_),
307                    <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.key_size),
308                    <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.value_size),
309                    <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.max_entries),
310                    <MapFlags as fidl::encoding::ValueTypeMarker>::borrow(&self.flags),
311                ),
312                encoder,
313                offset,
314                _depth,
315            )
316        }
317    }
318    unsafe impl<
319        D: fidl::encoding::ResourceDialect,
320        T0: fidl::encoding::Encode<MapType, D>,
321        T1: fidl::encoding::Encode<u32, D>,
322        T2: fidl::encoding::Encode<u32, D>,
323        T3: fidl::encoding::Encode<u32, D>,
324        T4: fidl::encoding::Encode<MapFlags, D>,
325    > fidl::encoding::Encode<MapSchema, D> for (T0, T1, T2, T3, T4)
326    {
327        #[inline]
328        unsafe fn encode(
329            self,
330            encoder: &mut fidl::encoding::Encoder<'_, D>,
331            offset: usize,
332            depth: fidl::encoding::Depth,
333        ) -> fidl::Result<()> {
334            encoder.debug_check_bounds::<MapSchema>(offset);
335            // Zero out padding regions. There's no need to apply masks
336            // because the unmasked parts will be overwritten by fields.
337            // Write the fields.
338            self.0.encode(encoder, offset + 0, depth)?;
339            self.1.encode(encoder, offset + 4, depth)?;
340            self.2.encode(encoder, offset + 8, depth)?;
341            self.3.encode(encoder, offset + 12, depth)?;
342            self.4.encode(encoder, offset + 16, depth)?;
343            Ok(())
344        }
345    }
346
347    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for MapSchema {
348        #[inline(always)]
349        fn new_empty() -> Self {
350            Self {
351                type_: fidl::new_empty!(MapType, D),
352                key_size: fidl::new_empty!(u32, D),
353                value_size: fidl::new_empty!(u32, D),
354                max_entries: fidl::new_empty!(u32, D),
355                flags: fidl::new_empty!(MapFlags, D),
356            }
357        }
358
359        #[inline]
360        unsafe fn decode(
361            &mut self,
362            decoder: &mut fidl::encoding::Decoder<'_, D>,
363            offset: usize,
364            _depth: fidl::encoding::Depth,
365        ) -> fidl::Result<()> {
366            decoder.debug_check_bounds::<Self>(offset);
367            // Verify that padding bytes are zero.
368            fidl::decode!(MapType, D, &mut self.type_, decoder, offset + 0, _depth)?;
369            fidl::decode!(u32, D, &mut self.key_size, decoder, offset + 4, _depth)?;
370            fidl::decode!(u32, D, &mut self.value_size, decoder, offset + 8, _depth)?;
371            fidl::decode!(u32, D, &mut self.max_entries, decoder, offset + 12, _depth)?;
372            fidl::decode!(MapFlags, D, &mut self.flags, decoder, offset + 16, _depth)?;
373            Ok(())
374        }
375    }
376
377    impl fidl::encoding::ValueTypeMarker for ProgramId {
378        type Borrowed<'a> = &'a Self;
379        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
380            value
381        }
382    }
383
384    unsafe impl fidl::encoding::TypeMarker for ProgramId {
385        type Owned = Self;
386
387        #[inline(always)]
388        fn inline_align(_context: fidl::encoding::Context) -> usize {
389            8
390        }
391
392        #[inline(always)]
393        fn inline_size(_context: fidl::encoding::Context) -> usize {
394            8
395        }
396        #[inline(always)]
397        fn encode_is_copy() -> bool {
398            true
399        }
400
401        #[inline(always)]
402        fn decode_is_copy() -> bool {
403            true
404        }
405    }
406
407    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<ProgramId, D>
408        for &ProgramId
409    {
410        #[inline]
411        unsafe fn encode(
412            self,
413            encoder: &mut fidl::encoding::Encoder<'_, D>,
414            offset: usize,
415            _depth: fidl::encoding::Depth,
416        ) -> fidl::Result<()> {
417            encoder.debug_check_bounds::<ProgramId>(offset);
418            unsafe {
419                // Copy the object into the buffer.
420                let buf_ptr = encoder.buf.as_mut_ptr().add(offset);
421                (buf_ptr as *mut ProgramId).write_unaligned((self as *const ProgramId).read());
422                // Zero out padding regions. Unlike `fidl_struct_impl_noncopy!`, this must be
423                // done second because the memcpy will write garbage to these bytes.
424            }
425            Ok(())
426        }
427    }
428    unsafe impl<D: fidl::encoding::ResourceDialect, T0: fidl::encoding::Encode<u64, D>>
429        fidl::encoding::Encode<ProgramId, D> for (T0,)
430    {
431        #[inline]
432        unsafe fn encode(
433            self,
434            encoder: &mut fidl::encoding::Encoder<'_, D>,
435            offset: usize,
436            depth: fidl::encoding::Depth,
437        ) -> fidl::Result<()> {
438            encoder.debug_check_bounds::<ProgramId>(offset);
439            // Zero out padding regions. There's no need to apply masks
440            // because the unmasked parts will be overwritten by fields.
441            // Write the fields.
442            self.0.encode(encoder, offset + 0, depth)?;
443            Ok(())
444        }
445    }
446
447    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for ProgramId {
448        #[inline(always)]
449        fn new_empty() -> Self {
450            Self { id: fidl::new_empty!(u64, D) }
451        }
452
453        #[inline]
454        unsafe fn decode(
455            &mut self,
456            decoder: &mut fidl::encoding::Decoder<'_, D>,
457            offset: usize,
458            _depth: fidl::encoding::Depth,
459        ) -> fidl::Result<()> {
460            decoder.debug_check_bounds::<Self>(offset);
461            let buf_ptr = unsafe { decoder.buf.as_ptr().add(offset) };
462            // Verify that padding bytes are zero.
463            // Copy from the buffer into the object.
464            unsafe {
465                std::ptr::copy_nonoverlapping(buf_ptr, self as *mut Self as *mut u8, 8);
466            }
467            Ok(())
468        }
469    }
470
471    impl fidl::encoding::ValueTypeMarker for StructAccess {
472        type Borrowed<'a> = &'a Self;
473        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
474            value
475        }
476    }
477
478    unsafe impl fidl::encoding::TypeMarker for StructAccess {
479        type Owned = Self;
480
481        #[inline(always)]
482        fn inline_align(_context: fidl::encoding::Context) -> usize {
483            8
484        }
485
486        #[inline(always)]
487        fn inline_size(_context: fidl::encoding::Context) -> usize {
488            24
489        }
490    }
491
492    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<StructAccess, D>
493        for &StructAccess
494    {
495        #[inline]
496        unsafe fn encode(
497            self,
498            encoder: &mut fidl::encoding::Encoder<'_, D>,
499            offset: usize,
500            _depth: fidl::encoding::Depth,
501        ) -> fidl::Result<()> {
502            encoder.debug_check_bounds::<StructAccess>(offset);
503            // Delegate to tuple encoding.
504            fidl::encoding::Encode::<StructAccess, D>::encode(
505                (
506                    <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.pc),
507                    <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.struct_memory_id),
508                    <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.field_offset),
509                    <bool as fidl::encoding::ValueTypeMarker>::borrow(&self.is_32_bit_ptr_load),
510                ),
511                encoder,
512                offset,
513                _depth,
514            )
515        }
516    }
517    unsafe impl<
518        D: fidl::encoding::ResourceDialect,
519        T0: fidl::encoding::Encode<u32, D>,
520        T1: fidl::encoding::Encode<u64, D>,
521        T2: fidl::encoding::Encode<u32, D>,
522        T3: fidl::encoding::Encode<bool, D>,
523    > fidl::encoding::Encode<StructAccess, D> for (T0, T1, T2, T3)
524    {
525        #[inline]
526        unsafe fn encode(
527            self,
528            encoder: &mut fidl::encoding::Encoder<'_, D>,
529            offset: usize,
530            depth: fidl::encoding::Depth,
531        ) -> fidl::Result<()> {
532            encoder.debug_check_bounds::<StructAccess>(offset);
533            // Zero out padding regions. There's no need to apply masks
534            // because the unmasked parts will be overwritten by fields.
535            unsafe {
536                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
537                (ptr as *mut u64).write_unaligned(0);
538            }
539            unsafe {
540                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(16);
541                (ptr as *mut u64).write_unaligned(0);
542            }
543            // Write the fields.
544            self.0.encode(encoder, offset + 0, depth)?;
545            self.1.encode(encoder, offset + 8, depth)?;
546            self.2.encode(encoder, offset + 16, depth)?;
547            self.3.encode(encoder, offset + 20, depth)?;
548            Ok(())
549        }
550    }
551
552    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for StructAccess {
553        #[inline(always)]
554        fn new_empty() -> Self {
555            Self {
556                pc: fidl::new_empty!(u32, D),
557                struct_memory_id: fidl::new_empty!(u64, D),
558                field_offset: fidl::new_empty!(u32, D),
559                is_32_bit_ptr_load: fidl::new_empty!(bool, D),
560            }
561        }
562
563        #[inline]
564        unsafe fn decode(
565            &mut self,
566            decoder: &mut fidl::encoding::Decoder<'_, D>,
567            offset: usize,
568            _depth: fidl::encoding::Depth,
569        ) -> fidl::Result<()> {
570            decoder.debug_check_bounds::<Self>(offset);
571            // Verify that padding bytes are zero.
572            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
573            let padval = unsafe { (ptr as *const u64).read_unaligned() };
574            let mask = 0xffffffff00000000u64;
575            let maskedval = padval & mask;
576            if maskedval != 0 {
577                return Err(fidl::Error::NonZeroPadding {
578                    padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
579                });
580            }
581            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(16) };
582            let padval = unsafe { (ptr as *const u64).read_unaligned() };
583            let mask = 0xffffff0000000000u64;
584            let maskedval = padval & mask;
585            if maskedval != 0 {
586                return Err(fidl::Error::NonZeroPadding {
587                    padding_start: offset + 16 + ((mask as u64).trailing_zeros() / 8) as usize,
588                });
589            }
590            fidl::decode!(u32, D, &mut self.pc, decoder, offset + 0, _depth)?;
591            fidl::decode!(u64, D, &mut self.struct_memory_id, decoder, offset + 8, _depth)?;
592            fidl::decode!(u32, D, &mut self.field_offset, decoder, offset + 16, _depth)?;
593            fidl::decode!(bool, D, &mut self.is_32_bit_ptr_load, decoder, offset + 20, _depth)?;
594            Ok(())
595        }
596    }
597}