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> FIELD_NAME
104 struct rte_swx_field_params *fields;
109 struct_spec_free(struct struct_spec *s)
119 for (i = 0; i < s->n_fields; i++) {
120 uintptr_t name = (uintptr_t)s->fields[i].name;
132 struct_statement_parse(struct struct_spec *s,
133 uint32_t *block_mask,
138 const char **err_msg)
141 if ((n_tokens != 3) || strcmp(tokens[2], "{")) {
145 *err_msg = "Invalid struct statement.";
150 s->name = strdup(tokens[1]);
155 *err_msg = "Memory allocation failed.";
160 *block_mask |= 1 << STRUCT_BLOCK;
166 struct_block_parse(struct struct_spec *s,
167 uint32_t *block_mask,
172 const char **err_msg)
174 struct rte_swx_field_params *new_fields;
175 char *p = tokens[0], *name;
178 /* Handle end of block. */
179 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
180 *block_mask &= ~(1 << STRUCT_BLOCK);
185 if ((n_tokens != 2) ||
191 (p[strlen(p) - 1] != '>')) {
195 *err_msg = "Invalid struct field statement.";
199 /* Remove the "bit<" and ">". */
200 p[strlen(p) - 1] = 0;
203 n_bits = strtoul(p, &p, 0);
211 *err_msg = "Invalid struct field size.";
216 name = strdup(tokens[1]);
221 *err_msg = "Memory allocation failed.";
225 new_fields = realloc(s->fields,
226 (s->n_fields + 1) * sizeof(struct rte_swx_field_params));
233 *err_msg = "Memory allocation failed.";
237 s->fields = new_fields;
238 s->fields[s->n_fields].name = name;
239 s->fields[s->n_fields].n_bits = n_bits;
248 * header HEADER_NAME instanceof STRUCT_TYPE_NAME
252 char *struct_type_name;
256 header_spec_free(struct header_spec *s)
264 free(s->struct_type_name);
265 s->struct_type_name = NULL;
269 header_statement_parse(struct header_spec *s,
274 const char **err_msg)
277 if ((n_tokens != 4) || strcmp(tokens[2], "instanceof")) {
281 *err_msg = "Invalid header statement.";
286 s->name = strdup(tokens[1]);
287 s->struct_type_name = strdup(tokens[3]);
289 if (!s->name || !s->struct_type_name) {
291 free(s->struct_type_name);
296 *err_msg = "Memory allocation failed.";
306 * metadata instanceof STRUCT_TYPE_NAME
308 struct metadata_spec {
309 char *struct_type_name;
313 metadata_spec_free(struct metadata_spec *s)
318 free(s->struct_type_name);
319 s->struct_type_name = NULL;
323 metadata_statement_parse(struct metadata_spec *s,
328 const char **err_msg)
331 if ((n_tokens != 3) || strcmp(tokens[1], "instanceof")) {
335 *err_msg = "Invalid metadata statement.";
340 s->struct_type_name = strdup(tokens[2]);
341 if (!s->struct_type_name) {
345 *err_msg = "Memory allocation failed.";
355 * action ACTION_NAME args none | instanceof STRUCT_TYPE_NAME {
362 char *args_struct_type_name;
363 const char **instructions;
364 uint32_t n_instructions;
368 action_spec_free(struct action_spec *s)
378 free(s->args_struct_type_name);
379 s->args_struct_type_name = NULL;
381 for (i = 0; i < s->n_instructions; i++) {
382 uintptr_t instr = (uintptr_t)s->instructions[i];
387 free(s->instructions);
388 s->instructions = NULL;
390 s->n_instructions = 0;
394 action_statement_parse(struct action_spec *s,
395 uint32_t *block_mask,
400 const char **err_msg)
403 if (((n_tokens != 5) && (n_tokens != 6)) ||
405 (strcmp(tokens[2], "args") ||
406 strcmp(tokens[3], "none") ||
407 strcmp(tokens[4], "{"))) ||
409 (strcmp(tokens[2], "args") ||
410 strcmp(tokens[3], "instanceof") ||
411 strcmp(tokens[5], "{")))) {
415 *err_msg = "Invalid action statement.";
420 s->name = strdup(tokens[1]);
421 s->args_struct_type_name = (n_tokens == 6) ? strdup(tokens[4]) : NULL;
423 if ((!s->name) || ((n_tokens == 6) && !s->args_struct_type_name)) {
427 *err_msg = "Memory allocation failed.";
432 *block_mask |= 1 << ACTION_BLOCK;
438 action_block_parse(struct action_spec *s,
439 uint32_t *block_mask,
444 const char **err_msg)
446 char buffer[RTE_SWX_INSTRUCTION_SIZE], *instr;
447 const char **new_instructions;
450 /* Handle end of block. */
451 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
452 *block_mask &= ~(1 << ACTION_BLOCK);
458 for (i = 0; i < n_tokens; i++) {
461 strcat(buffer, tokens[i]);
464 instr = strdup(buffer);
469 *err_msg = "Memory allocation failed.";
473 new_instructions = realloc(s->instructions,
474 (s->n_instructions + 1) * sizeof(char *));
475 if (!new_instructions) {
481 *err_msg = "Memory allocation failed.";
485 s->instructions = new_instructions;
486 s->instructions[s->n_instructions] = instr;
497 * MATCH_FIELD_NAME exact | wildcard | lpm
504 * default_action ACTION_NAME args none | ARGS_BYTE_ARRAY [ const ]
505 * instanceof TABLE_TYPE_NAME
512 struct rte_swx_pipeline_table_params params;
513 char *recommended_table_type_name;
519 table_spec_free(struct table_spec *s)
521 uintptr_t default_action_name;
530 for (i = 0; i < s->params.n_fields; i++) {
531 uintptr_t name = (uintptr_t)s->params.fields[i].name;
536 free(s->params.fields);
537 s->params.fields = NULL;
539 s->params.n_fields = 0;
541 for (i = 0; i < s->params.n_actions; i++) {
542 uintptr_t name = (uintptr_t)s->params.action_names[i];
547 free(s->params.action_names);
548 s->params.action_names = NULL;
550 s->params.n_actions = 0;
552 default_action_name = (uintptr_t)s->params.default_action_name;
553 free((void *)default_action_name);
554 s->params.default_action_name = NULL;
556 free(s->params.default_action_data);
557 s->params.default_action_data = NULL;
559 s->params.default_action_is_const = 0;
561 free(s->recommended_table_type_name);
562 s->recommended_table_type_name = NULL;
571 table_key_statement_parse(uint32_t *block_mask,
576 const char **err_msg)
579 if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
583 *err_msg = "Invalid key statement.";
588 *block_mask |= 1 << TABLE_KEY_BLOCK;
594 table_key_block_parse(struct table_spec *s,
595 uint32_t *block_mask,
600 const char **err_msg)
602 struct rte_swx_match_field_params *new_fields;
603 enum rte_swx_table_match_type match_type = RTE_SWX_TABLE_MATCH_WILDCARD;
606 /* Handle end of block. */
607 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
608 *block_mask &= ~(1 << TABLE_KEY_BLOCK);
612 /* Check input arguments. */
613 if ((n_tokens != 2) ||
614 (strcmp(tokens[1], "exact") &&
615 strcmp(tokens[1], "wildcard") &&
616 strcmp(tokens[1], "lpm"))) {
620 *err_msg = "Invalid match field statement.";
624 if (!strcmp(tokens[1], "wildcard"))
625 match_type = RTE_SWX_TABLE_MATCH_WILDCARD;
626 if (!strcmp(tokens[1], "lpm"))
627 match_type = RTE_SWX_TABLE_MATCH_LPM;
628 if (!strcmp(tokens[1], "exact"))
629 match_type = RTE_SWX_TABLE_MATCH_EXACT;
631 name = strdup(tokens[0]);
636 *err_msg = "Memory allocation failed.";
640 new_fields = realloc(s->params.fields,
641 (s->params.n_fields + 1) * sizeof(struct rte_swx_match_field_params));
648 *err_msg = "Memory allocation failed.";
652 s->params.fields = new_fields;
653 s->params.fields[s->params.n_fields].name = name;
654 s->params.fields[s->params.n_fields].match_type = match_type;
655 s->params.n_fields++;
661 table_actions_statement_parse(uint32_t *block_mask,
666 const char **err_msg)
669 if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
673 *err_msg = "Invalid actions statement.";
678 *block_mask |= 1 << TABLE_ACTIONS_BLOCK;
684 table_actions_block_parse(struct table_spec *s,
685 uint32_t *block_mask,
690 const char **err_msg)
692 const char **new_action_names;
695 /* Handle end of block. */
696 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
697 *block_mask &= ~(1 << TABLE_ACTIONS_BLOCK);
701 /* Check input arguments. */
706 *err_msg = "Invalid action name statement.";
710 name = strdup(tokens[0]);
715 *err_msg = "Memory allocation failed.";
719 new_action_names = realloc(s->params.action_names,
720 (s->params.n_actions + 1) * sizeof(char *));
721 if (!new_action_names) {
727 *err_msg = "Memory allocation failed.";
731 s->params.action_names = new_action_names;
732 s->params.action_names[s->params.n_actions] = name;
733 s->params.n_actions++;
739 table_statement_parse(struct table_spec *s,
740 uint32_t *block_mask,
745 const char **err_msg)
748 if ((n_tokens != 3) || strcmp(tokens[2], "{")) {
752 *err_msg = "Invalid table statement.";
757 s->name = strdup(tokens[1]);
762 *err_msg = "Memory allocation failed.";
767 *block_mask |= 1 << TABLE_BLOCK;
773 table_block_parse(struct table_spec *s,
774 uint32_t *block_mask,
779 const char **err_msg)
781 if (*block_mask & (1 << TABLE_KEY_BLOCK))
782 return table_key_block_parse(s,
790 if (*block_mask & (1 << TABLE_ACTIONS_BLOCK))
791 return table_actions_block_parse(s,
799 /* Handle end of block. */
800 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
801 *block_mask &= ~(1 << TABLE_BLOCK);
805 if (!strcmp(tokens[0], "key"))
806 return table_key_statement_parse(block_mask,
813 if (!strcmp(tokens[0], "actions"))
814 return table_actions_statement_parse(block_mask,
821 if (!strcmp(tokens[0], "default_action")) {
822 if (((n_tokens != 4) && (n_tokens != 5)) ||
823 strcmp(tokens[2], "args") ||
824 strcmp(tokens[3], "none") ||
825 ((n_tokens == 5) && strcmp(tokens[4], "const"))) {
829 *err_msg = "Invalid default_action statement.";
833 if (s->params.default_action_name) {
837 *err_msg = "Duplicate default_action stmt.";
841 s->params.default_action_name = strdup(tokens[1]);
842 if (!s->params.default_action_name) {
846 *err_msg = "Memory allocation failed.";
851 s->params.default_action_is_const = 1;
856 if (!strcmp(tokens[0], "instanceof")) {
861 *err_msg = "Invalid instanceof statement.";
865 if (s->recommended_table_type_name) {
869 *err_msg = "Duplicate instanceof statement.";
873 s->recommended_table_type_name = strdup(tokens[1]);
874 if (!s->recommended_table_type_name) {
878 *err_msg = "Memory allocation failed.";
885 if (!strcmp(tokens[0], "pragma")) {
890 *err_msg = "Invalid pragma statement.";
898 *err_msg = "Duplicate pragma statement.";
902 s->args = strdup(tokens[1]);
907 *err_msg = "Memory allocation failed.";
914 if (!strcmp(tokens[0], "size")) {
921 *err_msg = "Invalid pragma statement.";
925 s->size = strtoul(p, &p, 0);
930 *err_msg = "Invalid size argument.";
941 *err_msg = "Invalid statement.";
948 * selector SELECTOR_NAME {
949 * group_id FIELD_NAME
954 * member_id FIELD_NAME
956 * n_members_per_group N_MEMBERS_PER_GROUP
959 struct selector_spec {
961 struct rte_swx_pipeline_selector_params params;
965 selector_spec_free(struct selector_spec *s)
967 uintptr_t field_name;
977 /* params->group_id_field_name. */
978 field_name = (uintptr_t)s->params.group_id_field_name;
979 free((void *)field_name);
980 s->params.group_id_field_name = NULL;
982 /* params->selector_field_names. */
983 for (i = 0; i < s->params.n_selector_fields; i++) {
984 field_name = (uintptr_t)s->params.selector_field_names[i];
986 free((void *)field_name);
989 free(s->params.selector_field_names);
990 s->params.selector_field_names = NULL;
992 s->params.n_selector_fields = 0;
994 /* params->member_id_field_name. */
995 field_name = (uintptr_t)s->params.member_id_field_name;
996 free((void *)field_name);
997 s->params.member_id_field_name = NULL;
999 /* params->n_groups_max. */
1000 s->params.n_groups_max = 0;
1002 /* params->n_members_per_group_max. */
1003 s->params.n_members_per_group_max = 0;
1007 selector_statement_parse(struct selector_spec *s,
1008 uint32_t *block_mask,
1013 const char **err_msg)
1016 if ((n_tokens != 3) || strcmp(tokens[2], "{")) {
1018 *err_line = n_lines;
1020 *err_msg = "Invalid selector statement.";
1025 s->name = strdup(tokens[1]);
1028 *err_line = n_lines;
1030 *err_msg = "Memory allocation failed.";
1035 *block_mask |= 1 << SELECTOR_BLOCK;
1041 selector_selector_statement_parse(uint32_t *block_mask,
1046 const char **err_msg)
1049 if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
1051 *err_line = n_lines;
1053 *err_msg = "Invalid selector statement.";
1058 *block_mask |= 1 << SELECTOR_SELECTOR_BLOCK;
1064 selector_selector_block_parse(struct selector_spec *s,
1065 uint32_t *block_mask,
1070 const char **err_msg)
1072 const char **new_fields;
1075 /* Handle end of block. */
1076 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
1077 *block_mask &= ~(1 << SELECTOR_SELECTOR_BLOCK);
1081 /* Check input arguments. */
1082 if (n_tokens != 1) {
1084 *err_line = n_lines;
1086 *err_msg = "Invalid selector field statement.";
1090 name = strdup(tokens[0]);
1093 *err_line = n_lines;
1095 *err_msg = "Memory allocation failed.";
1099 new_fields = realloc(s->params.selector_field_names,
1100 (s->params.n_selector_fields + 1) * sizeof(char *));
1105 *err_line = n_lines;
1107 *err_msg = "Memory allocation failed.";
1111 s->params.selector_field_names = new_fields;
1112 s->params.selector_field_names[s->params.n_selector_fields] = name;
1113 s->params.n_selector_fields++;
1119 selector_block_parse(struct selector_spec *s,
1120 uint32_t *block_mask,
1125 const char **err_msg)
1127 if (*block_mask & (1 << SELECTOR_SELECTOR_BLOCK))
1128 return selector_selector_block_parse(s,
1136 /* Handle end of block. */
1137 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
1138 *block_mask &= ~(1 << SELECTOR_BLOCK);
1142 if (!strcmp(tokens[0], "group_id")) {
1143 if (n_tokens != 2) {
1145 *err_line = n_lines;
1147 *err_msg = "Invalid group_id statement.";
1151 s->params.group_id_field_name = strdup(tokens[1]);
1152 if (!s->params.group_id_field_name) {
1154 *err_line = n_lines;
1156 *err_msg = "Memory allocation failed.";
1163 if (!strcmp(tokens[0], "selector"))
1164 return selector_selector_statement_parse(block_mask,
1171 if (!strcmp(tokens[0], "member_id")) {
1172 if (n_tokens != 2) {
1174 *err_line = n_lines;
1176 *err_msg = "Invalid member_id statement.";
1180 s->params.member_id_field_name = strdup(tokens[1]);
1181 if (!s->params.member_id_field_name) {
1183 *err_line = n_lines;
1185 *err_msg = "Memory allocation failed.";
1192 if (!strcmp(tokens[0], "n_groups_max")) {
1193 char *p = tokens[1];
1195 if (n_tokens != 2) {
1197 *err_line = n_lines;
1199 *err_msg = "Invalid n_groups statement.";
1203 s->params.n_groups_max = strtoul(p, &p, 0);
1206 *err_line = n_lines;
1208 *err_msg = "Invalid n_groups argument.";
1215 if (!strcmp(tokens[0], "n_members_per_group_max")) {
1216 char *p = tokens[1];
1218 if (n_tokens != 2) {
1220 *err_line = n_lines;
1222 *err_msg = "Invalid n_members_per_group statement.";
1226 s->params.n_members_per_group_max = strtoul(p, &p, 0);
1229 *err_line = n_lines;
1231 *err_msg = "Invalid n_members_per_group argument.";
1238 /* Anything else. */
1240 *err_line = n_lines;
1242 *err_msg = "Invalid statement.";
1249 * regarray NAME size SIZE initval INITVAL
1251 struct regarray_spec {
1258 regarray_spec_free(struct regarray_spec *s)
1268 regarray_statement_parse(struct regarray_spec *s,
1273 const char **err_msg)
1278 if ((n_tokens != 6) ||
1279 strcmp(tokens[2], "size") ||
1280 strcmp(tokens[4], "initval")) {
1282 *err_line = n_lines;
1284 *err_msg = "Invalid regarray statement.";
1289 s->name = strdup(tokens[1]);
1292 *err_line = n_lines;
1294 *err_msg = "Memory allocation failed.";
1299 s->size = strtoul(p, &p, 0);
1300 if (p[0] || !s->size) {
1302 *err_line = n_lines;
1304 *err_msg = "Invalid size argument.";
1309 s->init_val = strtoull(p, &p, 0);
1312 *err_line = n_lines;
1314 *err_msg = "Invalid initval argument.";
1324 * metarray NAME size SIZE
1326 struct metarray_spec {
1332 metarray_spec_free(struct metarray_spec *s)
1342 metarray_statement_parse(struct metarray_spec *s,
1347 const char **err_msg)
1352 if ((n_tokens != 4) || strcmp(tokens[2], "size")) {
1354 *err_line = n_lines;
1356 *err_msg = "Invalid metarray statement.";
1361 s->name = strdup(tokens[1]);
1364 *err_line = n_lines;
1366 *err_msg = "Memory allocation failed.";
1371 s->size = strtoul(p, &p, 0);
1372 if (p[0] || !s->size) {
1374 *err_line = n_lines;
1376 *err_msg = "Invalid size argument.";
1392 const char **instructions;
1393 uint32_t n_instructions;
1397 apply_spec_free(struct apply_spec *s)
1404 for (i = 0; i < s->n_instructions; i++) {
1405 uintptr_t instr = (uintptr_t)s->instructions[i];
1407 free((void *)instr);
1410 free(s->instructions);
1411 s->instructions = NULL;
1413 s->n_instructions = 0;
1417 apply_statement_parse(uint32_t *block_mask,
1422 const char **err_msg)
1425 if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
1427 *err_line = n_lines;
1429 *err_msg = "Invalid apply statement.";
1434 *block_mask |= 1 << APPLY_BLOCK;
1440 apply_block_parse(struct apply_spec *s,
1441 uint32_t *block_mask,
1446 const char **err_msg)
1448 char buffer[RTE_SWX_INSTRUCTION_SIZE], *instr;
1449 const char **new_instructions;
1452 /* Handle end of block. */
1453 if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
1454 *block_mask &= ~(1 << APPLY_BLOCK);
1460 for (i = 0; i < n_tokens; i++) {
1462 strcat(buffer, " ");
1463 strcat(buffer, tokens[i]);
1466 instr = strdup(buffer);
1469 *err_line = n_lines;
1471 *err_msg = "Memory allocation failed.";
1475 new_instructions = realloc(s->instructions,
1476 (s->n_instructions + 1) * sizeof(char *));
1477 if (!new_instructions) {
1481 *err_line = n_lines;
1483 *err_msg = "Memory allocation failed.";
1487 s->instructions = new_instructions;
1488 s->instructions[s->n_instructions] = instr;
1489 s->n_instructions++;
1498 rte_swx_pipeline_build_from_spec(struct rte_swx_pipeline *p,
1501 const char **err_msg)
1503 struct extobj_spec extobj_spec = {0};
1504 struct struct_spec struct_spec = {0};
1505 struct header_spec header_spec = {0};
1506 struct metadata_spec metadata_spec = {0};
1507 struct action_spec action_spec = {0};
1508 struct table_spec table_spec = {0};
1509 struct selector_spec selector_spec = {0};
1510 struct regarray_spec regarray_spec = {0};
1511 struct metarray_spec metarray_spec = {0};
1512 struct apply_spec apply_spec = {0};
1514 uint32_t block_mask = 0;
1517 /* Check the input arguments. */
1522 *err_msg = "Null pipeline arument.";
1531 *err_msg = "Null specification file argument.";
1536 for (n_lines = 1; ; n_lines++) {
1537 char line[MAX_LINE_LENGTH];
1538 char *tokens[MAX_TOKENS], *ptr = line;
1539 uint32_t n_tokens = 0;
1541 /* Read next line. */
1542 if (!fgets(line, sizeof(line), spec))
1545 /* Parse the line into tokens. */
1550 token = strtok_r(ptr, " \f\n\r\t\v", &ptr);
1554 /* Handle comments. */
1555 if ((token[0] == '#') ||
1556 (token[0] == ';') ||
1557 ((token[0] == '/') && (token[1] == '/'))) {
1561 /* Handle excessively long lines. */
1562 if (n_tokens >= MAX_TOKENS) {
1564 *err_line = n_lines;
1566 *err_msg = "Too many tokens.";
1571 /* Handle excessively long tokens. */
1572 if (strnlen(token, RTE_SWX_NAME_SIZE) >=
1573 RTE_SWX_NAME_SIZE) {
1575 *err_line = n_lines;
1577 *err_msg = "Token too big.";
1583 tokens[n_tokens] = token;
1587 /* Handle empty lines. */
1592 if (block_mask & (1 << STRUCT_BLOCK)) {
1593 status = struct_block_parse(&struct_spec,
1603 if (block_mask & (1 << STRUCT_BLOCK))
1607 status = rte_swx_pipeline_struct_type_register(p,
1610 struct_spec.n_fields);
1613 *err_line = n_lines;
1615 *err_msg = "Struct registration error.";
1619 struct_spec_free(&struct_spec);
1625 if (block_mask & (1 << ACTION_BLOCK)) {
1626 status = action_block_parse(&action_spec,
1636 if (block_mask & (1 << ACTION_BLOCK))
1640 status = rte_swx_pipeline_action_config(p,
1642 action_spec.args_struct_type_name,
1643 action_spec.instructions,
1644 action_spec.n_instructions);
1647 *err_line = n_lines;
1649 *err_msg = "Action config error.";
1653 action_spec_free(&action_spec);
1659 if (block_mask & (1 << TABLE_BLOCK)) {
1660 status = table_block_parse(&table_spec,
1670 if (block_mask & (1 << TABLE_BLOCK))
1674 status = rte_swx_pipeline_table_config(p,
1677 table_spec.recommended_table_type_name,
1682 *err_line = n_lines;
1684 *err_msg = "Table configuration error.";
1688 table_spec_free(&table_spec);
1693 /* selector block. */
1694 if (block_mask & (1 << SELECTOR_BLOCK)) {
1695 status = selector_block_parse(&selector_spec,
1705 if (block_mask & (1 << SELECTOR_BLOCK))
1709 status = rte_swx_pipeline_selector_config(p,
1711 &selector_spec.params);
1714 *err_line = n_lines;
1716 *err_msg = "Selector configuration error.";
1720 selector_spec_free(&selector_spec);
1726 if (block_mask & (1 << APPLY_BLOCK)) {
1727 status = apply_block_parse(&apply_spec,
1737 if (block_mask & (1 << APPLY_BLOCK))
1741 status = rte_swx_pipeline_instructions_config(p,
1742 apply_spec.instructions,
1743 apply_spec.n_instructions);
1746 *err_line = n_lines;
1748 *err_msg = "Pipeline instructions err.";
1752 apply_spec_free(&apply_spec);
1758 if (!strcmp(tokens[0], "extobj")) {
1759 status = extobj_statement_parse(&extobj_spec,
1768 status = rte_swx_pipeline_extern_object_config(p,
1770 extobj_spec.extern_type_name,
1771 extobj_spec.pragma);
1774 *err_line = n_lines;
1776 *err_msg = "Extern object config err.";
1780 extobj_spec_free(&extobj_spec);
1786 if (!strcmp(tokens[0], "struct")) {
1787 status = struct_statement_parse(&struct_spec,
1801 if (!strcmp(tokens[0], "header")) {
1802 status = header_statement_parse(&header_spec,
1811 status = rte_swx_pipeline_packet_header_register(p,
1813 header_spec.struct_type_name);
1816 *err_line = n_lines;
1818 *err_msg = "Header registration error.";
1822 header_spec_free(&header_spec);
1828 if (!strcmp(tokens[0], "metadata")) {
1829 status = metadata_statement_parse(&metadata_spec,
1838 status = rte_swx_pipeline_packet_metadata_register(p,
1839 metadata_spec.struct_type_name);
1842 *err_line = n_lines;
1844 *err_msg = "Meta-data reg err.";
1848 metadata_spec_free(&metadata_spec);
1854 if (!strcmp(tokens[0], "action")) {
1855 status = action_statement_parse(&action_spec,
1869 if (!strcmp(tokens[0], "table")) {
1870 status = table_statement_parse(&table_spec,
1884 if (!strcmp(tokens[0], "selector")) {
1885 status = selector_statement_parse(&selector_spec,
1899 if (!strcmp(tokens[0], "regarray")) {
1900 status = regarray_statement_parse(®array_spec,
1909 status = rte_swx_pipeline_regarray_config(p,
1912 regarray_spec.init_val);
1915 *err_line = n_lines;
1917 *err_msg = "Register array configuration error.";
1921 regarray_spec_free(®array_spec);
1927 if (!strcmp(tokens[0], "metarray")) {
1928 status = metarray_statement_parse(&metarray_spec,
1937 status = rte_swx_pipeline_metarray_config(p,
1939 metarray_spec.size);
1942 *err_line = n_lines;
1944 *err_msg = "Meter array configuration error.";
1948 metarray_spec_free(&metarray_spec);
1954 if (!strcmp(tokens[0], "apply")) {
1955 status = apply_statement_parse(&block_mask,
1967 /* Anything else. */
1969 *err_line = n_lines;
1971 *err_msg = "Unknown statement.";
1976 /* Handle unfinished block. */
1979 *err_line = n_lines;
1981 *err_msg = "Missing }.";
1986 /* Pipeline build. */
1987 status = rte_swx_pipeline_build(p);
1990 *err_line = n_lines;
1992 *err_msg = "Pipeline build error.";
1999 extobj_spec_free(&extobj_spec);
2000 struct_spec_free(&struct_spec);
2001 header_spec_free(&header_spec);
2002 metadata_spec_free(&metadata_spec);
2003 action_spec_free(&action_spec);
2004 table_spec_free(&table_spec);
2005 selector_spec_free(&selector_spec);
2006 regarray_spec_free(®array_spec);
2007 metarray_spec_free(&metarray_spec);
2008 apply_spec_free(&apply_spec);