Skip to main content

vpp_plugin/vnet/
buffer.rs

1#![allow(missing_docs)]
2
3//! VNET buffer flags
4
5use bitflags::bitflags;
6
7use crate::bindings::{
8    VNET_BUFFER_F_AVAIL1, VNET_BUFFER_F_AVAIL2, VNET_BUFFER_F_AVAIL3, VNET_BUFFER_F_AVAIL4,
9    VNET_BUFFER_F_AVAIL5, VNET_BUFFER_F_AVAIL6, VNET_BUFFER_F_AVAIL7, VNET_BUFFER_F_AVAIL8,
10    VNET_BUFFER_F_AVAIL9, VNET_BUFFER_F_FLOW_REPORT, VNET_BUFFER_F_GSO, VNET_BUFFER_F_IS_DVR,
11    VNET_BUFFER_F_IS_IP4, VNET_BUFFER_F_IS_IP6, VNET_BUFFER_F_IS_NATED,
12    VNET_BUFFER_F_L2_HDR_OFFSET_VALID, VNET_BUFFER_F_L3_HDR_OFFSET_VALID,
13    VNET_BUFFER_F_L4_CHECKSUM_COMPUTED, VNET_BUFFER_F_L4_CHECKSUM_CORRECT,
14    VNET_BUFFER_F_L4_HDR_OFFSET_VALID, VNET_BUFFER_F_LOCALLY_ORIGINATED,
15    VNET_BUFFER_F_LOOP_COUNTER_VALID, VNET_BUFFER_F_OFFLOAD, VNET_BUFFER_F_QOS_DATA_VALID,
16    VNET_BUFFER_F_SPAN_CLONE, VNET_BUFFER_F_VLAN_1_DEEP, VNET_BUFFER_F_VLAN_2_DEEP, feature_main,
17    vnet_buffer_opaque_t, vnet_config_main_t,
18};
19
20bitflags! {
21    /// VNET buffer flags
22    pub struct BufferFlags: u32 {
23        const L4_CHECKSUM_COMPUTED = VNET_BUFFER_F_L4_CHECKSUM_COMPUTED as u32;
24        const L4_CHECKSUM_CORRECT = VNET_BUFFER_F_L4_CHECKSUM_CORRECT as u32;
25        const VLAN_2_DEEP = VNET_BUFFER_F_VLAN_2_DEEP as u32;
26        const VLAN_1_DEEP = VNET_BUFFER_F_VLAN_1_DEEP as u32;
27        const SPAN_CLONE = VNET_BUFFER_F_SPAN_CLONE as u32;
28        const LOOP_COUNTER_VALID = VNET_BUFFER_F_LOOP_COUNTER_VALID as u32;
29        const LOCALLY_ORIGINATED = VNET_BUFFER_F_LOCALLY_ORIGINATED as u32;
30        const IS_IP4 = VNET_BUFFER_F_IS_IP4 as u32;
31        const IS_IP6 = VNET_BUFFER_F_IS_IP6 as u32;
32        const OFFLOAD = VNET_BUFFER_F_OFFLOAD as u32;
33        const IS_NATED = VNET_BUFFER_F_IS_NATED as u32;
34        const L2_HDR_OFFSET_VALID = VNET_BUFFER_F_L2_HDR_OFFSET_VALID as u32;
35        const L3_HDR_OFFSET_VALID = VNET_BUFFER_F_L3_HDR_OFFSET_VALID as u32;
36        const L4_HDR_OFFSET_VALID = VNET_BUFFER_F_L4_HDR_OFFSET_VALID as u32;
37        const FLOW_REPORT = VNET_BUFFER_F_FLOW_REPORT as u32;
38        const IS_DVR = VNET_BUFFER_F_IS_DVR as u32;
39        const QOS_DATA_VALID = VNET_BUFFER_F_QOS_DATA_VALID as u32;
40        const GSO = VNET_BUFFER_F_GSO as u32;
41        const AVAIL1 = VNET_BUFFER_F_AVAIL1 as u32;
42        const AVAIL2 = VNET_BUFFER_F_AVAIL2 as u32;
43        const AVAIL3 = VNET_BUFFER_F_AVAIL3 as u32;
44        const AVAIL4 = VNET_BUFFER_F_AVAIL4 as u32;
45        const AVAIL5 = VNET_BUFFER_F_AVAIL5 as u32;
46        const AVAIL6 = VNET_BUFFER_F_AVAIL6 as u32;
47        const AVAIL7 = VNET_BUFFER_F_AVAIL7 as u32;
48        const AVAIL8 = VNET_BUFFER_F_AVAIL8 as u32;
49        const AVAIL9 = VNET_BUFFER_F_AVAIL9 as u32;
50
51        // vlib flags not represented here
52        const _ = !0;
53    }
54}
55
56impl crate::vlib::buffer::BufferFlags {
57    /// Get the VNET buffer flags from the VLIB buffer flags
58    pub fn vnet_flags(&self) -> BufferFlags {
59        BufferFlags::from_bits_retain(self.bits())
60    }
61}
62
63/// Reference to a VNET buffer
64///
65/// A `&mut BufferRef` is equivalent to a `vnet_buffer_opaque_t *` in C (a `*vnet_buffer_opaque_t`
66/// in Rust).
67#[repr(transparent)]
68pub struct BufferRef(foreign_types::Opaque);
69
70impl BufferRef {
71    /// Create a `&BufferRef` from a raw pointer
72    ///
73    /// # Safety
74    ///
75    /// - The pointer must be a valid and properly initialised `vlib_buffer_t`.
76    /// - The pointer must stay valid and the contents must not be mutated for the duration of the
77    ///   lifetime of the returned object.
78    #[inline(always)]
79    pub unsafe fn from_ptr<'a>(ptr: *const vnet_buffer_opaque_t) -> &'a BufferRef {
80        // SAFETY: The safety requirements are documented in the function's safety comment.
81        unsafe { &*(ptr as *mut _) }
82    }
83
84    /// Create a `&mut BufferRef` from a raw pointer
85    ///
86    /// # Safety
87    ///
88    /// - The pointer must be a valid and properly initialised `vlib_buffer_t`.
89    /// - The pointer must stay valid and the contents must not be mutated for the duration of the
90    ///   lifetime of the returned object.
91    #[inline(always)]
92    pub unsafe fn from_ptr_mut<'a>(ptr: *mut vnet_buffer_opaque_t) -> &'a mut BufferRef {
93        // SAFETY: The safety requirements are documented in the function's safety comment.
94        unsafe { &mut *(ptr as *mut _) }
95    }
96
97    /// Returns the raw pointer to the underlying `vnet_buffer_opaque_t`
98    #[inline(always)]
99    pub fn as_ptr(&self) -> *mut vnet_buffer_opaque_t {
100        self as *const _ as *mut _
101    }
102
103    /// Returns the index of the feature arc that the buffer is being processed from
104    #[inline(always)]
105    pub fn feature_arc_index(&self) -> u8 {
106        // SAFETY: since the reference to self is valid, so must be the pointer
107        unsafe { (*self.as_ptr()).feature_arc_index }
108    }
109}
110
111impl<FeatureData> crate::vlib::BufferRef<FeatureData> {
112    pub fn vnet_buffer(&self) -> &BufferRef {
113        let ptr = &self.as_metadata().opaque as *const _;
114        // SAFETY: ptr is valid since reference to self is valid, and the representation is a
115        // valid `vnet_buffer_opaque_t`
116        unsafe { BufferRef::from_ptr(ptr as *const vnet_buffer_opaque_t) }
117    }
118
119    pub fn vnet_buffer_mut(&mut self) -> &mut BufferRef {
120        let ptr = &mut self.as_metadata_mut().opaque as *mut _;
121        // SAFETY: ptr is valid since reference to self is valid, and the representation is a
122        // valid `vnet_buffer_opaque_t`
123        unsafe { BufferRef::from_ptr_mut(ptr as *mut vnet_buffer_opaque_t) }
124    }
125}
126
127/// Returns VNET config data for the given config index
128///
129/// In the process, the config index is advanced to the next one.
130///
131/// # Safety
132///
133/// - `cm` must be a valid pointer.
134/// - `*config_index` must be a valid config index on calling.
135/// - `FeatureData` must match the type the config data was created with (and must match the
136///   index that was allocated for it).
137#[inline(always)]
138unsafe fn vnet_get_config_data<FeatureData: Copy>(
139    cm: *const vnet_config_main_t,
140    config_index: &mut u32,
141) -> (u32, FeatureData) {
142    // SAFETY: function preconditions mean that this pointer arithmetic is valid and matches what
143    // VPP expects
144    unsafe {
145        let index = *config_index;
146
147        let d = (*cm).config_string_heap.add(index as usize);
148
149        let n = std::mem::size_of::<FeatureData>().next_multiple_of(std::mem::size_of_val(&*d))
150            / std::mem::size_of_val(&*d);
151
152        // The last u32 is the next index
153        let next = *d.add(n);
154
155        // Advance config index to next config
156        *config_index = index + n as u32 + 1;
157
158        (next, *(d as *const FeatureData))
159    }
160}
161
162impl<FeatureData: Copy> crate::vlib::BufferRef<FeatureData> {
163    /// Get the next feature node and feature data for this buffer
164    ///
165    /// Used when continuing to the next feature node in a node invoked from a feature arc.
166    ///
167    /// # Safety
168    ///
169    /// Must only be used from nodes when invoked from a feature arc.
170    #[inline(always)]
171    pub unsafe fn vnet_feature_next(&mut self) -> (u32, FeatureData) {
172        let arc = self.vnet_buffer().feature_arc_index();
173        // SAFETY: method precondition means that arc is a valid index into
174        // `feature_main.feature_config_mains`, and then also that the `current_config_index`
175        // buffer field is a valid config index for that feature arc.
176        // Access to `feature_main.feature_config_mains` is safe without locking because VPP only
177        // modifies this during init, before any buffers are allocated.
178        unsafe {
179            let cm = *feature_main.feature_config_mains.add(arc as usize);
180
181            vnet_get_config_data(
182                &cm.config_main,
183                &mut self.as_metadata_mut().__bindgen_anon_1.current_config_index,
184            )
185        }
186    }
187}