1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020 Intel Corporation
10 #include "rte_swx_pipeline.h"
11 #include "rte_swx_ctl.h"
13 #define MAX_LINE_LENGTH RTE_SWX_INSTRUCTION_SIZE
14 #define MAX_TOKENS RTE_SWX_INSTRUCTION_TOKENS_MAX
16 #define STRUCT_BLOCK 0
17 #define ACTION_BLOCK 1
19 #define TABLE_KEY_BLOCK 3
20 #define TABLE_ACTIONS_BLOCK 4
21 #define SELECTOR_BLOCK 5
22 #define SELECTOR_SELECTOR_BLOCK 6
28 * extobj OBJ_NAME instanceof OBJ_TYPE [ pragma OBJ_CREATE_ARGS ]
32 char *extern_type_name;
37 extobj_spec_free(struct extobj_spec *s)
45 free(s->extern_type_name);
46 s->extern_type_name = NULL;
53 extobj_statement_parse(struct extobj_spec *s,
61 if (((n_tokens != 4) && (n_tokens != 6)) ||
62 ((n_tokens == 4) && strcmp(tokens[2], "instanceof")) ||
63 ((n_tokens == 6) && (strcmp(tokens[2], "instanceof") ||
64 strcmp(tokens[4], "pragma")))) {
68 *err_msg = "Invalid extobj statement.";
73 s->name = strdup(tokens[1]);
74 s->extern_type_name = strdup(tokens[3]);
75 s->pragma = (n_tokens == 6) ? strdup(tokens[5]) : NULL;
78 !s->extern_type_name ||
79 ((n_tokens == 6) && !s->pragma)) {
81 free(s->extern_type_name);
87 *err_msg = "Memory allocation failed.";
97 * struct STRUCT_TYPE_NAME {
98 * bit<SIZE> | varbit<SIZE> FIELD_NAME
104 struct rte_swx_field_params *fields;
110 struct_spec_free(struct struct_spec *s)
120 for (i = 0; i < s->n_fields; i++) {
121 uintptr_t name = (uintptr_t)s->fields[i].name;
135 struct_statement_parse(struct struct_spec *s,
136 uint32_t *block_mask,
141 const char **err_msg)
144 if ((n_tokens != 3) || strcmp(tokens[2], "{")) {
148 *err_msg = "Invalid struct statement.";
153 s->name = strdup(tokens[1]);
158 *err_msg = "Memory allocation failed.";
163 *block_mask |= 1 << STRUCT_BLOCK;
169 struct_block_parse(struct struct_spec *s,
170 uint32_t *block_mask,
175 const char **err_msg)
177 struct rte_swx_field_params *new_fields;
178 char *p = tokens[0], *name = NULL;
180 int varbit = 0, error = 0, error_size_invalid = 0, error_varbit_not_last = 0;
182 /* Handle end of block. */
183 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
184 *block_mask &= ~(1 << STRUCT_BLOCK);
196 error_varbit_not_last = 1;
200 if (!strncmp(p, "bit<", strlen("bit<"))) {
201 size_t len = strlen(p);
203 if ((len < strlen("bit< >")) || (p[len - 1] != '>')) {
208 /* Remove the "bit<" and ">". */
209 p[strlen(p) - 1] = 0;
211 } else if (!strncmp(p, "varbit<", strlen("varbit<"))) {
212 size_t len = strlen(p);
214 if ((len < strlen("varbit< >")) || (p[len - 1] != '>')) {
219 /* Remove the "varbit<" and ">". */
220 p[strlen(p) - 1] = 0;
221 p += strlen("varbit<");
223 /* Set the varbit flag. */
230 n_bits = strtoul(p, &p, 0);
234 ((n_bits > 64) && !varbit)) {
236 error_size_invalid = 1;
241 name = strdup(tokens[1]);
247 new_fields = realloc(s->fields, (s->n_fields + 1) * sizeof(struct rte_swx_field_params));
253 s->fields = new_fields;
254 s->fields[s->n_fields].name = name;
255 s->fields[s->n_fields].n_bits = n_bits;
268 *err_msg = "Invalid struct field statement.";
270 if ((error == -EINVAL) && error_varbit_not_last)
271 *err_msg = "Varbit field is not the last struct field.";
273 if ((error == -EINVAL) && error_size_invalid)
274 *err_msg = "Invalid struct field size.";
276 if (error == -ENOMEM)
277 *err_msg = "Memory allocation failed.";
286 * header HEADER_NAME instanceof STRUCT_TYPE_NAME
290 char *struct_type_name;
294 header_spec_free(struct header_spec *s)
302 free(s->struct_type_name);
303 s->struct_type_name = NULL;
307 header_statement_parse(struct header_spec *s,
312 const char **err_msg)
315 if ((n_tokens != 4) || strcmp(tokens[2], "instanceof")) {
319 *err_msg = "Invalid header statement.";
324 s->name = strdup(tokens[1]);
325 s->struct_type_name = strdup(tokens[3]);
327 if (!s->name || !s->struct_type_name) {
329 free(s->struct_type_name);
334 *err_msg = "Memory allocation failed.";
344 * metadata instanceof STRUCT_TYPE_NAME
346 struct metadata_spec {
347 char *struct_type_name;
351 metadata_spec_free(struct metadata_spec *s)
356 free(s->struct_type_name);
357 s->struct_type_name = NULL;
361 metadata_statement_parse(struct metadata_spec *s,
366 const char **err_msg)
369 if ((n_tokens != 3) || strcmp(tokens[1], "instanceof")) {
373 *err_msg = "Invalid metadata statement.";
378 s->struct_type_name = strdup(tokens[2]);
379 if (!s->struct_type_name) {
383 *err_msg = "Memory allocation failed.";
393 * action ACTION_NAME args none | instanceof STRUCT_TYPE_NAME {
400 char *args_struct_type_name;
401 const char **instructions;
402 uint32_t n_instructions;
406 action_spec_free(struct action_spec *s)
416 free(s->args_struct_type_name);
417 s->args_struct_type_name = NULL;
419 for (i = 0; i < s->n_instructions; i++) {
420 uintptr_t instr = (uintptr_t)s->instructions[i];
425 free(s->instructions);
426 s->instructions = NULL;
428 s->n_instructions = 0;
432 action_statement_parse(struct action_spec *s,
433 uint32_t *block_mask,
438 const char **err_msg)
441 if (((n_tokens != 5) && (n_tokens != 6)) ||
443 (strcmp(tokens[2], "args") ||
444 strcmp(tokens[3], "none") ||
445 strcmp(tokens[4], "{"))) ||
447 (strcmp(tokens[2], "args") ||
448 strcmp(tokens[3], "instanceof") ||
449 strcmp(tokens[5], "{")))) {
453 *err_msg = "Invalid action statement.";
458 s->name = strdup(tokens[1]);
459 s->args_struct_type_name = (n_tokens == 6) ? strdup(tokens[4]) : NULL;
461 if ((!s->name) || ((n_tokens == 6) && !s->args_struct_type_name)) {
465 *err_msg = "Memory allocation failed.";
470 *block_mask |= 1 << ACTION_BLOCK;
476 action_block_parse(struct action_spec *s,
477 uint32_t *block_mask,
482 const char **err_msg)
484 char buffer[RTE_SWX_INSTRUCTION_SIZE], *instr;
485 const char **new_instructions;
488 /* Handle end of block. */
489 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
490 *block_mask &= ~(1 << ACTION_BLOCK);
496 for (i = 0; i < n_tokens; i++) {
499 strcat(buffer, tokens[i]);
502 instr = strdup(buffer);
507 *err_msg = "Memory allocation failed.";
511 new_instructions = realloc(s->instructions,
512 (s->n_instructions + 1) * sizeof(char *));
513 if (!new_instructions) {
519 *err_msg = "Memory allocation failed.";
523 s->instructions = new_instructions;
524 s->instructions[s->n_instructions] = instr;
535 * MATCH_FIELD_NAME exact | wildcard | lpm
542 * default_action ACTION_NAME args none | ARGS_BYTE_ARRAY [ const ]
543 * instanceof TABLE_TYPE_NAME
550 struct rte_swx_pipeline_table_params params;
551 char *recommended_table_type_name;
557 table_spec_free(struct table_spec *s)
559 uintptr_t default_action_name;
568 for (i = 0; i < s->params.n_fields; i++) {
569 uintptr_t name = (uintptr_t)s->params.fields[i].name;
574 free(s->params.fields);
575 s->params.fields = NULL;
577 s->params.n_fields = 0;
579 for (i = 0; i < s->params.n_actions; i++) {
580 uintptr_t name = (uintptr_t)s->params.action_names[i];
585 free(s->params.action_names);
586 s->params.action_names = NULL;
588 s->params.n_actions = 0;
590 default_action_name = (uintptr_t)s->params.default_action_name;
591 free((void *)default_action_name);
592 s->params.default_action_name = NULL;
594 free(s->params.default_action_data);
595 s->params.default_action_data = NULL;
597 s->params.default_action_is_const = 0;
599 free(s->recommended_table_type_name);
600 s->recommended_table_type_name = NULL;
609 table_key_statement_parse(uint32_t *block_mask,
614 const char **err_msg)
617 if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
621 *err_msg = "Invalid key statement.";
626 *block_mask |= 1 << TABLE_KEY_BLOCK;
632 table_key_block_parse(struct table_spec *s,
633 uint32_t *block_mask,
638 const char **err_msg)
640 struct rte_swx_match_field_params *new_fields;
641 enum rte_swx_table_match_type match_type = RTE_SWX_TABLE_MATCH_WILDCARD;
644 /* Handle end of block. */
645 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
646 *block_mask &= ~(1 << TABLE_KEY_BLOCK);
650 /* Check input arguments. */
651 if ((n_tokens != 2) ||
652 (strcmp(tokens[1], "exact") &&
653 strcmp(tokens[1], "wildcard") &&
654 strcmp(tokens[1], "lpm"))) {
658 *err_msg = "Invalid match field statement.";
662 if (!strcmp(tokens[1], "wildcard"))
663 match_type = RTE_SWX_TABLE_MATCH_WILDCARD;
664 if (!strcmp(tokens[1], "lpm"))
665 match_type = RTE_SWX_TABLE_MATCH_LPM;
666 if (!strcmp(tokens[1], "exact"))
667 match_type = RTE_SWX_TABLE_MATCH_EXACT;
669 name = strdup(tokens[0]);
674 *err_msg = "Memory allocation failed.";
678 new_fields = realloc(s->params.fields,
679 (s->params.n_fields + 1) * sizeof(struct rte_swx_match_field_params));
686 *err_msg = "Memory allocation failed.";
690 s->params.fields = new_fields;
691 s->params.fields[s->params.n_fields].name = name;
692 s->params.fields[s->params.n_fields].match_type = match_type;
693 s->params.n_fields++;
699 table_actions_statement_parse(uint32_t *block_mask,
704 const char **err_msg)
707 if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
711 *err_msg = "Invalid actions statement.";
716 *block_mask |= 1 << TABLE_ACTIONS_BLOCK;
722 table_actions_block_parse(struct table_spec *s,
723 uint32_t *block_mask,
728 const char **err_msg)
730 const char **new_action_names;
733 /* Handle end of block. */
734 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
735 *block_mask &= ~(1 << TABLE_ACTIONS_BLOCK);
739 /* Check input arguments. */
744 *err_msg = "Invalid action name statement.";
748 name = strdup(tokens[0]);
753 *err_msg = "Memory allocation failed.";
757 new_action_names = realloc(s->params.action_names,
758 (s->params.n_actions + 1) * sizeof(char *));
759 if (!new_action_names) {
765 *err_msg = "Memory allocation failed.";
769 s->params.action_names = new_action_names;
770 s->params.action_names[s->params.n_actions] = name;
771 s->params.n_actions++;
777 table_statement_parse(struct table_spec *s,
778 uint32_t *block_mask,
783 const char **err_msg)
786 if ((n_tokens != 3) || strcmp(tokens[2], "{")) {
790 *err_msg = "Invalid table statement.";
795 s->name = strdup(tokens[1]);
800 *err_msg = "Memory allocation failed.";
805 *block_mask |= 1 << TABLE_BLOCK;
811 table_block_parse(struct table_spec *s,
812 uint32_t *block_mask,
817 const char **err_msg)
819 if (*block_mask & (1 << TABLE_KEY_BLOCK))
820 return table_key_block_parse(s,
828 if (*block_mask & (1 << TABLE_ACTIONS_BLOCK))
829 return table_actions_block_parse(s,
837 /* Handle end of block. */
838 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
839 *block_mask &= ~(1 << TABLE_BLOCK);
843 if (!strcmp(tokens[0], "key"))
844 return table_key_statement_parse(block_mask,
851 if (!strcmp(tokens[0], "actions"))
852 return table_actions_statement_parse(block_mask,
859 if (!strcmp(tokens[0], "default_action")) {
860 if (((n_tokens != 4) && (n_tokens != 5)) ||
861 strcmp(tokens[2], "args") ||
862 strcmp(tokens[3], "none") ||
863 ((n_tokens == 5) && strcmp(tokens[4], "const"))) {
867 *err_msg = "Invalid default_action statement.";
871 if (s->params.default_action_name) {
875 *err_msg = "Duplicate default_action stmt.";
879 s->params.default_action_name = strdup(tokens[1]);
880 if (!s->params.default_action_name) {
884 *err_msg = "Memory allocation failed.";
889 s->params.default_action_is_const = 1;
894 if (!strcmp(tokens[0], "instanceof")) {
899 *err_msg = "Invalid instanceof statement.";
903 if (s->recommended_table_type_name) {
907 *err_msg = "Duplicate instanceof statement.";
911 s->recommended_table_type_name = strdup(tokens[1]);
912 if (!s->recommended_table_type_name) {
916 *err_msg = "Memory allocation failed.";
923 if (!strcmp(tokens[0], "pragma")) {
928 *err_msg = "Invalid pragma statement.";
936 *err_msg = "Duplicate pragma statement.";
940 s->args = strdup(tokens[1]);
945 *err_msg = "Memory allocation failed.";
952 if (!strcmp(tokens[0], "size")) {
959 *err_msg = "Invalid pragma statement.";
963 s->size = strtoul(p, &p, 0);
968 *err_msg = "Invalid size argument.";
979 *err_msg = "Invalid statement.";
986 * selector SELECTOR_NAME {
987 * group_id FIELD_NAME
992 * member_id FIELD_NAME
994 * n_members_per_group N_MEMBERS_PER_GROUP
997 struct selector_spec {
999 struct rte_swx_pipeline_selector_params params;
1003 selector_spec_free(struct selector_spec *s)
1005 uintptr_t field_name;
1015 /* params->group_id_field_name. */
1016 field_name = (uintptr_t)s->params.group_id_field_name;
1017 free((void *)field_name);
1018 s->params.group_id_field_name = NULL;
1020 /* params->selector_field_names. */
1021 for (i = 0; i < s->params.n_selector_fields; i++) {
1022 field_name = (uintptr_t)s->params.selector_field_names[i];
1024 free((void *)field_name);
1027 free(s->params.selector_field_names);
1028 s->params.selector_field_names = NULL;
1030 s->params.n_selector_fields = 0;
1032 /* params->member_id_field_name. */
1033 field_name = (uintptr_t)s->params.member_id_field_name;
1034 free((void *)field_name);
1035 s->params.member_id_field_name = NULL;
1037 /* params->n_groups_max. */
1038 s->params.n_groups_max = 0;
1040 /* params->n_members_per_group_max. */
1041 s->params.n_members_per_group_max = 0;
1045 selector_statement_parse(struct selector_spec *s,
1046 uint32_t *block_mask,
1051 const char **err_msg)
1054 if ((n_tokens != 3) || strcmp(tokens[2], "{")) {
1056 *err_line = n_lines;
1058 *err_msg = "Invalid selector statement.";
1063 s->name = strdup(tokens[1]);
1066 *err_line = n_lines;
1068 *err_msg = "Memory allocation failed.";
1073 *block_mask |= 1 << SELECTOR_BLOCK;
1079 selector_selector_statement_parse(uint32_t *block_mask,
1084 const char **err_msg)
1087 if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
1089 *err_line = n_lines;
1091 *err_msg = "Invalid selector statement.";
1096 *block_mask |= 1 << SELECTOR_SELECTOR_BLOCK;
1102 selector_selector_block_parse(struct selector_spec *s,
1103 uint32_t *block_mask,
1108 const char **err_msg)
1110 const char **new_fields;
1113 /* Handle end of block. */
1114 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
1115 *block_mask &= ~(1 << SELECTOR_SELECTOR_BLOCK);
1119 /* Check input arguments. */
1120 if (n_tokens != 1) {
1122 *err_line = n_lines;
1124 *err_msg = "Invalid selector field statement.";
1128 name = strdup(tokens[0]);
1131 *err_line = n_lines;
1133 *err_msg = "Memory allocation failed.";
1137 new_fields = realloc(s->params.selector_field_names,
1138 (s->params.n_selector_fields + 1) * sizeof(char *));
1143 *err_line = n_lines;
1145 *err_msg = "Memory allocation failed.";
1149 s->params.selector_field_names = new_fields;
1150 s->params.selector_field_names[s->params.n_selector_fields] = name;
1151 s->params.n_selector_fields++;
1157 selector_block_parse(struct selector_spec *s,
1158 uint32_t *block_mask,
1163 const char **err_msg)
1165 if (*block_mask & (1 << SELECTOR_SELECTOR_BLOCK))
1166 return selector_selector_block_parse(s,
1174 /* Handle end of block. */
1175 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
1176 *block_mask &= ~(1 << SELECTOR_BLOCK);
1180 if (!strcmp(tokens[0], "group_id")) {
1181 if (n_tokens != 2) {
1183 *err_line = n_lines;
1185 *err_msg = "Invalid group_id statement.";
1189 s->params.group_id_field_name = strdup(tokens[1]);
1190 if (!s->params.group_id_field_name) {
1192 *err_line = n_lines;
1194 *err_msg = "Memory allocation failed.";
1201 if (!strcmp(tokens[0], "selector"))
1202 return selector_selector_statement_parse(block_mask,
1209 if (!strcmp(tokens[0], "member_id")) {
1210 if (n_tokens != 2) {
1212 *err_line = n_lines;
1214 *err_msg = "Invalid member_id statement.";
1218 s->params.member_id_field_name = strdup(tokens[1]);
1219 if (!s->params.member_id_field_name) {
1221 *err_line = n_lines;
1223 *err_msg = "Memory allocation failed.";
1230 if (!strcmp(tokens[0], "n_groups_max")) {
1231 char *p = tokens[1];
1233 if (n_tokens != 2) {
1235 *err_line = n_lines;
1237 *err_msg = "Invalid n_groups statement.";
1241 s->params.n_groups_max = strtoul(p, &p, 0);
1244 *err_line = n_lines;
1246 *err_msg = "Invalid n_groups argument.";
1253 if (!strcmp(tokens[0], "n_members_per_group_max")) {
1254 char *p = tokens[1];
1256 if (n_tokens != 2) {
1258 *err_line = n_lines;
1260 *err_msg = "Invalid n_members_per_group statement.";
1264 s->params.n_members_per_group_max = strtoul(p, &p, 0);
1267 *err_line = n_lines;
1269 *err_msg = "Invalid n_members_per_group argument.";
1276 /* Anything else. */
1278 *err_line = n_lines;
1280 *err_msg = "Invalid statement.";
1287 * regarray NAME size SIZE initval INITVAL
1289 struct regarray_spec {
1296 regarray_spec_free(struct regarray_spec *s)
1306 regarray_statement_parse(struct regarray_spec *s,
1311 const char **err_msg)
1316 if ((n_tokens != 6) ||
1317 strcmp(tokens[2], "size") ||
1318 strcmp(tokens[4], "initval")) {
1320 *err_line = n_lines;
1322 *err_msg = "Invalid regarray statement.";
1327 s->name = strdup(tokens[1]);
1330 *err_line = n_lines;
1332 *err_msg = "Memory allocation failed.";
1337 s->size = strtoul(p, &p, 0);
1338 if (p[0] || !s->size) {
1340 *err_line = n_lines;
1342 *err_msg = "Invalid size argument.";
1347 s->init_val = strtoull(p, &p, 0);
1350 *err_line = n_lines;
1352 *err_msg = "Invalid initval argument.";
1362 * metarray NAME size SIZE
1364 struct metarray_spec {
1370 metarray_spec_free(struct metarray_spec *s)
1380 metarray_statement_parse(struct metarray_spec *s,
1385 const char **err_msg)
1390 if ((n_tokens != 4) || strcmp(tokens[2], "size")) {
1392 *err_line = n_lines;
1394 *err_msg = "Invalid metarray statement.";
1399 s->name = strdup(tokens[1]);
1402 *err_line = n_lines;
1404 *err_msg = "Memory allocation failed.";
1409 s->size = strtoul(p, &p, 0);
1410 if (p[0] || !s->size) {
1412 *err_line = n_lines;
1414 *err_msg = "Invalid size argument.";
1430 const char **instructions;
1431 uint32_t n_instructions;
1435 apply_spec_free(struct apply_spec *s)
1442 for (i = 0; i < s->n_instructions; i++) {
1443 uintptr_t instr = (uintptr_t)s->instructions[i];
1445 free((void *)instr);
1448 free(s->instructions);
1449 s->instructions = NULL;
1451 s->n_instructions = 0;
1455 apply_statement_parse(uint32_t *block_mask,
1460 const char **err_msg)
1463 if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
1465 *err_line = n_lines;
1467 *err_msg = "Invalid apply statement.";
1472 *block_mask |= 1 << APPLY_BLOCK;
1478 apply_block_parse(struct apply_spec *s,
1479 uint32_t *block_mask,
1484 const char **err_msg)
1486 char buffer[RTE_SWX_INSTRUCTION_SIZE], *instr;
1487 const char **new_instructions;
1490 /* Handle end of block. */
1491 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
1492 *block_mask &= ~(1 << APPLY_BLOCK);
1498 for (i = 0; i < n_tokens; i++) {
1500 strcat(buffer, " ");
1501 strcat(buffer, tokens[i]);
1504 instr = strdup(buffer);
1507 *err_line = n_lines;
1509 *err_msg = "Memory allocation failed.";
1513 new_instructions = realloc(s->instructions,
1514 (s->n_instructions + 1) * sizeof(char *));
1515 if (!new_instructions) {
1519 *err_line = n_lines;
1521 *err_msg = "Memory allocation failed.";
1525 s->instructions = new_instructions;
1526 s->instructions[s->n_instructions] = instr;
1527 s->n_instructions++;
1536 rte_swx_pipeline_build_from_spec(struct rte_swx_pipeline *p,
1539 const char **err_msg)
1541 struct extobj_spec extobj_spec = {0};
1542 struct struct_spec struct_spec = {0};
1543 struct header_spec header_spec = {0};
1544 struct metadata_spec metadata_spec = {0};
1545 struct action_spec action_spec = {0};
1546 struct table_spec table_spec = {0};
1547 struct selector_spec selector_spec = {0};
1548 struct regarray_spec regarray_spec = {0};
1549 struct metarray_spec metarray_spec = {0};
1550 struct apply_spec apply_spec = {0};
1552 uint32_t block_mask = 0;
1555 /* Check the input arguments. */
1560 *err_msg = "Null pipeline arument.";
1569 *err_msg = "Null specification file argument.";
1574 for (n_lines = 1; ; n_lines++) {
1575 char line[MAX_LINE_LENGTH];
1576 char *tokens[MAX_TOKENS], *ptr = line;
1577 uint32_t n_tokens = 0;
1579 /* Read next line. */
1580 if (!fgets(line, sizeof(line), spec))
1583 /* Parse the line into tokens. */
1588 token = strtok_r(ptr, " \f\n\r\t\v", &ptr);
1592 /* Handle comments. */
1593 if ((token[0] == '#') ||
1594 (token[0] == ';') ||
1595 ((token[0] == '/') && (token[1] == '/'))) {
1599 /* Handle excessively long lines. */
1600 if (n_tokens >= MAX_TOKENS) {
1602 *err_line = n_lines;
1604 *err_msg = "Too many tokens.";
1609 /* Handle excessively long tokens. */
1610 if (strnlen(token, RTE_SWX_NAME_SIZE) >=
1611 RTE_SWX_NAME_SIZE) {
1613 *err_line = n_lines;
1615 *err_msg = "Token too big.";
1621 tokens[n_tokens] = token;
1625 /* Handle empty lines. */
1630 if (block_mask & (1 << STRUCT_BLOCK)) {
1631 status = struct_block_parse(&struct_spec,
1641 if (block_mask & (1 << STRUCT_BLOCK))
1645 status = rte_swx_pipeline_struct_type_register(p,
1648 struct_spec.n_fields,
1649 struct_spec.varbit);
1652 *err_line = n_lines;
1654 *err_msg = "Struct registration error.";
1658 struct_spec_free(&struct_spec);
1664 if (block_mask & (1 << ACTION_BLOCK)) {
1665 status = action_block_parse(&action_spec,
1675 if (block_mask & (1 << ACTION_BLOCK))
1679 status = rte_swx_pipeline_action_config(p,
1681 action_spec.args_struct_type_name,
1682 action_spec.instructions,
1683 action_spec.n_instructions);
1686 *err_line = n_lines;
1688 *err_msg = "Action config error.";
1692 action_spec_free(&action_spec);
1698 if (block_mask & (1 << TABLE_BLOCK)) {
1699 status = table_block_parse(&table_spec,
1709 if (block_mask & (1 << TABLE_BLOCK))
1713 status = rte_swx_pipeline_table_config(p,
1716 table_spec.recommended_table_type_name,
1721 *err_line = n_lines;
1723 *err_msg = "Table configuration error.";
1727 table_spec_free(&table_spec);
1732 /* selector block. */
1733 if (block_mask & (1 << SELECTOR_BLOCK)) {
1734 status = selector_block_parse(&selector_spec,
1744 if (block_mask & (1 << SELECTOR_BLOCK))
1748 status = rte_swx_pipeline_selector_config(p,
1750 &selector_spec.params);
1753 *err_line = n_lines;
1755 *err_msg = "Selector configuration error.";
1759 selector_spec_free(&selector_spec);
1765 if (block_mask & (1 << APPLY_BLOCK)) {
1766 status = apply_block_parse(&apply_spec,
1776 if (block_mask & (1 << APPLY_BLOCK))
1780 status = rte_swx_pipeline_instructions_config(p,
1781 apply_spec.instructions,
1782 apply_spec.n_instructions);
1785 *err_line = n_lines;
1787 *err_msg = "Pipeline instructions err.";
1791 apply_spec_free(&apply_spec);
1797 if (!strcmp(tokens[0], "extobj")) {
1798 status = extobj_statement_parse(&extobj_spec,
1807 status = rte_swx_pipeline_extern_object_config(p,
1809 extobj_spec.extern_type_name,
1810 extobj_spec.pragma);
1813 *err_line = n_lines;
1815 *err_msg = "Extern object config err.";
1819 extobj_spec_free(&extobj_spec);
1825 if (!strcmp(tokens[0], "struct")) {
1826 status = struct_statement_parse(&struct_spec,
1840 if (!strcmp(tokens[0], "header")) {
1841 status = header_statement_parse(&header_spec,
1850 status = rte_swx_pipeline_packet_header_register(p,
1852 header_spec.struct_type_name);
1855 *err_line = n_lines;
1857 *err_msg = "Header registration error.";
1861 header_spec_free(&header_spec);
1867 if (!strcmp(tokens[0], "metadata")) {
1868 status = metadata_statement_parse(&metadata_spec,
1877 status = rte_swx_pipeline_packet_metadata_register(p,
1878 metadata_spec.struct_type_name);
1881 *err_line = n_lines;
1883 *err_msg = "Meta-data reg err.";
1887 metadata_spec_free(&metadata_spec);
1893 if (!strcmp(tokens[0], "action")) {
1894 status = action_statement_parse(&action_spec,
1908 if (!strcmp(tokens[0], "table")) {
1909 status = table_statement_parse(&table_spec,
1923 if (!strcmp(tokens[0], "selector")) {
1924 status = selector_statement_parse(&selector_spec,
1938 if (!strcmp(tokens[0], "regarray")) {
1939 status = regarray_statement_parse(®array_spec,
1948 status = rte_swx_pipeline_regarray_config(p,
1951 regarray_spec.init_val);
1954 *err_line = n_lines;
1956 *err_msg = "Register array configuration error.";
1960 regarray_spec_free(®array_spec);
1966 if (!strcmp(tokens[0], "metarray")) {
1967 status = metarray_statement_parse(&metarray_spec,
1976 status = rte_swx_pipeline_metarray_config(p,
1978 metarray_spec.size);
1981 *err_line = n_lines;
1983 *err_msg = "Meter array configuration error.";
1987 metarray_spec_free(&metarray_spec);
1993 if (!strcmp(tokens[0], "apply")) {
1994 status = apply_statement_parse(&block_mask,
2006 /* Anything else. */
2008 *err_line = n_lines;
2010 *err_msg = "Unknown statement.";
2015 /* Handle unfinished block. */
2018 *err_line = n_lines;
2020 *err_msg = "Missing }.";
2025 /* Pipeline build. */
2026 status = rte_swx_pipeline_build(p);
2029 *err_line = n_lines;
2031 *err_msg = "Pipeline build error.";
2038 extobj_spec_free(&extobj_spec);
2039 struct_spec_free(&struct_spec);
2040 header_spec_free(&header_spec);
2041 metadata_spec_free(&metadata_spec);
2042 action_spec_free(&action_spec);
2043 table_spec_free(&table_spec);
2044 selector_spec_free(&selector_spec);
2045 regarray_spec_free(®array_spec);
2046 metarray_spec_free(&metarray_spec);
2047 apply_spec_free(&apply_spec);