vpp_plugin/vlib/
node_generic.rs1use core::slice;
7use std::mem::MaybeUninit;
8
9use arrayvec::ArrayVec;
10
11use crate::vlib::{
12 buffer::BufferRef,
13 node::{FrameRef, NextNodes, Node, NodeRuntimeRef, FRAME_SIZE},
14 BufferIndex, MainRef,
15};
16
17#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
19pub enum FeatureNextNode<NextNode> {
20 DefinedNode(NextNode),
22 NextFeature,
24}
25
26impl<NextNode> From<NextNode> for FeatureNextNode<NextNode> {
27 fn from(value: NextNode) -> Self {
28 Self::DefinedNode(value)
29 }
30}
31
32pub trait GenericFeatureNodeX1<N: Node> {
34 unsafe fn map_buffer_to_next(
40 &self,
41 vm: &MainRef,
42 node: &mut NodeRuntimeRef<N>,
43 b0: &mut BufferRef<N::FeatureData>,
44 ) -> FeatureNextNode<N::NextNodes>;
45}
46
47#[inline(always)]
57pub unsafe fn generic_feature_node_x1<GenericNode, N, FeatureData>(
58 vm: &MainRef,
59 node: &mut NodeRuntimeRef<N>,
60 frame: &mut FrameRef<N>,
61 generic_node_impl: GenericNode,
62) -> u16
63where
64 N: Node<Vector = BufferIndex, Scalar = (), Aux = (), FeatureData = FeatureData>,
65 GenericNode: GenericFeatureNodeX1<N>,
66 FeatureData: Copy,
67{
68 let mut nexts: [MaybeUninit<u16>; FRAME_SIZE] = [MaybeUninit::uninit(); FRAME_SIZE];
69 let mut b = ArrayVec::new();
70
71 let from = frame.get_buffers::<FRAME_SIZE>(vm, &mut b);
72
73 for (i, b0) in b.iter_mut().enumerate() {
74 let next = generic_node_impl.map_buffer_to_next(vm, node, b0);
75 let next = match next {
76 FeatureNextNode::NextFeature => b0.vnet_feature_next().0 as u16,
77 FeatureNextNode::DefinedNode(next) => next.into_u16(),
78 };
79 nexts.get_unchecked_mut(i).write(next);
80 }
81
82 vm.buffer_enqueue_to_next(
87 node,
88 from,
89 std::mem::transmute::<&[MaybeUninit<u16>], &[u16]>(slice::from_raw_parts(
90 nexts.as_ptr(),
91 b.len(),
92 )),
93 );
94
95 frame.vector().len() as u16
96}