2c798f4a337fca54dc60fabd0fb41cbb0791980e
[vpp.git] / docs / gettingstarted / developers / infrastructure.md
1 VPPINFRA (Infrastructure)
2 =========================
3
4 The files associated with the VPP Infrastructure layer are located in
5 the ./src/vppinfra folder.
6
7 VPPinfra is a collection of basic c-library services, quite
8 sufficient to build standalone programs to run directly on bare metal.
9 It also provides high-performance dynamic arrays, hashes, bitmaps,
10 high-precision real-time clock support, fine-grained event-logging, and
11 data structure serialization.
12
13 One fair comment / fair warning about vppinfra: you can\'t always tell a
14 macro from an inline function from an ordinary function simply by name.
15 Macros are used to avoid function calls in the typical case, and to
16 cause (intentional) side-effects.
17
18 Vppinfra has been around for almost 20 years and tends not to change
19 frequently. The VPP Infrastructure layer contains the following
20 functions:
21
22 Vectors
23 -------
24
25 Vppinfra vectors are ubiquitous dynamically resized arrays with by user
26 defined \"headers\". Many vpppinfra data structures (e.g. hash, heap,
27 pool) are vectors with various different headers.
28
29 The memory layout looks like this:
30
31 ```
32                    User header (optional, uword aligned)
33                    Alignment padding (if needed)
34                    Vector length in elements
35  User's pointer -> Vector element 0
36                    Vector element 1
37                    ...
38                    Vector element N-1
39 ```
40
41 As shown above, the vector APIs deal with pointers to the 0th element of
42 a vector. Null pointers are valid vectors of length zero.
43
44 To avoid thrashing the memory allocator, one often resets the length of
45 a vector to zero while retaining the memory allocation. Set the vector
46 length field to zero via the vec\_reset\_length(v) macro. \[Use the
47 macro! It's smart about NULL pointers.\]
48
49 Typically, the user header is not present. User headers allow for other
50 data structures to be built atop vppinfra vectors. Users may specify the
51 alignment for first data element of a vector via the \[vec\]()\*\_aligned
52 macros.
53
54 Vector elements can be any C type e.g. (int, double, struct bar). This
55 is also true for data types built atop vectors (e.g. heap, pool, etc.).
56 Many macros have \_a variants supporting alignment of vector elements
57 and \_h variants supporting non-zero-length vector headers. The \_ha
58 variants support both.  Additionally cacheline alignment within a
59 vector element structure can be specified using the
60 \[CLIB_CACHE_LINE_ALIGN_MARK\]() macro.
61
62 Inconsistent usage of header and/or alignment related macro variants
63 will cause delayed, confusing failures.
64
65 Standard programming error: memorize a pointer to the ith element of a
66 vector, and then expand the vector. Vectors expand by 3/2, so such code
67 may appear to work for a period of time. Correct code almost always
68 memorizes vector **indices** which are invariant across reallocations.
69
70 In typical application images, one supplies a set of global functions
71 designed to be called from gdb. Here are a few examples:
72
73 -   vl(v) - prints vec\_len(v)
74 -   pe(p) - prints pool\_elts(p)
75 -   pifi(p, index) - prints pool\_is\_free\_index(p, index)
76 -   debug\_hex\_bytes (p, nbytes) - hex memory dump nbytes starting at p
77
78 Use the "show gdb" debug CLI command to print the current set.
79
80 Bitmaps
81 -------
82
83 Vppinfra bitmaps are dynamic, built using the vppinfra vector APIs.
84 Quite handy for a variety jobs.
85
86 Pools
87 -----
88
89 Vppinfra pools combine vectors and bitmaps to rapidly allocate and free
90 fixed-size data structures with independent lifetimes. Pools are perfect
91 for allocating per-session structures.
92
93 Hashes
94 ------
95
96 Vppinfra provides several hash flavors. Data plane problems involving
97 packet classification / session lookup often use
98 ./src/vppinfra/bihash\_template.\[ch\] bounded-index extensible
99 hashes. These templates are instantiated multiple times, to efficiently
100 service different fixed-key sizes.
101
102 Bihashes are thread-safe. Read-locking is not required. A simple
103 spin-lock ensures that only one thread writes an entry at a time.
104
105 The original vppinfra hash implementation in
106 ./src/vppinfra/hash.\[ch\] are simple to use, and are often used in
107 control-plane code which needs exact-string-matching.
108
109 In either case, one almost always looks up a key in a hash table to
110 obtain an index in a related vector or pool. The APIs are simple enough,
111 but one must take care when using the unmanaged arbitrary-sized key
112 variant. Hash\_set\_mem (hash\_table, key\_pointer, value) memorizes
113 key\_pointer. It is usually a bad mistake to pass the address of a
114 vector element as the second argument to hash\_set\_mem. It is perfectly
115 fine to memorize constant string addresses in the text segment.
116
117 Format
118 ------
119
120 Vppinfra format is roughly equivalent to printf.
121
122 Format has a few properties worth mentioning. Format's first argument is
123 a (u8 \*) vector to which it appends the result of the current format
124 operation. Chaining calls is very easy:
125
126 ```c
127     u8 * result;
128
129     result = format (0, "junk = %d, ", junk);
130     result = format (result, "more junk = %d\n", more_junk);
131 ```
132
133 As previously noted, NULL pointers are perfectly proper 0-length
134 vectors. Format returns a (u8 \*) vector, **not** a C-string. If you
135 wish to print a (u8 \*) vector, use the "%v" format string. If you need
136 a (u8 \*) vector which is also a proper C-string, either of these
137 schemes may be used:
138
139 ```c
140     vec_add1 (result, 0)
141     or
142     result = format (result, "<whatever>%c", 0);
143 ```
144
145 Remember to vec\_free() the result if appropriate. Be careful not to
146 pass format an uninitialized (u8 \*).
147
148 Format implements a particularly handy user-format scheme via the "%U"
149 format specification. For example:
150
151 ```c
152     u8 * format_junk (u8 * s, va_list *va)
153     {
154       junk = va_arg (va, u32);
155       s = format (s, "%s", junk);
156       return s;
157     }
158
159     result = format (0, "junk = %U, format_junk, "This is some junk");
160 ```
161
162 format\_junk() can invoke other user-format functions if desired. The
163 programmer shoulders responsibility for argument type-checking. It is
164 typical for user format functions to blow up spectacularly if the
165 va\_arg(va, type) macros don't match the caller's idea of reality.
166
167 Unformat
168 --------
169
170 Vppinfra unformat is vaguely related to scanf, but considerably more
171 general.
172
173 A typical use case involves initializing an unformat\_input\_t from
174 either a C-string or a (u8 \*) vector, then parsing via unformat() as
175 follows:
176
177 ```c
178     unformat_input_t input;
179
180     unformat_init_string (&input, "<some-C-string>");
181     /* or */
182     unformat_init_vector (&input, <u8-vector>);
183 ```
184
185 Then loop parsing individual elements:
186
187 ```c
188     while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT)
189     {
190       if (unformat (&input, "value1 %d", &value1))
191         ;/* unformat sets value1 */
192       else if (unformat (&input, "value2 %d", &value2)
193         ;/* unformat sets value2 */
194       else
195         return clib_error_return (0, "unknown input '%U'",
196                                   format_unformat_error, input);
197     }
198 ```
199
200 As with format, unformat implements a user-unformat function capability
201 via a "%U" user unformat function scheme. Generally, one can trivially
202 transform "format (s, "foo %d", foo) -> "unformat (input, "foo %d", &foo)".
203
204 Unformat implements a couple of handy non-scanf-like format specifiers:
205
206 ```c
207     unformat (input, "enable %=", &enable, 1 /* defaults to 1 */);
208     unformat (input, "bitzero %|", &mask, (1<<0));
209     unformat (input, "bitone %|", &mask, (1<<1));
210     <etc>
211 ```
212
213 The phrase "enable %=" means "set the supplied variable to the default
214 value" if unformat parses the "enable" keyword all by itself. If
215 unformat parses "enable 123" set the supplied variable to 123.
216
217 We could clean up a number of hand-rolled "verbose" + "verbose %d"
218 argument parsing codes using "%=".
219
220 The phrase "bitzero %|" means "set the specified bit in the supplied
221 bitmask" if unformat parses "bitzero". Although it looks like it could
222 be fairly handy, it's very lightly used in the code base.
223
224 ### How to parse a single input line
225
226 Debug CLI command functions MUST NOT accidentally consume input
227 belonging to other debug CLI commands. Otherwise, it's impossible to
228 script a set of debug CLI commands which "work fine" when issued one
229 at a time.
230
231 This bit of code is NOT correct:
232
233 ```c
234   /* Eats script input NOT beloging to it, and chokes! */
235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
236     {
237       if (unformat (input, ...))
238         ;
239       else if (unformat (input, ...))
240         ;
241       else
242         return clib_error_return (0, "parse error: '%U'",
243                                      format_unformat_error, input);
244         }
245     }
246 ```
247
248 When executed as part of a script, such a function will return "parse
249 error: '<next-command-text>'" every time, unless it happens to be the
250 last command in the script.
251
252 Instead, use "unformat_line_input" to consume the rest of a line's
253 worth of input - everything past the path specified in the
254 VLIB_CLI_COMMAND declaration.
255
256 For example, unformat_line_input with "my_command" set up as shown
257 below and user input "my path is clear" will produce an
258 unformat_input_t that contains "is clear".
259
260 ```c
261     VLIB_CLI_COMMAND (...) = {
262         .path = "my path",
263     };
264 ```
265
266 Here's a bit of code which shows the required mechanics, in full:
267
268 ```c
269     static clib_error_t *
270     my_command_fn (vlib_main_t * vm,
271                    unformat_input_t * input,
272                    vlib_cli_command_t * cmd)
273     {
274       unformat_input_t _line_input, *line_input = &_line_input;
275       u32 this, that;
276       clib_error_t *error = 0;
277
278       if (!unformat_user (input, unformat_line_input, line_input))
279         return 0;
280
281       /*
282        * Here, UNFORMAT_END_OF_INPUT is at the end of the line we consumed,
283        * not at the end of the script...
284        */
285       while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
286         {
287            if (unformat (line_input, "this %u", &this))
288              ;
289            else if (unformat (line_input, "that %u", &that))
290              ;
291            else
292              {
293                error = clib_error_return (0, "parse error: '%U'",
294                                      format_unformat_error, line_input);
295                goto done;
296              }
297           }
298
299     <do something based on "this" and "that", etc>
300
301     done:
302       unformat_free (line_input);
303       return error;
304     }
305    /* *INDENT-OFF* */
306    VLIB_CLI_COMMAND (my_command, static) = {
307      .path = "my path",
308      .function = my_command_fn",
309    };
310    /* *INDENT-ON* */
311
312 ```
313
314
315 Vppinfra errors and warnings
316 ----------------------------
317
318 Many functions within the vpp dataplane have return-values of type
319 clib\_error\_t \*. Clib\_error\_t's are arbitrary strings with a bit of
320 metadata \[fatal, warning\] and are easy to announce. Returning a NULL
321 clib\_error\_t \* indicates "A-OK, no error."
322
323 Clib\_warning(format-args) is a handy way to add debugging
324 output; clib warnings prepend function:line info to unambiguously locate
325 the message source. Clib\_unix\_warning() adds perror()-style Linux
326 system-call information. In production images, clib\_warnings result in
327 syslog entries.
328
329 Serialization
330 -------------
331
332 Vppinfra serialization support allows the programmer to easily serialize
333 and unserialize complex data structures.
334
335 The underlying primitive serialize/unserialize functions use network
336 byte-order, so there are no structural issues serializing on a
337 little-endian host and unserializing on a big-endian host.