2 VNET (VPP Network Stack)
3 ========================
5 The files associated with the VPP network stack layer are located in the
6 ./src/vnet folder. The Network Stack Layer is basically an
7 instantiation of the code in the other layers. This layer has a vnet
8 library that provides vectorized layer-2 and 3 networking graph nodes, a
9 packet generator, and a packet tracer.
11 In terms of building a packet processing application, vnet provides a
12 platform-independent subgraph to which one connects a couple of
15 Typical RX connections include "ethernet-input" \[full software
16 classification, feeds ipv4-input, ipv6-input, arp-input etc.\] and
17 "ipv4-input-no-checksum" \[if hardware can classify, perform ipv4 header
20 ![image](/_images/VNET_Features.png)
22 List of features and layer areas that VNET works with:
24 Effective graph dispatch function coding
25 ----------------------------------------
27 Over the 15 years, multiple coding styles have emerged: a
28 single/dual/quad loop coding model (with variations) and a
29 fully-pipelined coding model.
34 The single/dual/quad loop model variations conveniently solve problems
35 where the number of items to process is not known in advance: typical
36 hardware RX-ring processing. This coding style is also very effective
37 when a given node will not need to cover a complex set of dependent
40 Here is an quad/single loop which can leverage up-to-avx512 SIMD vector
41 units to convert buffer indices to buffer pointers:
45 simulated_ethernet_interface_tx (vlib_main_t * vm,
47 node, vlib_frame_t * frame)
49 u32 n_left_from, *from;
52 u32 thread_index = vm->thread_index;
53 vnet_main_t *vnm = vnet_get_main ();
54 vnet_interface_main_t *im = &vnm->interface_main;
55 vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
56 u16 nexts[VLIB_FRAME_SIZE], *next;
58 n_left_from = frame->n_vectors;
59 from = vlib_frame_args (frame);
62 * Convert up to VLIB_FRAME_SIZE indices in "from" to
63 * buffer pointers in bufs[]
65 vlib_get_buffers (vm, from, bufs, n_left_from);
70 * While we have at least 4 vector elements (pkts) to process..
72 while (n_left_from >= 4)
74 /* Prefetch next quad-loop iteration. */
75 if (PREDICT_TRUE (n_left_from >= 8))
77 vlib_prefetch_buffer_header (b[4], STORE);
78 vlib_prefetch_buffer_header (b[5], STORE);
79 vlib_prefetch_buffer_header (b[6], STORE);
80 vlib_prefetch_buffer_header (b[7], STORE);
84 * $$$ Process 4x packets right here...
85 * set next[0..3] to send the packets where they need to go
88 do_something_to (b[0]);
89 do_something_to (b[1]);
90 do_something_to (b[2]);
91 do_something_to (b[3]);
93 /* Process the next 0..4 packets */
99 * Clean up 0...3 remaining packets at the end of the incoming frame
101 while (n_left_from > 0)
104 * $$$ Process one packet right here...
105 * set next[0..3] to send the packets where they need to go
107 do_something_to (b[0]);
109 /* Process the next packet */
116 * Send the packets along their respective next-node graph arcs
117 * Considerable locality of reference is expected, most if not all
118 * packets in the inbound vector will traverse the same next-node
121 vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
123 return frame->n_vectors;
127 Given a packet processing task to implement, it pays to scout around
128 looking for similar tasks, and think about using the same coding
129 pattern. It is not uncommon to recode a given graph node dispatch function
130 several times during performance optimization.
135 Vlib includes a frame element \[packet\] trace facility, with a simple
136 vlib cli interface. The cli is straightforward: "trace add
137 input-node-name count".
139 To trace 100 packets on a typical x86\_64 system running the dpdk
140 plugin: "trace add dpdk-input 100". When using the packet generator:
141 "trace add pg-input 100"
143 Each graph node has the opportunity to capture its own trace data. It is
144 almost always a good idea to do so. The trace capture APIs are simple.
146 The packet capture APIs snapshoot binary data, to minimize processing at
147 capture time. Each participating graph node initialization provides a
148 vppinfra format-style user function to pretty-print data when required
149 by the VLIB "show trace" command.
151 Set the VLIB node registration ".format\_trace" member to the name of
152 the per-graph node format function.
154 Here's a simple example:
157 u8 * my_node_format_trace (u8 * s, va_list * args)
159 vlib_main_t * vm = va_arg (*args, vlib_main_t *);
160 vlib_node_t * node = va_arg (*args, vlib_node_t *);
161 my_node_trace_t * t = va_arg (*args, my_trace_t *);
163 s = format (s, "My trace data was: %d", t-><whatever>);
169 The trace framework hands the per-node format function the data it
170 captured as the packet whizzed by. The format function pretty-prints the