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 /** Instruction size. */
31 #ifndef RTE_SWX_INSTRUCTION_SIZE
32 #define RTE_SWX_INSTRUCTION_SIZE 256
35 /** Instruction tokens. */
36 #ifndef RTE_SWX_INSTRUCTION_TOKENS_MAX
37 #define RTE_SWX_INSTRUCTION_TOKENS_MAX 16
41 * Pipeline setup and operation
44 /** Pipeline opaque data structure. */
45 struct rte_swx_pipeline;
51 * Pipeline handle. Must point to valid memory. Contains valid pipeline handle
52 * when the function returns successfully.
53 * @param[in] numa_node
54 * Non-Uniform Memory Access (NUMA) node.
56 * 0 on success or the following error codes otherwise:
57 * -EINVAL: Invalid argument;
58 * -ENOMEM: Not enough space/cannot allocate memory.
62 rte_swx_pipeline_config(struct rte_swx_pipeline **p,
66 * Pipeline input ports
70 * Pipeline input port type register
75 * Input port type name.
77 * Input port type operations.
79 * 0 on success or the following error codes otherwise:
80 * -EINVAL: Invalid argument;
81 * -ENOMEM: Not enough space/cannot allocate memory;
82 * -EEXIST: Input port type with this name already exists.
86 rte_swx_pipeline_port_in_type_register(struct rte_swx_pipeline *p,
88 struct rte_swx_port_in_ops *ops);
91 * Pipeline input port configure
97 * @param[in] port_type_name
98 * Existing input port type name.
100 * Input port creation arguments.
102 * 0 on success or the following error codes otherwise:
103 * -EINVAL: Invalid argument;
104 * -ENOMEM: Not enough space/cannot allocate memory;
105 * -ENODEV: Input port object creation error.
109 rte_swx_pipeline_port_in_config(struct rte_swx_pipeline *p,
111 const char *port_type_name,
115 * Pipeline output ports
119 * Pipeline output port type register
124 * Output port type name.
126 * Output port type operations.
128 * 0 on success or the following error codes otherwise:
129 * -EINVAL: Invalid argument;
130 * -ENOMEM: Not enough space/cannot allocate memory;
131 * -EEXIST: Output port type with this name already exists.
135 rte_swx_pipeline_port_out_type_register(struct rte_swx_pipeline *p,
137 struct rte_swx_port_out_ops *ops);
140 * Pipeline output port configure
146 * @param[in] port_type_name
147 * Existing output port type name.
149 * Output port creation arguments.
151 * 0 on success or the following error codes otherwise:
152 * -EINVAL: Invalid argument;
153 * -ENOMEM: Not enough space/cannot allocate memory;
154 * -ENODEV: Output port object creation error.
158 rte_swx_pipeline_port_out_config(struct rte_swx_pipeline *p,
160 const char *port_type_name,
164 * Extern objects and functions
168 * Pipeline extern type register
174 * @param[in] mailbox_struct_type_name
175 * Name of existing struct type used to define the mailbox size and layout for
176 * the extern objects that are instances of this type. Each extern object gets
177 * its own mailbox, which is used to pass the input arguments to the member
178 * functions and retrieve the output results.
179 * @param[in] constructor
180 * Function used to create the extern objects that are instances of this type.
181 * @param[in] destructor
182 * Function used to free the extern objects that are instances of this type.
184 * 0 on success or the following error codes otherwise:
185 * -EINVAL: Invalid argument;
186 * -ENOMEM: Not enough space/cannot allocate memory;
187 * -EEXIST: Extern type with this name already exists.
191 rte_swx_pipeline_extern_type_register(struct rte_swx_pipeline *p,
193 const char *mailbox_struct_type_name,
194 rte_swx_extern_type_constructor_t constructor,
195 rte_swx_extern_type_destructor_t destructor);
198 * Pipeline extern type member function register
202 * @param[in] extern_type_name
203 * Existing extern type name.
205 * Name for the new member function to be added to the extern type.
206 * @param[in] member_func
207 * The new member function.
209 * 0 on success or the following error codes otherwise:
210 * -EINVAL: Invalid argument;
211 * -ENOMEM: Not enough space/cannot allocate memory;
212 * -EEXIST: Member function with this name already exists for this type;
213 * -ENOSPC: Maximum number of member functions reached for this type.
217 rte_swx_pipeline_extern_type_member_func_register(struct rte_swx_pipeline *p,
218 const char *extern_type_name,
220 rte_swx_extern_type_member_func_t member_func);
223 * Pipeline extern object configure
225 * Instantiate a given extern type to create new extern object.
229 * @param[in] extern_type_name
230 * Existing extern type name.
232 * Name for the new object instantiating the extern type.
234 * Extern object constructor arguments.
236 * 0 on success or the following error codes otherwise:
237 * -EINVAL: Invalid argument;
238 * -ENOMEM: Not enough space/cannot allocate memory;
239 * -EEXIST: Extern object with this name already exists;
240 * -ENODEV: Extern object constructor error.
244 rte_swx_pipeline_extern_object_config(struct rte_swx_pipeline *p,
245 const char *extern_type_name,
250 * Pipeline extern function register
255 * Extern function name.
256 * @param[in] mailbox_struct_type_name
257 * Name of existing struct type used to define the mailbox size and layout for
258 * this extern function. The mailbox is used to pass the input arguments to
259 * the extern function and retrieve the output results.
261 * The extern function.
263 * 0 on success or the following error codes otherwise:
264 * -EINVAL: Invalid argument;
265 * -ENOMEM: Not enough space/cannot allocate memory;
266 * -EEXIST: Extern function with this name already exists.
270 rte_swx_pipeline_extern_func_register(struct rte_swx_pipeline *p,
272 const char *mailbox_struct_type_name,
273 rte_swx_extern_func_t func);
276 * Packet headers and meta-data
279 /** Structure (struct) field. */
280 struct rte_swx_field_params {
281 /** Struct field name. */
284 /** Struct field size (in bits).
285 * Restriction: All struct fields must be a multiple of 8 bits.
286 * Restriction: All struct fields must be no greater than 64 bits.
292 * Pipeline struct type register
294 * Structs are used extensively in many part of the pipeline to define the size
295 * and layout of a specific memory piece such as: headers, meta-data, action
296 * data stored in a table entry, mailboxes for extern objects and functions.
297 * Similar to C language structs, they are a well defined sequence of fields,
298 * with each field having a unique name and a constant size.
305 * The sequence of struct fields.
306 * @param[in] n_fields
307 * The number of struct fields.
309 * 0 on success or the following error codes otherwise:
310 * -EINVAL: Invalid argument;
311 * -ENOMEM: Not enough space/cannot allocate memory;
312 * -EEXIST: Struct type with this name already exists.
316 rte_swx_pipeline_struct_type_register(struct rte_swx_pipeline *p,
318 struct rte_swx_field_params *fields,
322 * Pipeline packet header register
328 * @param[in] struct_type_name
329 * The struct type instantiated by this packet header.
331 * 0 on success or the following error codes otherwise:
332 * -EINVAL: Invalid argument;
333 * -ENOMEM: Not enough space/cannot allocate memory;
334 * -EEXIST: Header with this name already exists;
335 * -ENOSPC: Maximum number of headers reached for the pipeline.
339 rte_swx_pipeline_packet_header_register(struct rte_swx_pipeline *p,
341 const char *struct_type_name);
344 * Pipeline packet meta-data register
348 * @param[in] struct_type_name
349 * The struct type instantiated by the packet meta-data.
351 * 0 on success or the following error codes otherwise:
352 * -EINVAL: Invalid argument.
356 rte_swx_pipeline_packet_metadata_register(struct rte_swx_pipeline *p,
357 const char *struct_type_name);
364 * Instruction operands:
366 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
367 *<pre>| | Description | Format | DST | SRC |</pre>
368 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
369 *<pre>| hdr | Header | h.header | | |</pre>
370 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
371 *<pre>| act | Action | ACTION | | |</pre>
372 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
373 *<pre>| tbl | Table | TABLE | | |</pre>
374 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
375 *<pre>| H | Header field | h.header.field | YES | YES |</pre>
376 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
377 *<pre>| M | Meta-data field | m.field | YES | YES |</pre>
378 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
379 *<pre>| E | Extern obj mailbox field | e.ext_obj.field | YES | YES |</pre>
380 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
381 *<pre>| F | Extern func mailbox field | f.ext_func.field | YES | YES |</pre>
382 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
383 *<pre>| T | Table action data field | t.header.field | NO | YES |</pre>
384 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
385 *<pre>| I | Immediate value (32-bit) | h.header.field | NO | YES |</pre>
386 *<pre>+-----+---------------------------+------------------+-----+-----+</pre>
390 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
391 *<pre>| Instr. | Instruction | Instruction | 1st | 2nd |</pre>
392 *<pre>| Name | Description | Format | opnd.| opnd. |</pre>
393 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
394 *<pre>| rx | Receive one pkt | rx m.port_in | M | |</pre>
395 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
396 *<pre>| tx | Transmit one pkt | tx m.port_out | M | |</pre>
397 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
398 *<pre>| extract | Extract one hdr | extract h.hdr | hdr | |</pre>
399 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
400 *<pre>| emit | Emit one hdr | emit h.hdr | hdr | |</pre>
401 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
402 *<pre>| validate | Validate one hdr | validate h.hdr | hdr | |</pre>
403 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
404 *<pre>| invalidate | Invalidate one hdr | invalidate h.hdr | hdr | |</pre>
405 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
406 *<pre>| mov | dst = src | mov dst src | HMEF | HMEFTI |</pre>
407 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
408 *<pre>| dma | memcpy(h.hdr, | dma h.hdr t.field | hdr | T |</pre>
409 *<pre>| | &t.field, | | | |</pre>
410 *<pre>| | sizeof(h.hdr) | | | |</pre>
411 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
412 *<pre>| add | dst += src | add dst src | HMEF | HMEFTI |</pre>
413 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
414 *<pre>| sub | dst -= src | add dst src | HMEF | HMEFTI |</pre>
415 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
416 *<pre>| ckadd | Checksum add: dst = | add dst src | HMEF | HMEFTI |</pre>
417 *<pre>| | dst '+ src[0:1] '+ | | | or hdr |</pre>
418 *<pre>| | src[2:3] '+ ... | | | |</pre>
419 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
420 *<pre>| cksub | Checksum subtract: | add dst src | HMEF | HMEFTI |</pre>
421 *<pre>| | dst = dst '- src | | | |</pre>
422 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
423 *<pre>| and | dst &= src | and dst src | HMEF | HMEFTI |</pre>
424 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
425 *<pre>| or | dst |= src | or dst src | HMEF | HMEFTI |</pre>
426 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
427 *<pre>| xor | dst ^= src | xor dst src | HMEF | HMEFTI |</pre>
428 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
429 *<pre>| shl | dst <<= src | shl dst src | HMEF | HMEFTI |</pre>
430 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
431 *<pre>| shr | dst >>= src | shr dst src | HMEF | HMEFTI |</pre>
432 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
433 *<pre>| table | Table lookup | table TABLE | tbl | |</pre>
434 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
435 *<pre>| extern | Ext obj member func | extern e.obj.mfunc| ext | |</pre>
436 *<pre>| | call or ext func call| extern f.func | | |</pre>
437 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
438 *<pre>| jmp | Unconditional jump | jmp LABEL | | |</pre>
439 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
440 *<pre>| jmpv | Jump if hdr is valid | jmpv LABEL h.hdr | hdr | |</pre>
441 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
442 *<pre>| jmpnv | Jump if hdr is inval | jmpnv LABEL h.hdr | hdr | |</pre>
443 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
444 *<pre>| jmph | Jump if tbl lkp hit | jmph LABEL | | |</pre>
445 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
446 *<pre>| jmpnh | Jump if tbl lkp miss | jmpnh LABEL | | |</pre>
447 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
448 *<pre>| jmpa | Jump if action run | jmpa LABEL ACTION | act | |</pre>
449 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
450 *<pre>| jmpna | Jump if act not run | jmpna LABEL ACTION| act | |</pre>
451 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
452 *<pre>| jmpeq | Jump if (a == b) | jmpeq LABEL a b | HMEFT| HMEFTI |</pre>
453 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
454 *<pre>| jmpneq | Jump if (a != b) | jmpneq LABEL a b | HMEFT| HMEFTI |</pre>
455 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
456 *<pre>| jmplt | Jump if (a < b) | jmplt LABEL a b | HMEFT| HMEFTI |</pre>
457 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
458 *<pre>| jmpgt | Jump if (a > b) | jmpgt LABEL a b | HMEFT| HMEFTI |</pre>
459 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
460 *<pre>| return | Return from action | return | | |</pre>
461 *<pre>+------------+----------------------+-------------------+------+--------+</pre>
463 * At initialization time, the pipeline and action instructions (including the
464 * symbolic name operands) are translated to internal data structures that are
473 * Pipeline action configure
479 * @param[in] args_struct_type_name
480 * The struct type instantiated by the action data. The action data represent
481 * the action arguments that are stored in the table entry together with the
482 * action ID. Set to NULL when the action does not have any arguments.
483 * @param[in] instructions
484 * Action instructions.
485 * @param[in] n_instructions
486 * Number of action instructions.
488 * 0 on success or the following error codes otherwise:
489 * -EINVAL: Invalid argument;
490 * -ENOMEM: Not enough space/cannot allocate memory;
491 * -EEXIST: Action with this name already exists.
495 rte_swx_pipeline_action_config(struct rte_swx_pipeline *p,
497 const char *args_struct_type_name,
498 const char **instructions,
499 uint32_t n_instructions);
506 * Pipeline table type register
512 * @param[in] match_type
513 * Match type implemented by the new table type.
515 * Table type operations.
517 * 0 on success or the following error codes otherwise:
518 * -EINVAL: Invalid argument;
519 * -ENOMEM: Not enough space/cannot allocate memory;
520 * -EEXIST: Table type with this name already exists.
524 rte_swx_pipeline_table_type_register(struct rte_swx_pipeline *p,
526 enum rte_swx_table_match_type match_type,
527 struct rte_swx_table_ops *ops);
529 /** Match field parameters. */
530 struct rte_swx_match_field_params {
531 /** Match field name. Must be either a field of one of the registered
532 * packet headers ("h.header.field") or a field of the registered
533 * meta-data ("m.field").
537 /** Match type of the field. */
538 enum rte_swx_table_match_type match_type;
541 /** Pipeline table parameters. */
542 struct rte_swx_pipeline_table_params {
543 /** The set of match fields for the current table.
544 * Restriction: All the match fields of the current table need to be
545 * part of the same struct, i.e. either all the match fields are part of
546 * the same header or all the match fields are part of the meta-data.
548 struct rte_swx_match_field_params *fields;
550 /** The number of match fields for the current table. If set to zero, no
551 * "regular" entries (i.e. entries other than the default entry) can be
552 * added to the current table and the match process always results in
557 /** The set of actions for the current table. */
558 const char **action_names;
560 /** The number of actions for the current table. Must be at least one.
564 /** The default table action that gets executed on lookup miss. Must be
565 * one of the table actions included in the *action_names*.
567 const char *default_action_name;
569 /** Default action data. The size of this array is the action data size
570 * of the default action. Must be NULL if the default action data size
573 uint8_t *default_action_data;
575 /** If non-zero (true), then the default action of the current table
576 * cannot be changed. If zero (false), then the default action can be
577 * changed in the future with another action from the *action_names*
580 int default_action_is_const;
584 * Pipeline table configure
592 * @param[in] recommended_table_type_name
593 * Recommended table type. Typically set to NULL. Useful as guidance when
594 * there are multiple table types registered for the match type of the table,
595 * as determined from the table match fields specification. Silently ignored
596 * if the recommended table type does not exist or it serves a different match
599 * Table creation arguments.
601 * Guideline on maximum number of table entries.
603 * 0 on success or the following error codes otherwise:
604 * -EINVAL: Invalid argument;
605 * -ENOMEM: Not enough space/cannot allocate memory;
606 * -EEXIST: Table with this name already exists;
607 * -ENODEV: Table creation error.
611 rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,
613 struct rte_swx_pipeline_table_params *params,
614 const char *recommended_table_type_name,
619 * Pipeline instructions configure
623 * @param[in] instructions
624 * Pipeline instructions.
625 * @param[in] n_instructions
626 * Number of pipeline instructions.
628 * 0 on success or the following error codes otherwise:
629 * -EINVAL: Invalid argument;
630 * -ENOMEM: Not enough space/cannot allocate memory.
634 rte_swx_pipeline_instructions_config(struct rte_swx_pipeline *p,
635 const char **instructions,
636 uint32_t n_instructions);
641 * Once called, the pipeline build operation marks the end of pipeline
642 * configuration. At this point, all the internal data structures needed to run
643 * the pipeline are built.
648 * 0 on success or the following error codes otherwise:
649 * -EINVAL: Invalid argument;
650 * -ENOMEM: Not enough space/cannot allocate memory;
651 * -EEXIST: Pipeline was already built successfully.
655 rte_swx_pipeline_build(struct rte_swx_pipeline *p);
658 * Pipeline build from specification file
663 * Pipeline specification file.
664 * @param[out] err_line
665 * In case of error and non-NULL, the line number within the *spec* file where
666 * the error occurred. The first line number in the file is 1.
667 * @param[out] err_msg
668 * In case of error and non-NULL, the error message.
670 * 0 on success or the following error codes otherwise:
671 * -EINVAL: Invalid argument;
672 * -ENOMEM: Not enough space/cannot allocate memory;
673 * -EEXIST: Resource with the same name already exists;
674 * -ENODEV: Extern object or table creation error.
678 rte_swx_pipeline_build_from_spec(struct rte_swx_pipeline *p,
681 const char **err_msg);
688 * @param[in] n_instructions
689 * Number of instructions to execute.
693 rte_swx_pipeline_run(struct rte_swx_pipeline *p,
694 uint32_t n_instructions);
699 * Flush all output ports of the pipeline.
706 rte_swx_pipeline_flush(struct rte_swx_pipeline *p);
716 rte_swx_pipeline_free(struct rte_swx_pipeline *p);