1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020 Intel Corporation
4 #ifndef __INCLUDE_RTE_SWX_PIPELINE_H__
5 #define __INCLUDE_RTE_SWX_PIPELINE_H__
19 #include <rte_compat.h>
21 #include "rte_swx_port.h"
22 #include "rte_swx_table.h"
23 #include "rte_swx_extern.h"
26 #ifndef RTE_SWX_NAME_SIZE
27 #define RTE_SWX_NAME_SIZE 64
30 * Pipeline setup and operation
33 /** Pipeline opaque data structure. */
34 struct rte_swx_pipeline;
40 * Pipeline handle. Must point to valid memory. Contains valid pipeline handle
41 * when the function returns successfully.
42 * @param[in] numa_node
43 * Non-Uniform Memory Access (NUMA) node.
45 * 0 on success or the following error codes otherwise:
46 * -EINVAL: Invalid argument;
47 * -ENOMEM: Not enough space/cannot allocate memory.
51 rte_swx_pipeline_config(struct rte_swx_pipeline **p,
55 * Pipeline input ports
59 * Pipeline input port type register
64 * Input port type name.
66 * Input port type operations.
68 * 0 on success or the following error codes otherwise:
69 * -EINVAL: Invalid argument;
70 * -ENOMEM: Not enough space/cannot allocate memory;
71 * -EEXIST: Input port type with this name already exists.
75 rte_swx_pipeline_port_in_type_register(struct rte_swx_pipeline *p,
77 struct rte_swx_port_in_ops *ops);
80 * Pipeline input port configure
86 * @param[in] port_type_name
87 * Existing input port type name.
89 * Input port creation arguments.
91 * 0 on success or the following error codes otherwise:
92 * -EINVAL: Invalid argument;
93 * -ENOMEM: Not enough space/cannot allocate memory;
94 * -ENODEV: Input port object creation error.
98 rte_swx_pipeline_port_in_config(struct rte_swx_pipeline *p,
100 const char *port_type_name,
104 * Pipeline output ports
108 * Pipeline output port type register
113 * Output port type name.
115 * Output port type operations.
117 * 0 on success or the following error codes otherwise:
118 * -EINVAL: Invalid argument;
119 * -ENOMEM: Not enough space/cannot allocate memory;
120 * -EEXIST: Output port type with this name already exists.
124 rte_swx_pipeline_port_out_type_register(struct rte_swx_pipeline *p,
126 struct rte_swx_port_out_ops *ops);
129 * Pipeline output port configure
135 * @param[in] port_type_name
136 * Existing output port type name.
138 * Output port creation arguments.
140 * 0 on success or the following error codes otherwise:
141 * -EINVAL: Invalid argument;
142 * -ENOMEM: Not enough space/cannot allocate memory;
143 * -ENODEV: Output port object creation error.
147 rte_swx_pipeline_port_out_config(struct rte_swx_pipeline *p,
149 const char *port_type_name,
153 * Extern objects and functions
157 * Pipeline extern type register
163 * @param[in] mailbox_struct_type_name
164 * Name of existing struct type used to define the mailbox size and layout for
165 * the extern objects that are instances of this type. Each extern object gets
166 * its own mailbox, which is used to pass the input arguments to the member
167 * functions and retrieve the output results.
168 * @param[in] constructor
169 * Function used to create the extern objects that are instances of this type.
170 * @param[in] destructor
171 * Function used to free the extern objects that are instances of this type.
173 * 0 on success or the following error codes otherwise:
174 * -EINVAL: Invalid argument;
175 * -ENOMEM: Not enough space/cannot allocate memory;
176 * -EEXIST: Extern type with this name already exists.
180 rte_swx_pipeline_extern_type_register(struct rte_swx_pipeline *p,
182 const char *mailbox_struct_type_name,
183 rte_swx_extern_type_constructor_t constructor,
184 rte_swx_extern_type_destructor_t destructor);
187 * Pipeline extern type member function register
191 * @param[in] extern_type_name
192 * Existing extern type name.
194 * Name for the new member function to be added to the extern type.
195 * @param[in] member_func
196 * The new member function.
198 * 0 on success or the following error codes otherwise:
199 * -EINVAL: Invalid argument;
200 * -ENOMEM: Not enough space/cannot allocate memory;
201 * -EEXIST: Member function with this name already exists for this type;
202 * -ENOSPC: Maximum number of member functions reached for this type.
206 rte_swx_pipeline_extern_type_member_func_register(struct rte_swx_pipeline *p,
207 const char *extern_type_name,
209 rte_swx_extern_type_member_func_t member_func);
212 * Pipeline extern object configure
214 * Instantiate a given extern type to create new extern object.
218 * @param[in] extern_type_name
219 * Existing extern type name.
221 * Name for the new object instantiating the extern type.
223 * Extern object constructor arguments.
225 * 0 on success or the following error codes otherwise:
226 * -EINVAL: Invalid argument;
227 * -ENOMEM: Not enough space/cannot allocate memory;
228 * -EEXIST: Extern object with this name already exists;
229 * -ENODEV: Extern object constructor error.
233 rte_swx_pipeline_extern_object_config(struct rte_swx_pipeline *p,
234 const char *extern_type_name,
239 * Pipeline extern function register
244 * Extern function name.
245 * @param[in] mailbox_struct_type_name
246 * Name of existing struct type used to define the mailbox size and layout for
247 * this extern function. The mailbox is used to pass the input arguments to
248 * the extern function and retrieve the output results.
250 * The extern function.
252 * 0 on success or the following error codes otherwise:
253 * -EINVAL: Invalid argument;
254 * -ENOMEM: Not enough space/cannot allocate memory;
255 * -EEXIST: Extern function with this name already exists.
259 rte_swx_pipeline_extern_func_register(struct rte_swx_pipeline *p,
261 const char *mailbox_struct_type_name,
262 rte_swx_extern_func_t func);
265 * Packet headers and meta-data
268 /** Structure (struct) field. */
269 struct rte_swx_field_params {
270 /** Struct field name. */
273 /** Struct field size (in bits).
274 * Restriction: All struct fields must be a multiple of 8 bits.
275 * Restriction: All struct fields must be no greater than 64 bits.
281 * Pipeline struct type register
283 * Structs are used extensively in many part of the pipeline to define the size
284 * and layout of a specific memory piece such as: headers, meta-data, action
285 * data stored in a table entry, mailboxes for extern objects and functions.
286 * Similar to C language structs, they are a well defined sequence of fields,
287 * with each field having a unique name and a constant size.
294 * The sequence of struct fields.
295 * @param[in] n_fields
296 * The number of struct fields.
298 * 0 on success or the following error codes otherwise:
299 * -EINVAL: Invalid argument;
300 * -ENOMEM: Not enough space/cannot allocate memory;
301 * -EEXIST: Struct type with this name already exists.
305 rte_swx_pipeline_struct_type_register(struct rte_swx_pipeline *p,
307 struct rte_swx_field_params *fields,
311 * Pipeline packet header register
317 * @param[in] struct_type_name
318 * The struct type instantiated by this packet header.
320 * 0 on success or the following error codes otherwise:
321 * -EINVAL: Invalid argument;
322 * -ENOMEM: Not enough space/cannot allocate memory;
323 * -EEXIST: Header with this name already exists;
324 * -ENOSPC: Maximum number of headers reached for the pipeline.
328 rte_swx_pipeline_packet_header_register(struct rte_swx_pipeline *p,
330 const char *struct_type_name);
333 * Pipeline packet meta-data register
337 * @param[in] struct_type_name
338 * The struct type instantiated by the packet meta-data.
340 * 0 on success or the following error codes otherwise:
341 * -EINVAL: Invalid argument.
345 rte_swx_pipeline_packet_metadata_register(struct rte_swx_pipeline *p,
346 const char *struct_type_name);
353 * Instruction operands:
355 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
356 *<pre>| | Description | Format | DST | SRC |</pre>
357 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
358 *<pre>| hdr | Header | h.header | | |</pre>
359 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
360 *<pre>| act | Action | ACTION | | |</pre>
361 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
362 *<pre>| tbl | Table | TABLE | | |</pre>
363 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
364 *<pre>| H | Header field | h.header.field | YES | YES |</pre>
365 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
366 *<pre>| M | Meta-data field | m.field | YES | YES |</pre>
367 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
368 *<pre>| E | Extern obj mailbox field | e.ext_obj.field | YES | YES |</pre>
369 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
370 *<pre>| F | Extern func mailbox field | f.ext_func.field | YES | YES |</pre>
371 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
372 *<pre>| T | Table action data field | t.header.field | NO | YES |</pre>
373 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
374 *<pre>| I | Immediate value (32-bit) | h.header.field | NO | YES |</pre>
375 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
379 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
380 *<pre>| Instr. | Instruction | Instruction | 1st | 2nd |</pre>
381 *<pre>| Name | Description | Format | opnd.| opnd. |</pre>
382 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
383 *<pre>| rx | Receive one pkt | rx m.port_in | M | |</pre>
384 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
385 *<pre>| tx | Transmit one pkt | tx m.port_out | M | |</pre>
386 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
387 *<pre>| extract | Extract one hdr | extract h.hdr | hdr | |</pre>
388 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
389 *<pre>| emit | Emit one hdr | emit h.hdr | hdr | |</pre>
390 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
391 *<pre>| validate | Validate one hdr | validate h.hdr | hdr | |</pre>
392 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
393 *<pre>| invalidate | Invalidate one hdr | invalidate h.hdr | hdr | |</pre>
394 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
395 *<pre>| mov | dst = src | mov dst src | HMEF | HMEFTI |</pre>
396 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
397 *<pre>| dma | memcpy(h.hdr, | dma h.hdr t.field | hdr | T |</pre>
398 *<pre>| | &t.field, | | | |</pre>
399 *<pre>| | sizeof(h.hdr) | | | |</pre>
400 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
401 *<pre>| add | dst += src | add dst src | HMEF | HMEFTI |</pre>
402 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
403 *<pre>| sub | dst -= src | add dst src | HMEF | HMEFTI |</pre>
404 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
405 *<pre>| ckadd | Checksum add: dst = | add dst src | HMEF | HMEFTI |</pre>
406 *<pre>| | dst '+ src[0:1] '+ | | | or hdr |</pre>
407 *<pre>| | src[2:3] '+ ... | | | |</pre>
408 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
409 *<pre>| cksub | Checksum subtract: | add dst src | HMEF | HMEFTI |</pre>
410 *<pre>| | dst = dst '- src | | | |</pre>
411 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
412 *<pre>| and | dst &= src | and dst src | HMEF | HMEFTI |</pre>
413 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
414 *<pre>| or | dst |= src | or dst src | HMEF | HMEFTI |</pre>
415 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
416 *<pre>| xor | dst ^= src | xor dst src | HMEF | HMEFTI |</pre>
417 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
418 *<pre>| shl | dst <<= src | shl dst src | HMEF | HMEFTI |</pre>
419 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
420 *<pre>| shr | dst >>= src | shr dst src | HMEF | HMEFTI |</pre>
421 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
422 *<pre>| table | Table lookup | table TABLE | tbl | |</pre>
423 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
424 *<pre>| extern | Ext obj member func | extern e.obj.mfunc| ext | |</pre>
425 *<pre>| | call or ext func call| extern f.func | | |</pre>
426 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
427 *<pre>| jmp | Unconditional jump | jmp LABEL | | |</pre>
428 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
429 *<pre>| jmpv | Jump if hdr is valid | jmpv LABEL h.hdr | hdr | |</pre>
430 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
431 *<pre>| jmpnv | Jump if hdr is inval | jmpnv LABEL h.hdr | hdr | |</pre>
432 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
433 *<pre>| jmph | Jump if tbl lkp hit | jmph LABEL | | |</pre>
434 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
435 *<pre>| jmpnh | Jump if tbl lkp miss | jmpnh LABEL | | |</pre>
436 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
437 *<pre>| jmpa | Jump if action run | jmpa LABEL ACTION | act | |</pre>
438 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
439 *<pre>| jmpna | Jump if act not run | jmpna LABEL ACTION| act | |</pre>
440 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
441 *<pre>| jmpeq | Jump if (a == b) | jmpeq LABEL a b | HMEFT| HMEFTI |</pre>
442 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
443 *<pre>| jmpneq | Jump if (a != b) | jmpneq LABEL a b | HMEFT| HMEFTI |</pre>
444 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
445 *<pre>| jmplt | Jump if (a < b) | jmplt LABEL a b | HMEFT| HMEFTI |</pre>
446 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
447 *<pre>| jmpgt | Jump if (a > b) | jmpgt LABEL a b | HMEFT| HMEFTI |</pre>
448 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
449 *<pre>| return | Return from action | return | | |</pre>
450 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
452 * At initialization time, the pipeline and action instructions (including the
453 * symbolic name operands) are translated to internal data structures that are
462 * Pipeline action configure
468 * @param[in] args_struct_type_name
469 * The struct type instantiated by the action data. The action data represent
470 * the action arguments that are stored in the table entry together with the
471 * action ID. Set to NULL when the action does not have any arguments.
472 * @param[in] instructions
473 * Action instructions.
474 * @param[in] n_instructions
475 * Number of action instructions.
477 * 0 on success or the following error codes otherwise:
478 * -EINVAL: Invalid argument;
479 * -ENOMEM: Not enough space/cannot allocate memory;
480 * -EEXIST: Action with this name already exists.
484 rte_swx_pipeline_action_config(struct rte_swx_pipeline *p,
486 const char *args_struct_type_name,
487 const char **instructions,
488 uint32_t n_instructions);
495 * Pipeline table type register
501 * @param[in] match_type
502 * Match type implemented by the new table type.
504 * Table type operations.
506 * 0 on success or the following error codes otherwise:
507 * -EINVAL: Invalid argument;
508 * -ENOMEM: Not enough space/cannot allocate memory;
509 * -EEXIST: Table type with this name already exists.
513 rte_swx_pipeline_table_type_register(struct rte_swx_pipeline *p,
515 enum rte_swx_table_match_type match_type,
516 struct rte_swx_table_ops *ops);
518 /** Match field parameters. */
519 struct rte_swx_match_field_params {
520 /** Match field name. Must be either a field of one of the registered
521 * packet headers ("h.header.field") or a field of the registered
522 * meta-data ("m.field").
526 /** Match type of the field. */
527 enum rte_swx_table_match_type match_type;
530 /** Pipeline table parameters. */
531 struct rte_swx_pipeline_table_params {
532 /** The set of match fields for the current table.
533 * Restriction: All the match fields of the current table need to be
534 * part of the same struct, i.e. either all the match fields are part of
535 * the same header or all the match fields are part of the meta-data.
537 struct rte_swx_match_field_params *fields;
539 /** The number of match fields for the current table. If set to zero, no
540 * "regular" entries (i.e. entries other than the default entry) can be
541 * added to the current table and the match process always results in
546 /** The set of actions for the current table. */
547 const char **action_names;
549 /** The number of actions for the current table. Must be at least one.
553 /** The default table action that gets executed on lookup miss. Must be
554 * one of the table actions included in the *action_names*.
556 const char *default_action_name;
558 /** Default action data. The size of this array is the action data size
559 * of the default action. Must be NULL if the default action data size
562 uint8_t *default_action_data;
564 /** If non-zero (true), then the default action of the current table
565 * cannot be changed. If zero (false), then the default action can be
566 * changed in the future with another action from the *action_names*
569 int default_action_is_const;
573 * Pipeline table configure
581 * @param[in] recommended_table_type_name
582 * Recommended table type. Typically set to NULL. Useful as guidance when
583 * there are multiple table types registered for the match type of the table,
584 * as determined from the table match fields specification. Silently ignored
585 * if the recommended table type does not exist or it serves a different match
588 * Table creation arguments.
590 * Guideline on maximum number of table entries.
592 * 0 on success or the following error codes otherwise:
593 * -EINVAL: Invalid argument;
594 * -ENOMEM: Not enough space/cannot allocate memory;
595 * -EEXIST: Table with this name already exists;
596 * -ENODEV: Table creation error.
600 rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,
602 struct rte_swx_pipeline_table_params *params,
603 const char *recommended_table_type_name,
608 * Pipeline instructions configure
612 * @param[in] instructions
613 * Pipeline instructions.
614 * @param[in] n_instructions
615 * Number of pipeline instructions.
617 * 0 on success or the following error codes otherwise:
618 * -EINVAL: Invalid argument;
619 * -ENOMEM: Not enough space/cannot allocate memory.
623 rte_swx_pipeline_instructions_config(struct rte_swx_pipeline *p,
624 const char **instructions,
625 uint32_t n_instructions);
630 * Once called, the pipeline build operation marks the end of pipeline
631 * configuration. At this point, all the internal data structures needed to run
632 * the pipeline are built.
637 * 0 on success or the following error codes otherwise:
638 * -EINVAL: Invalid argument;
639 * -ENOMEM: Not enough space/cannot allocate memory;
640 * -EEXIST: Pipeline was already built successfully.
644 rte_swx_pipeline_build(struct rte_swx_pipeline *p);
647 * Pipeline build from specification file
652 * Pipeline specification file.
653 * @param[out] err_line
654 * In case of error and non-NULL, the line number within the *spec* file where
655 * the error occurred. The first line number in the file is 1.
656 * @param[out] err_msg
657 * In case of error and non-NULL, the error message.
659 * 0 on success or the following error codes otherwise:
660 * -EINVAL: Invalid argument;
661 * -ENOMEM: Not enough space/cannot allocate memory;
662 * -EEXIST: Resource with the same name already exists;
663 * -ENODEV: Extern object or table creation error.
667 rte_swx_pipeline_build_from_spec(struct rte_swx_pipeline *p,
670 const char **err_msg);
677 * @param[in] n_instructions
678 * Number of instructions to execute.
682 rte_swx_pipeline_run(struct rte_swx_pipeline *p,
683 uint32_t n_instructions);
688 * Flush all output ports of the pipeline.
695 rte_swx_pipeline_flush(struct rte_swx_pipeline *p);
705 rte_swx_pipeline_free(struct rte_swx_pipeline *p);