#![allow(missing_docs)]
use bitflags::bitflags;
use crate::{
bindings::{
VNET_BUFFER_F_AVAIL1, VNET_BUFFER_F_AVAIL2, VNET_BUFFER_F_AVAIL3, VNET_BUFFER_F_AVAIL4,
VNET_BUFFER_F_AVAIL5, VNET_BUFFER_F_AVAIL6, VNET_BUFFER_F_AVAIL7, VNET_BUFFER_F_AVAIL8,
VNET_BUFFER_F_AVAIL9, VNET_BUFFER_F_FLOW_REPORT, VNET_BUFFER_F_GSO, VNET_BUFFER_F_IS_DVR,
VNET_BUFFER_F_IS_IP4, VNET_BUFFER_F_IS_IP6, VNET_BUFFER_F_IS_NATED,
VNET_BUFFER_F_L2_HDR_OFFSET_VALID, VNET_BUFFER_F_L3_HDR_OFFSET_VALID,
VNET_BUFFER_F_L4_CHECKSUM_COMPUTED, VNET_BUFFER_F_L4_CHECKSUM_CORRECT,
VNET_BUFFER_F_L4_HDR_OFFSET_VALID, VNET_BUFFER_F_LOCALLY_ORIGINATED,
VNET_BUFFER_F_LOOP_COUNTER_VALID, VNET_BUFFER_F_OFFLOAD, VNET_BUFFER_F_QOS_DATA_VALID,
VNET_BUFFER_F_SPAN_CLONE, VNET_BUFFER_F_VLAN_1_DEEP, VNET_BUFFER_F_VLAN_2_DEEP,
feature_main, vlib_rx_or_tx_t_VLIB_RX, vlib_rx_or_tx_t_VLIB_TX, vnet_buffer_opaque_t,
vnet_config_main_t,
},
vnet::types::SwIfIndex,
};
bitflags! {
pub struct BufferFlags: u32 {
const L4_CHECKSUM_COMPUTED = VNET_BUFFER_F_L4_CHECKSUM_COMPUTED as u32;
const L4_CHECKSUM_CORRECT = VNET_BUFFER_F_L4_CHECKSUM_CORRECT as u32;
const VLAN_2_DEEP = VNET_BUFFER_F_VLAN_2_DEEP as u32;
const VLAN_1_DEEP = VNET_BUFFER_F_VLAN_1_DEEP as u32;
const SPAN_CLONE = VNET_BUFFER_F_SPAN_CLONE as u32;
const LOOP_COUNTER_VALID = VNET_BUFFER_F_LOOP_COUNTER_VALID as u32;
const LOCALLY_ORIGINATED = VNET_BUFFER_F_LOCALLY_ORIGINATED as u32;
const IS_IP4 = VNET_BUFFER_F_IS_IP4 as u32;
const IS_IP6 = VNET_BUFFER_F_IS_IP6 as u32;
const OFFLOAD = VNET_BUFFER_F_OFFLOAD as u32;
const IS_NATED = VNET_BUFFER_F_IS_NATED as u32;
const L2_HDR_OFFSET_VALID = VNET_BUFFER_F_L2_HDR_OFFSET_VALID as u32;
const L3_HDR_OFFSET_VALID = VNET_BUFFER_F_L3_HDR_OFFSET_VALID as u32;
const L4_HDR_OFFSET_VALID = VNET_BUFFER_F_L4_HDR_OFFSET_VALID as u32;
const FLOW_REPORT = VNET_BUFFER_F_FLOW_REPORT as u32;
const IS_DVR = VNET_BUFFER_F_IS_DVR as u32;
const QOS_DATA_VALID = VNET_BUFFER_F_QOS_DATA_VALID as u32;
const GSO = VNET_BUFFER_F_GSO as u32;
const AVAIL1 = VNET_BUFFER_F_AVAIL1 as u32;
const AVAIL2 = VNET_BUFFER_F_AVAIL2 as u32;
const AVAIL3 = VNET_BUFFER_F_AVAIL3 as u32;
const AVAIL4 = VNET_BUFFER_F_AVAIL4 as u32;
const AVAIL5 = VNET_BUFFER_F_AVAIL5 as u32;
const AVAIL6 = VNET_BUFFER_F_AVAIL6 as u32;
const AVAIL7 = VNET_BUFFER_F_AVAIL7 as u32;
const AVAIL8 = VNET_BUFFER_F_AVAIL8 as u32;
const AVAIL9 = VNET_BUFFER_F_AVAIL9 as u32;
const _ = !0;
}
}
impl BufferFlags {
pub fn as_vlib_flags(&self) -> crate::vlib::buffer::BufferFlags {
crate::vlib::buffer::BufferFlags::from_bits_retain(self.bits())
}
}
impl crate::vlib::buffer::BufferFlags {
pub fn vnet_flags(&self) -> BufferFlags {
BufferFlags::from_bits_retain(self.bits())
}
}
#[repr(transparent)]
pub struct BufferRef(foreign_types::Opaque);
impl BufferRef {
#[inline(always)]
pub unsafe fn from_ptr<'a>(ptr: *const vnet_buffer_opaque_t) -> &'a BufferRef {
unsafe { &*(ptr as *mut _) }
}
#[inline(always)]
pub unsafe fn from_ptr_mut<'a>(ptr: *mut vnet_buffer_opaque_t) -> &'a mut BufferRef {
unsafe { &mut *(ptr as *mut _) }
}
#[inline(always)]
pub fn as_ptr(&self) -> *mut vnet_buffer_opaque_t {
self as *const _ as *mut _
}
#[inline(always)]
pub fn feature_arc_index(&self) -> u8 {
unsafe { (*self.as_ptr()).feature_arc_index }
}
pub fn rx_sw_if_index(&self) -> SwIfIndex {
SwIfIndex::new(unsafe { (*self.as_ptr()).sw_if_index[vlib_rx_or_tx_t_VLIB_RX as usize] })
}
pub fn set_rx_sw_if_index(&mut self, sw_if_index: SwIfIndex) {
unsafe {
(*self.as_ptr()).sw_if_index[vlib_rx_or_tx_t_VLIB_TX as usize] = sw_if_index.into()
};
}
pub fn tx_sw_if_index(&self) -> Option<SwIfIndex> {
let sw_if_index = unsafe { (*self.as_ptr()).sw_if_index[vlib_rx_or_tx_t_VLIB_TX as usize] };
if sw_if_index == u32::MAX {
None
} else {
Some(sw_if_index.into())
}
}
pub fn set_tx_sw_if_index(&mut self, sw_if_index: Option<SwIfIndex>) {
let sw_if_index = sw_if_index.map(u32::from).unwrap_or(u32::MAX);
unsafe { (*self.as_ptr()).sw_if_index[vlib_rx_or_tx_t_VLIB_TX as usize] = sw_if_index };
}
}
impl<FeatureData> crate::vlib::BufferRef<FeatureData> {
pub fn vnet_buffer(&self) -> &BufferRef {
let ptr = &self.as_metadata().opaque as *const _;
unsafe { BufferRef::from_ptr(ptr as *const vnet_buffer_opaque_t) }
}
pub fn vnet_buffer_mut(&mut self) -> &mut BufferRef {
let ptr = &mut self.as_metadata_mut().opaque as *mut _;
unsafe { BufferRef::from_ptr_mut(ptr as *mut vnet_buffer_opaque_t) }
}
}
#[inline(always)]
unsafe fn vnet_get_config_data<FeatureData: Copy>(
cm: *const vnet_config_main_t,
config_index: &mut u32,
) -> (u32, FeatureData) {
unsafe {
let index = *config_index;
let d = (*cm).config_string_heap.add(index as usize);
let n = std::mem::size_of::<FeatureData>().div_ceil(std::mem::size_of_val(&*d));
let next = *d.add(n);
*config_index = index + n as u32 + 1;
(next, *(d as *const FeatureData))
}
}
impl<FeatureData: Copy> crate::vlib::BufferRef<FeatureData> {
#[inline(always)]
pub unsafe fn vnet_feature_next(&mut self) -> (u32, FeatureData) {
let arc = self.vnet_buffer().feature_arc_index();
unsafe {
let cm = *feature_main.feature_config_mains.add(arc as usize);
vnet_get_config_data(
&cm.config_main,
&mut self.as_metadata_mut().__bindgen_anon_1.current_config_index,
)
}
}
}