Initial commit of Sphinx docs
[vpp.git] / docs / gettingstarted / developers / vnet.md
1
2 VNET (VPP Network Stack)
3 ========================
4
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.
10
11 In terms of building a packet processing application, vnet provides a
12 platform-independent subgraph to which one connects a couple of
13 device-driver nodes.
14
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
18 checksum\].
19
20 ![image](/_images/VNET_Features.png)
21
22 List of features and layer areas that VNET works with:
23
24 Effective graph dispatch function coding
25 ----------------------------------------
26
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.
30
31 Single/dual loops
32 -----------------
33
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
38 reads.
39
40 Here is an quad/single loop which can leverage up-to-avx512 SIMD vector
41 units to convert buffer indices to buffer pointers:
42
43 ```c
44    static uword
45    simulated_ethernet_interface_tx (vlib_main_t * vm,
46                                  vlib_node_runtime_t *
47                                  node, vlib_frame_t * frame)
48    {
49      u32 n_left_from, *from;
50      u32 next_index = 0;
51      u32 n_bytes;
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;
57
58      n_left_from = frame->n_vectors;
59      from = vlib_frame_args (frame);
60
61      /* 
62       * Convert up to VLIB_FRAME_SIZE indices in "from" to 
63       * buffer pointers in bufs[]
64       */
65      vlib_get_buffers (vm, from, bufs, n_left_from);
66      b = bufs;
67      next = nexts;
68
69      /* 
70       * While we have at least 4 vector elements (pkts) to process.. 
71       */
72      while (n_left_from >= 4)
73        {
74          /* Prefetch next quad-loop iteration. */
75          if (PREDICT_TRUE (n_left_from >= 8))
76            {
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);
81            }
82
83          /* 
84           * $$$ Process 4x packets right here...
85           * set next[0..3] to send the packets where they need to go
86           */
87
88           do_something_to (b[0]);
89           do_something_to (b[1]);
90           do_something_to (b[2]);
91           do_something_to (b[3]);
92
93          /* Process the next 0..4 packets */
94          b += 4;
95          next += 4;
96          n_left_from -= 4;
97         }
98      /* 
99       * Clean up 0...3 remaining packets at the end of the incoming frame
100       */
101      while (n_left_from > 0)
102        {
103          /* 
104           * $$$ Process one packet right here...
105           * set next[0..3] to send the packets where they need to go
106           */
107           do_something_to (b[0]);
108
109          /* Process the next packet */
110          b += 1;
111          next += 1;
112          n_left_from -= 1;
113        }
114
115      /*
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
119       * arc
120       */
121      vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
122
123      return frame->n_vectors;
124    }  
125 ```
126
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.
131
132 Packet tracer
133 -------------
134
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".
138
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"
142
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.
145
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.
150
151 Set the VLIB node registration ".format\_trace" member to the name of
152 the per-graph node format function.
153
154 Here's a simple example:
155
156 ```c
157     u8 * my_node_format_trace (u8 * s, va_list * args)
158     {
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 *);
162
163         s = format (s, "My trace data was: %d", t-><whatever>);
164
165         return s;
166     } 
167 ```
168
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
171 data as desired.