blob: 5b172a8c7582340f1c52a634216ebca4969ae195 [file] [log] [blame]
Nathan Skrzypczakd4a70642021-10-08 14:01:27 +02001VPP API Language
2================
3
4The VPP binary API is a message passing API. The VPP API language is
5used to define a RPC interface between VPP and its control plane. The
6API messages supports shared memory transport and Unix domain sockets
7(SOCK_STREAM).
8
9The wire format is essentially that of a network formatted (big-endian)
10packed C struct.
11
12The VPP API compiler is located in *src/tools/vppapigen* and can
13currently compile to JSON or C (used by the VPP binary itself).
14
15Language definition
16-------------------
17
18Defining a messages
19~~~~~~~~~~~~~~~~~~~
20
21There are 3 types of message exchanges:
22
23- Request/Reply The client sends a request message and the server
24 replies with a single reply message. The convention is that the reply
25 message is named as method_name + \_reply.
26
27- Dump/Detail The client sends a bulk request message to the server,
28 and the server replies with a set of detail messages. These messages
29 may be of different type. A dump/detail call must be enclosed in a
30 control ping block (Otherwise the client will not know the end of the
31 bulk transmission). The method name must end with method + \_dump”,
32 the reply message should be named method + \_details”. The exception
33 here is for the methods that return multiple message types
34 (e.g. sw_interface_dump). The Dump/Detail methods are typically used
35 for acquiring bulk information, like the complete FIB table.
36
37- Events The client can register for getting asynchronous notifications
38 from the server. This is useful for getting interface state changes,
39 and so on. The method name for requesting notifications is
40 conventionally prefixed with want\_”. E.g. want_interface_events”.
41 Which notification types results from an event registration is
42 defined in the service definition.
43
44A message from a client must include the client_index’, an opaque
45cookie identifying the sender, and a context field to let the client
46match request with reply.
47
48An example of a message definition. The client sends the show_version
49request, the server replies with the show_version_reply.
50
51The *client_index* and *context* fields are required in all requests.
52The *context* is returned by the server and is used by the client to
53match up request and reply messages.
54
55.. code-block:: c
56
57 define show_version
58 {
59 u32 client_index;
60 u32 context;
61 };
62 define show_version_reply
63 {
64 u32 context;
65 i32 retval;
66 string program [32];
67 string version [32];
68 string build_date [32];
69 /* The final field can be a variable length argument */
70 string build_directory [];
71 };
72
73The flags are not used by the clients, but have special meaning for some
74of the tracing and debugging of the API. The *autoreply* flag is a
75shorthand for a reply message with just a *retval* field.
76
77.. code-block:: c
78
79 define : DEFINE ID '{' block_statements_opt '}' ';'
80 define : flist DEFINE ID '{' block_statements_opt '}' ';'
81 flist : flag
82 | flist flag
83 flag : MANUAL_PRINT
84 | MANUAL_ENDIAN
85 | DONT_TRACE
86 | AUTOREPLY
87
88 block_statements_opt : block_statements
89 block_statements : block_statement
90 | block_statements block_statement
91 block_statement : declaration
92 | option
93 declaration : type_specifier ID ';'
94 | type_specifier ID '[' ID '=' assignee ']' ';'
95 declaration : type_specifier ID '[' NUM ']' ';'
96 | type_specifier ID '[' ID ']' ';'
97 type_specifier : U8
98 | U16
99 | U32
100 | U64
101 | I8
102 | I16
103 | I32
104 | I64
105 | F64
106 | BOOL
107 | STRING
108 type_specifier : ID
109
110Options
111~~~~~~~
112
113The *option* word is used to specify meta information. The only current
114use is to specify a semantic version of the .api file itself.
115
116Example:
117
118.. code-block:: c
119
120 option version = "1.0.0";
121
122.. code-block:: c
123
124
125 option : OPTION ID '=' assignee ';'
126 assignee : NUM
127 | TRUE
128 | FALSE
129 | STRING_LITERAL
130
131Defining new types
132~~~~~~~~~~~~~~~~~~
133
134New user defined types are defined just like messages. A typedef has two
135forms. It can either define an alias for a different type (or array).
136
137Example:
138
139.. code-block:: c
140
141 typedef u8 ip4_address[4];
142 typedef u8 ip6_address[16];
143
144Where the above defines two new types *vl_api_ip4_address_t* and
145*vl_api_ip6_address_t*. These are aliases for the underlying u8 array.
146
147In the other form, it is used to specify an abstract data type.
148
149.. code-block:: c
150
151 enum address_family {
152 ADDRESS_IP4 = 0,
153 ADDRESS_IP6,
154 };
155
156 union address_union {
157 vl_api_ip4_address_t ip4;
158 vl_api_ip6_address_t ip6;
159 };
160
161 typedef address {
162 vl_api_address_family_t af;
163 vl_api_address_union_t un;
164 };
165
166Where the new type *vl_api_address_t*
167
168.. code-block:: c
169
170 typedef : TYPEDEF ID '{' block_statements_opt '}' ';'
171 typedef : TYPEDEF declaration
172
173Importing Definitions
174~~~~~~~~~~~~~~~~~~~~~
175
176You can use definitions from other .api files by importing them. To
177import another .apis definitions, you add an import statement to the
178top of your file:
179
180import vnet/ip/ip_types.api”;
181
182By default you can only use definitions from directly imported .api
183files.
184
185The API compiler searches for imported files in a set of directories
186specified on the API compiler command line using the includedir flag.
187
188.. code-block:: c
189
190 import : IMPORT STRING_LITERAL ';'
191
192Comments
193~~~~~~~~
194
195The API language uses C style comments.
196
197.. code-block:: c
198
199 /* */
200 //
201
202Enumerations
203~~~~~~~~~~~~
204
205Enums are similar to enums in C.
206
207Every enum definition must contain a constant that maps to zero as its
208first element. This is because:
209
210There must be a zero value, so that we can use 0 as a numeric default
211value. The zero value needs to be the first element.
212
213As in C, enums can be used as flags or just as numbers. The on-wire, and
214in memory representation size of an enum can be specified. Not all
215language bindings will support that. The default size is 4 (u32).
216
217Example
218
219.. code-block:: c
220
221 enum ip_neighbor_flags
222 {
223 IP_API_NEIGHBOR_FLAG_NONE = 0,
224 IP_API_NEIGHBOR_FLAG_STATIC = 0x1,
225 IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY = 0x2,
226 };
227
228Which generates the vl_api_ip_neighbor_flags_t in the C binding. In
229Python that is represented as an IntFlag object
230VppEnum.vl_api_ip_neighbor_flags_t.
231
232.. code-block:: c
233
234 enum : ENUM ID '{' enum_statements '}' ';'
235 enum : ENUM ID ':' enum_size '{' enum_statements '}' ';'
236 enum_size : U8
237 | U16
238 | U32
239 enum_statements : enum_statement
240 | enum_statements enum_statement
241 enum_statement : ID '=' NUM ','
242 | ID ','
243
244Services
245~~~~~~~~
246
247The service statement defines the relationship between messages. For
248request/response and dump/details messages it ties the request with the
249reply. For events, it specifies which events that can be received for a
250given ``want_*`` call.
251
252Example:
253
254.. code-block:: c
255
256 service {
257 rpc want_interface_events returns want_interface_events_reply
258 events sw_interface_event;
259 };
260
261Which states that the request want_interface_events returns a
262want_interface_events_reply and if enabled the client will receive
263sw_interface_event messages whenever interface states changes.
264
265.. code-block:: c
266
267 service : SERVICE '{' service_statements '}' ';'
268 service_statements : service_statement
269 | service_statements service_statement
270 service_statement : RPC ID RETURNS NULL ';'
271 | RPC ID RETURNS ID ';'
272 | RPC ID RETURNS STREAM ID ';'
273 | RPC ID RETURNS ID EVENTS event_list ';'
274 event_list : events
275 | event_list events
276 events : ID
277 | ID ','
278
279Types
280-----
281
282Scalar Value Types
283~~~~~~~~~~~~~~~~~~
284
285========= ======== =============== ===========
286.api type size C type Python type
287========= ======== =============== ===========
288i8 1 i8 int
289u8 1 u8 int
290i16 2 i16 int
291u16 2 u16 int
292i32 4 i32 int
293u32 4 u32 int
294i64 8 i64 int
295u64 8 u64 int
296f64 8 f64 float
297bool 1 bool boolean
298string variable vl_api_string_t str
299========= ======== =============== ===========
300
301User Defined Types
302~~~~~~~~~~~~~~~~~~
303
304vnet/ip/ip_types.api
305^^^^^^^^^^^^^^^^^^^^
306
307+--------------------+--------+-------------+-------------------------+
308| .api type | size | C type | Python type |
309+====================+========+=============+=========================+
310| vl_api_address_t | 20 | vl_ap | ` |
311| | | i_address_t | `<class 'ipaddress.IPv4 |
312| | | | Address'> or <class 'ip |
313| | | | address.IPv6Address'>`` |
314+--------------------+--------+-------------+-------------------------+
315| vl | 4 | vl_api_ip | ``<class 'ip |
316| _api_ip4_address_t | | 4_address_t | address.IPv4Address'>`` |
317+--------------------+--------+-------------+-------------------------+
318| vl | 16 | vl_api_ip | ``<class 'ip |
319| _api_ip6_address_t | | 6_address_t | address.IPv6Address'>`` |
320+--------------------+--------+-------------+-------------------------+
321| vl_api_prefix_t | 21 | vl_a | ` |
322| | | pi_prefix_t | `<class 'ipaddress.IPv4 |
323| | | | Network'> or <class 'ip |
324| | | | address.IPv6Network'>`` |
325+--------------------+--------+-------------+-------------------------+
326| v | 5 | vl_api_i | ``<class 'ip |
327| l_api_ip4_prefix_t | | p4_prefix_t | address.IPv4Network'>`` |
328+--------------------+--------+-------------+-------------------------+
329| v | 17 | vl_api_i | ``<class 'ip |
330| l_api_ip6_prefix_t | | p6_prefix_t | address.IPv6Network'>`` |
331+--------------------+--------+-------------+-------------------------+
332| vl_api_ip4_add | 5 | vl_api_ip4 | ``<class 'ipad |
333| ress_with_prefix_t | | _address_wi | dress.IPv4Interface'>`` |
334| | | th_prefix_t | |
335+--------------------+--------+-------------+-------------------------+
336| vl_api_ip6_add | 17 | vl_api_ip6 | ``<class 'ipad |
337| ress_with_prefix_t | | _address_wi | dress.IPv6Interface'>`` |
338| | | th_prefix_t | |
339+--------------------+--------+-------------+-------------------------+
340
341vnet/ethernet/ethernet_types.api
342^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
343
344+---------------------+------+---------------------+-------------------+
345| .api type | size | C type | Python type |
346+=====================+======+=====================+===================+
347| ``vl_ | 6 | ``vl_ | ``class 'vpp_pa |
348| api_mac_address_t`` | | api_mac_address_t`` | pi.MACAddress'>`` |
349+---------------------+------+---------------------+-------------------+
350
351vnet/interface_types.api
352^^^^^^^^^^^^^^^^^^^^^^^^
353
354======================== ==== ======================== ===========
355.api type size C type Python type
356======================== ==== ======================== ===========
357vl_api_interface_index_t 4 vl_api_interface_index_t int
358======================== ==== ======================== ===========
359
360New explicit types
361~~~~~~~~~~~~~~~~~~
362
363String versus bytes
364^^^^^^^^^^^^^^^^^^^
365
366A byte string with a maximum length of 64:
367
368.. code-block:: c
369
370 u8 name[64];
371
372Before the string type was added, text string were defined like this.
373The implications of that was the user would have to know if the field
374represented a \\0 ended C-string or a fixed length byte string. The wire
375format of the string type is a u32 length
376
377An IPv4 or IPv6 address was previously defined like:
378
379.. code-block:: c
380
381 u8 is_ip6;
382 u8 address[16];
383
384Which made it hard for language bindings to represent the address as
385anything but a byte string. The new explicit address types are shown
386above.
387
388Language generators
389-------------------
390
391The VPP API compiler currently has two output modules. One generating
392JSON and one generating C header files that are directly used by the VPP
393infrastructure and plugins.
394
395The C/C++, Python, Go Lua, and Java language bindings are generated
396based on the JSON files.
397
398Future considerations
399~~~~~~~~~~~~~~~~~~~~~
400
401- Generate C/C++ (vapi) client code directly from vppapigen
402- Embed JSON definitions into the API server, so dynamic languages
403 can download them directly without going via the filesystem and JSON
404 files.