199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson * Copyright(c) 2020 Intel Corporation
399a2dd95SBruce Richardson */
499a2dd95SBruce Richardson #include <stdint.h>
5894c93e1SCristian Dumitrescu #include <inttypes.h>
699a2dd95SBruce Richardson #include <stdlib.h>
799a2dd95SBruce Richardson #include <stdio.h>
899a2dd95SBruce Richardson #include <string.h>
999a2dd95SBruce Richardson #include <errno.h>
1099a2dd95SBruce Richardson
1173d94b00SCristian Dumitrescu #include <rte_common.h>
1254cae37eSCristian Dumitrescu #include <rte_mempool.h>
1354cae37eSCristian Dumitrescu
1454cae37eSCristian Dumitrescu #include <rte_swx_port_ethdev.h>
1554cae37eSCristian Dumitrescu #include <rte_swx_port_ring.h>
1654cae37eSCristian Dumitrescu #include <rte_swx_port_source_sink.h>
1754cae37eSCristian Dumitrescu #include <rte_swx_port_fd.h>
1873d94b00SCristian Dumitrescu
193421eb42SCristian Dumitrescu #include "rte_swx_pipeline_spec.h"
2099a2dd95SBruce Richardson
2173d94b00SCristian Dumitrescu #ifndef MAX_LINE_LENGTH
2273d94b00SCristian Dumitrescu #define MAX_LINE_LENGTH 2048
2373d94b00SCristian Dumitrescu #endif
2473d94b00SCristian Dumitrescu
2573d94b00SCristian Dumitrescu #ifndef MAX_TOKENS
2673d94b00SCristian Dumitrescu #define MAX_TOKENS 256
2773d94b00SCristian Dumitrescu #endif
2899a2dd95SBruce Richardson
2999a2dd95SBruce Richardson #define STRUCT_BLOCK 0
3099a2dd95SBruce Richardson #define ACTION_BLOCK 1
3199a2dd95SBruce Richardson #define TABLE_BLOCK 2
3299a2dd95SBruce Richardson #define TABLE_KEY_BLOCK 3
3399a2dd95SBruce Richardson #define TABLE_ACTIONS_BLOCK 4
34cdaa937dSCristian Dumitrescu #define SELECTOR_BLOCK 5
35cdaa937dSCristian Dumitrescu #define SELECTOR_SELECTOR_BLOCK 6
364f59d372SCristian Dumitrescu #define LEARNER_BLOCK 7
374f59d372SCristian Dumitrescu #define LEARNER_KEY_BLOCK 8
384f59d372SCristian Dumitrescu #define LEARNER_ACTIONS_BLOCK 9
39e2ecc535SCristian Dumitrescu #define LEARNER_TIMEOUT_BLOCK 10
40e2ecc535SCristian Dumitrescu #define APPLY_BLOCK 11
4199a2dd95SBruce Richardson
4299a2dd95SBruce Richardson /*
4399a2dd95SBruce Richardson * extobj.
4499a2dd95SBruce Richardson */
4599a2dd95SBruce Richardson static void
extobj_spec_free(struct extobj_spec * s)4699a2dd95SBruce Richardson extobj_spec_free(struct extobj_spec *s)
4799a2dd95SBruce Richardson {
4899a2dd95SBruce Richardson if (!s)
4999a2dd95SBruce Richardson return;
5099a2dd95SBruce Richardson
5199a2dd95SBruce Richardson free(s->name);
5299a2dd95SBruce Richardson s->name = NULL;
5399a2dd95SBruce Richardson
5499a2dd95SBruce Richardson free(s->extern_type_name);
5599a2dd95SBruce Richardson s->extern_type_name = NULL;
5699a2dd95SBruce Richardson
5799a2dd95SBruce Richardson free(s->pragma);
5899a2dd95SBruce Richardson s->pragma = NULL;
5999a2dd95SBruce Richardson }
6099a2dd95SBruce Richardson
6199a2dd95SBruce Richardson static int
extobj_statement_parse(struct extobj_spec * s,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)6299a2dd95SBruce Richardson extobj_statement_parse(struct extobj_spec *s,
6399a2dd95SBruce Richardson char **tokens,
6499a2dd95SBruce Richardson uint32_t n_tokens,
6599a2dd95SBruce Richardson uint32_t n_lines,
6699a2dd95SBruce Richardson uint32_t *err_line,
6799a2dd95SBruce Richardson const char **err_msg)
6899a2dd95SBruce Richardson {
6999a2dd95SBruce Richardson /* Check format. */
7099a2dd95SBruce Richardson if (((n_tokens != 4) && (n_tokens != 6)) ||
7199a2dd95SBruce Richardson ((n_tokens == 4) && strcmp(tokens[2], "instanceof")) ||
7299a2dd95SBruce Richardson ((n_tokens == 6) && (strcmp(tokens[2], "instanceof") ||
7399a2dd95SBruce Richardson strcmp(tokens[4], "pragma")))) {
7499a2dd95SBruce Richardson if (err_line)
7599a2dd95SBruce Richardson *err_line = n_lines;
7699a2dd95SBruce Richardson if (err_msg)
7799a2dd95SBruce Richardson *err_msg = "Invalid extobj statement.";
7899a2dd95SBruce Richardson return -EINVAL;
7999a2dd95SBruce Richardson }
8099a2dd95SBruce Richardson
8199a2dd95SBruce Richardson /* spec. */
8299a2dd95SBruce Richardson s->name = strdup(tokens[1]);
8399a2dd95SBruce Richardson s->extern_type_name = strdup(tokens[3]);
8499a2dd95SBruce Richardson s->pragma = (n_tokens == 6) ? strdup(tokens[5]) : NULL;
8599a2dd95SBruce Richardson
8699a2dd95SBruce Richardson if (!s->name ||
8799a2dd95SBruce Richardson !s->extern_type_name ||
8899a2dd95SBruce Richardson ((n_tokens == 6) && !s->pragma)) {
8999a2dd95SBruce Richardson free(s->name);
9099a2dd95SBruce Richardson free(s->extern_type_name);
9199a2dd95SBruce Richardson free(s->pragma);
9299a2dd95SBruce Richardson
9399a2dd95SBruce Richardson if (err_line)
9499a2dd95SBruce Richardson *err_line = n_lines;
9599a2dd95SBruce Richardson if (err_msg)
9699a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
9799a2dd95SBruce Richardson return -ENOMEM;
9899a2dd95SBruce Richardson }
9999a2dd95SBruce Richardson
10099a2dd95SBruce Richardson return 0;
10199a2dd95SBruce Richardson }
10299a2dd95SBruce Richardson
10399a2dd95SBruce Richardson /*
10499a2dd95SBruce Richardson * struct.
10599a2dd95SBruce Richardson */
10699a2dd95SBruce Richardson static void
struct_spec_free(struct struct_spec * s)10799a2dd95SBruce Richardson struct_spec_free(struct struct_spec *s)
10899a2dd95SBruce Richardson {
10999a2dd95SBruce Richardson uint32_t i;
11099a2dd95SBruce Richardson
11199a2dd95SBruce Richardson if (!s)
11299a2dd95SBruce Richardson return;
11399a2dd95SBruce Richardson
11499a2dd95SBruce Richardson free(s->name);
11599a2dd95SBruce Richardson s->name = NULL;
11699a2dd95SBruce Richardson
11799a2dd95SBruce Richardson for (i = 0; i < s->n_fields; i++) {
11899a2dd95SBruce Richardson uintptr_t name = (uintptr_t)s->fields[i].name;
11999a2dd95SBruce Richardson
12099a2dd95SBruce Richardson free((void *)name);
12199a2dd95SBruce Richardson }
12299a2dd95SBruce Richardson
12399a2dd95SBruce Richardson free(s->fields);
12499a2dd95SBruce Richardson s->fields = NULL;
12599a2dd95SBruce Richardson
12699a2dd95SBruce Richardson s->n_fields = 0;
127cef38969SCristian Dumitrescu
128cef38969SCristian Dumitrescu s->varbit = 0;
12999a2dd95SBruce Richardson }
13099a2dd95SBruce Richardson
13199a2dd95SBruce Richardson static int
struct_statement_parse(struct struct_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)13299a2dd95SBruce Richardson struct_statement_parse(struct struct_spec *s,
13399a2dd95SBruce Richardson uint32_t *block_mask,
13499a2dd95SBruce Richardson char **tokens,
13599a2dd95SBruce Richardson uint32_t n_tokens,
13699a2dd95SBruce Richardson uint32_t n_lines,
13799a2dd95SBruce Richardson uint32_t *err_line,
13899a2dd95SBruce Richardson const char **err_msg)
13999a2dd95SBruce Richardson {
14099a2dd95SBruce Richardson /* Check format. */
14199a2dd95SBruce Richardson if ((n_tokens != 3) || strcmp(tokens[2], "{")) {
14299a2dd95SBruce Richardson if (err_line)
14399a2dd95SBruce Richardson *err_line = n_lines;
14499a2dd95SBruce Richardson if (err_msg)
14599a2dd95SBruce Richardson *err_msg = "Invalid struct statement.";
14699a2dd95SBruce Richardson return -EINVAL;
14799a2dd95SBruce Richardson }
14899a2dd95SBruce Richardson
14999a2dd95SBruce Richardson /* spec. */
15099a2dd95SBruce Richardson s->name = strdup(tokens[1]);
15199a2dd95SBruce Richardson if (!s->name) {
15299a2dd95SBruce Richardson if (err_line)
15399a2dd95SBruce Richardson *err_line = n_lines;
15499a2dd95SBruce Richardson if (err_msg)
15599a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
15699a2dd95SBruce Richardson return -ENOMEM;
15799a2dd95SBruce Richardson }
15899a2dd95SBruce Richardson
15999a2dd95SBruce Richardson /* block_mask. */
16099a2dd95SBruce Richardson *block_mask |= 1 << STRUCT_BLOCK;
16199a2dd95SBruce Richardson
16299a2dd95SBruce Richardson return 0;
16399a2dd95SBruce Richardson }
16499a2dd95SBruce Richardson
16599a2dd95SBruce Richardson static int
struct_block_parse(struct struct_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)16699a2dd95SBruce Richardson struct_block_parse(struct struct_spec *s,
16799a2dd95SBruce Richardson uint32_t *block_mask,
16899a2dd95SBruce Richardson char **tokens,
16999a2dd95SBruce Richardson uint32_t n_tokens,
17099a2dd95SBruce Richardson uint32_t n_lines,
17199a2dd95SBruce Richardson uint32_t *err_line,
17299a2dd95SBruce Richardson const char **err_msg)
17399a2dd95SBruce Richardson {
17499a2dd95SBruce Richardson struct rte_swx_field_params *new_fields;
175cef38969SCristian Dumitrescu char *p = tokens[0], *name = NULL;
17699a2dd95SBruce Richardson uint32_t n_bits;
177cef38969SCristian Dumitrescu int varbit = 0, error = 0, error_size_invalid = 0, error_varbit_not_last = 0;
17899a2dd95SBruce Richardson
17999a2dd95SBruce Richardson /* Handle end of block. */
18099a2dd95SBruce Richardson if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
18199a2dd95SBruce Richardson *block_mask &= ~(1 << STRUCT_BLOCK);
18299a2dd95SBruce Richardson return 0;
18399a2dd95SBruce Richardson }
18499a2dd95SBruce Richardson
18599a2dd95SBruce Richardson /* Check format. */
186cef38969SCristian Dumitrescu if (n_tokens != 2) {
187cef38969SCristian Dumitrescu error = -EINVAL;
188cef38969SCristian Dumitrescu goto error;
189cef38969SCristian Dumitrescu }
190cef38969SCristian Dumitrescu
191cef38969SCristian Dumitrescu if (s->varbit) {
192cef38969SCristian Dumitrescu error = -EINVAL;
193cef38969SCristian Dumitrescu error_varbit_not_last = 1;
194cef38969SCristian Dumitrescu goto error;
195cef38969SCristian Dumitrescu }
196cef38969SCristian Dumitrescu
197cef38969SCristian Dumitrescu if (!strncmp(p, "bit<", strlen("bit<"))) {
198cef38969SCristian Dumitrescu size_t len = strlen(p);
199cef38969SCristian Dumitrescu
200cef38969SCristian Dumitrescu if ((len < strlen("bit< >")) || (p[len - 1] != '>')) {
201cef38969SCristian Dumitrescu error = -EINVAL;
202cef38969SCristian Dumitrescu goto error;
20399a2dd95SBruce Richardson }
20499a2dd95SBruce Richardson
20599a2dd95SBruce Richardson /* Remove the "bit<" and ">". */
20699a2dd95SBruce Richardson p[strlen(p) - 1] = 0;
207cef38969SCristian Dumitrescu p += strlen("bit<");
208cef38969SCristian Dumitrescu } else if (!strncmp(p, "varbit<", strlen("varbit<"))) {
209cef38969SCristian Dumitrescu size_t len = strlen(p);
210cef38969SCristian Dumitrescu
211cef38969SCristian Dumitrescu if ((len < strlen("varbit< >")) || (p[len - 1] != '>')) {
212cef38969SCristian Dumitrescu error = -EINVAL;
213cef38969SCristian Dumitrescu goto error;
214cef38969SCristian Dumitrescu }
215cef38969SCristian Dumitrescu
216cef38969SCristian Dumitrescu /* Remove the "varbit<" and ">". */
217cef38969SCristian Dumitrescu p[strlen(p) - 1] = 0;
218cef38969SCristian Dumitrescu p += strlen("varbit<");
219cef38969SCristian Dumitrescu
220cef38969SCristian Dumitrescu /* Set the varbit flag. */
221cef38969SCristian Dumitrescu varbit = 1;
222cef38969SCristian Dumitrescu } else {
223cef38969SCristian Dumitrescu error = -EINVAL;
224cef38969SCristian Dumitrescu goto error;
225cef38969SCristian Dumitrescu }
22699a2dd95SBruce Richardson
22799a2dd95SBruce Richardson n_bits = strtoul(p, &p, 0);
22899a2dd95SBruce Richardson if ((p[0]) ||
22999a2dd95SBruce Richardson !n_bits ||
230076d6128SCristian Dumitrescu (n_bits % 8)) {
231cef38969SCristian Dumitrescu error = -EINVAL;
232cef38969SCristian Dumitrescu error_size_invalid = 1;
233cef38969SCristian Dumitrescu goto error;
23499a2dd95SBruce Richardson }
23599a2dd95SBruce Richardson
23699a2dd95SBruce Richardson /* spec. */
23799a2dd95SBruce Richardson name = strdup(tokens[1]);
23899a2dd95SBruce Richardson if (!name) {
239cef38969SCristian Dumitrescu error = -ENOMEM;
240cef38969SCristian Dumitrescu goto error;
24199a2dd95SBruce Richardson }
24299a2dd95SBruce Richardson
243cef38969SCristian Dumitrescu new_fields = realloc(s->fields, (s->n_fields + 1) * sizeof(struct rte_swx_field_params));
24499a2dd95SBruce Richardson if (!new_fields) {
245cef38969SCristian Dumitrescu error = -ENOMEM;
246cef38969SCristian Dumitrescu goto error;
24799a2dd95SBruce Richardson }
24899a2dd95SBruce Richardson
24999a2dd95SBruce Richardson s->fields = new_fields;
25099a2dd95SBruce Richardson s->fields[s->n_fields].name = name;
25199a2dd95SBruce Richardson s->fields[s->n_fields].n_bits = n_bits;
25299a2dd95SBruce Richardson s->n_fields++;
253cef38969SCristian Dumitrescu s->varbit = varbit;
25499a2dd95SBruce Richardson
25599a2dd95SBruce Richardson return 0;
256cef38969SCristian Dumitrescu
257cef38969SCristian Dumitrescu error:
258cef38969SCristian Dumitrescu free(name);
259cef38969SCristian Dumitrescu
260cef38969SCristian Dumitrescu if (err_line)
261cef38969SCristian Dumitrescu *err_line = n_lines;
262cef38969SCristian Dumitrescu
263cef38969SCristian Dumitrescu if (err_msg) {
264cef38969SCristian Dumitrescu *err_msg = "Invalid struct field statement.";
265cef38969SCristian Dumitrescu
266cef38969SCristian Dumitrescu if ((error == -EINVAL) && error_varbit_not_last)
267cef38969SCristian Dumitrescu *err_msg = "Varbit field is not the last struct field.";
268cef38969SCristian Dumitrescu
269cef38969SCristian Dumitrescu if ((error == -EINVAL) && error_size_invalid)
270cef38969SCristian Dumitrescu *err_msg = "Invalid struct field size.";
271cef38969SCristian Dumitrescu
272cef38969SCristian Dumitrescu if (error == -ENOMEM)
273cef38969SCristian Dumitrescu *err_msg = "Memory allocation failed.";
274cef38969SCristian Dumitrescu }
275cef38969SCristian Dumitrescu
276cef38969SCristian Dumitrescu return error;
27799a2dd95SBruce Richardson }
27899a2dd95SBruce Richardson
27999a2dd95SBruce Richardson /*
28099a2dd95SBruce Richardson * header.
28199a2dd95SBruce Richardson */
28299a2dd95SBruce Richardson static void
header_spec_free(struct header_spec * s)28399a2dd95SBruce Richardson header_spec_free(struct header_spec *s)
28499a2dd95SBruce Richardson {
28599a2dd95SBruce Richardson if (!s)
28699a2dd95SBruce Richardson return;
28799a2dd95SBruce Richardson
28899a2dd95SBruce Richardson free(s->name);
28999a2dd95SBruce Richardson s->name = NULL;
29099a2dd95SBruce Richardson
29199a2dd95SBruce Richardson free(s->struct_type_name);
29299a2dd95SBruce Richardson s->struct_type_name = NULL;
29399a2dd95SBruce Richardson }
29499a2dd95SBruce Richardson
29599a2dd95SBruce Richardson static int
header_statement_parse(struct header_spec * s,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)29699a2dd95SBruce Richardson header_statement_parse(struct header_spec *s,
29799a2dd95SBruce Richardson char **tokens,
29899a2dd95SBruce Richardson uint32_t n_tokens,
29999a2dd95SBruce Richardson uint32_t n_lines,
30099a2dd95SBruce Richardson uint32_t *err_line,
30199a2dd95SBruce Richardson const char **err_msg)
30299a2dd95SBruce Richardson {
30399a2dd95SBruce Richardson /* Check format. */
30499a2dd95SBruce Richardson if ((n_tokens != 4) || strcmp(tokens[2], "instanceof")) {
30599a2dd95SBruce Richardson if (err_line)
30699a2dd95SBruce Richardson *err_line = n_lines;
30799a2dd95SBruce Richardson if (err_msg)
30899a2dd95SBruce Richardson *err_msg = "Invalid header statement.";
30999a2dd95SBruce Richardson return -EINVAL;
31099a2dd95SBruce Richardson }
31199a2dd95SBruce Richardson
31299a2dd95SBruce Richardson /* spec. */
31399a2dd95SBruce Richardson s->name = strdup(tokens[1]);
31499a2dd95SBruce Richardson s->struct_type_name = strdup(tokens[3]);
31599a2dd95SBruce Richardson
31699a2dd95SBruce Richardson if (!s->name || !s->struct_type_name) {
31799a2dd95SBruce Richardson free(s->name);
31899a2dd95SBruce Richardson free(s->struct_type_name);
31999a2dd95SBruce Richardson
32099a2dd95SBruce Richardson if (err_line)
32199a2dd95SBruce Richardson *err_line = n_lines;
32299a2dd95SBruce Richardson if (err_msg)
32399a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
32499a2dd95SBruce Richardson return -ENOMEM;
32599a2dd95SBruce Richardson }
32699a2dd95SBruce Richardson
32799a2dd95SBruce Richardson return 0;
32899a2dd95SBruce Richardson }
32999a2dd95SBruce Richardson
33099a2dd95SBruce Richardson /*
33199a2dd95SBruce Richardson * metadata.
33299a2dd95SBruce Richardson */
33399a2dd95SBruce Richardson static void
metadata_spec_free(struct metadata_spec * s)33499a2dd95SBruce Richardson metadata_spec_free(struct metadata_spec *s)
33599a2dd95SBruce Richardson {
33699a2dd95SBruce Richardson if (!s)
33799a2dd95SBruce Richardson return;
33899a2dd95SBruce Richardson
33999a2dd95SBruce Richardson free(s->struct_type_name);
34099a2dd95SBruce Richardson s->struct_type_name = NULL;
34199a2dd95SBruce Richardson }
34299a2dd95SBruce Richardson
34399a2dd95SBruce Richardson static int
metadata_statement_parse(struct metadata_spec * s,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)34499a2dd95SBruce Richardson metadata_statement_parse(struct metadata_spec *s,
34599a2dd95SBruce Richardson char **tokens,
34699a2dd95SBruce Richardson uint32_t n_tokens,
34799a2dd95SBruce Richardson uint32_t n_lines,
34899a2dd95SBruce Richardson uint32_t *err_line,
34999a2dd95SBruce Richardson const char **err_msg)
35099a2dd95SBruce Richardson {
35199a2dd95SBruce Richardson /* Check format. */
35299a2dd95SBruce Richardson if ((n_tokens != 3) || strcmp(tokens[1], "instanceof")) {
35399a2dd95SBruce Richardson if (err_line)
35499a2dd95SBruce Richardson *err_line = n_lines;
35599a2dd95SBruce Richardson if (err_msg)
35699a2dd95SBruce Richardson *err_msg = "Invalid metadata statement.";
35799a2dd95SBruce Richardson return -EINVAL;
35899a2dd95SBruce Richardson }
35999a2dd95SBruce Richardson
36099a2dd95SBruce Richardson /* spec. */
36199a2dd95SBruce Richardson s->struct_type_name = strdup(tokens[2]);
36299a2dd95SBruce Richardson if (!s->struct_type_name) {
36399a2dd95SBruce Richardson if (err_line)
36499a2dd95SBruce Richardson *err_line = n_lines;
36599a2dd95SBruce Richardson if (err_msg)
36699a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
36799a2dd95SBruce Richardson return -ENOMEM;
36899a2dd95SBruce Richardson }
36999a2dd95SBruce Richardson
37099a2dd95SBruce Richardson return 0;
37199a2dd95SBruce Richardson }
37299a2dd95SBruce Richardson
37399a2dd95SBruce Richardson /*
37499a2dd95SBruce Richardson * action.
37599a2dd95SBruce Richardson */
37699a2dd95SBruce Richardson static void
action_spec_free(struct action_spec * s)37799a2dd95SBruce Richardson action_spec_free(struct action_spec *s)
37899a2dd95SBruce Richardson {
37999a2dd95SBruce Richardson uint32_t i;
38099a2dd95SBruce Richardson
38199a2dd95SBruce Richardson if (!s)
38299a2dd95SBruce Richardson return;
38399a2dd95SBruce Richardson
38499a2dd95SBruce Richardson free(s->name);
38599a2dd95SBruce Richardson s->name = NULL;
38699a2dd95SBruce Richardson
38799a2dd95SBruce Richardson free(s->args_struct_type_name);
38899a2dd95SBruce Richardson s->args_struct_type_name = NULL;
38999a2dd95SBruce Richardson
39099a2dd95SBruce Richardson for (i = 0; i < s->n_instructions; i++) {
39199a2dd95SBruce Richardson uintptr_t instr = (uintptr_t)s->instructions[i];
39299a2dd95SBruce Richardson
39399a2dd95SBruce Richardson free((void *)instr);
39499a2dd95SBruce Richardson }
39599a2dd95SBruce Richardson
39699a2dd95SBruce Richardson free(s->instructions);
39799a2dd95SBruce Richardson s->instructions = NULL;
39899a2dd95SBruce Richardson
39999a2dd95SBruce Richardson s->n_instructions = 0;
40099a2dd95SBruce Richardson }
40199a2dd95SBruce Richardson
40299a2dd95SBruce Richardson static int
action_statement_parse(struct action_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)40399a2dd95SBruce Richardson action_statement_parse(struct action_spec *s,
40499a2dd95SBruce Richardson uint32_t *block_mask,
40599a2dd95SBruce Richardson char **tokens,
40699a2dd95SBruce Richardson uint32_t n_tokens,
40799a2dd95SBruce Richardson uint32_t n_lines,
40899a2dd95SBruce Richardson uint32_t *err_line,
40999a2dd95SBruce Richardson const char **err_msg)
41099a2dd95SBruce Richardson {
41199a2dd95SBruce Richardson /* Check format. */
41299a2dd95SBruce Richardson if (((n_tokens != 5) && (n_tokens != 6)) ||
41399a2dd95SBruce Richardson ((n_tokens == 5) &&
41499a2dd95SBruce Richardson (strcmp(tokens[2], "args") ||
41599a2dd95SBruce Richardson strcmp(tokens[3], "none") ||
41699a2dd95SBruce Richardson strcmp(tokens[4], "{"))) ||
41799a2dd95SBruce Richardson ((n_tokens == 6) &&
41899a2dd95SBruce Richardson (strcmp(tokens[2], "args") ||
41999a2dd95SBruce Richardson strcmp(tokens[3], "instanceof") ||
42099a2dd95SBruce Richardson strcmp(tokens[5], "{")))) {
42199a2dd95SBruce Richardson if (err_line)
42299a2dd95SBruce Richardson *err_line = n_lines;
42399a2dd95SBruce Richardson if (err_msg)
42499a2dd95SBruce Richardson *err_msg = "Invalid action statement.";
42599a2dd95SBruce Richardson return -EINVAL;
42699a2dd95SBruce Richardson }
42799a2dd95SBruce Richardson
42899a2dd95SBruce Richardson /* spec. */
42999a2dd95SBruce Richardson s->name = strdup(tokens[1]);
43099a2dd95SBruce Richardson s->args_struct_type_name = (n_tokens == 6) ? strdup(tokens[4]) : NULL;
43199a2dd95SBruce Richardson
43299a2dd95SBruce Richardson if ((!s->name) || ((n_tokens == 6) && !s->args_struct_type_name)) {
43399a2dd95SBruce Richardson if (err_line)
43499a2dd95SBruce Richardson *err_line = n_lines;
43599a2dd95SBruce Richardson if (err_msg)
43699a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
43799a2dd95SBruce Richardson return -ENOMEM;
43899a2dd95SBruce Richardson }
43999a2dd95SBruce Richardson
44099a2dd95SBruce Richardson /* block_mask. */
44199a2dd95SBruce Richardson *block_mask |= 1 << ACTION_BLOCK;
44299a2dd95SBruce Richardson
44399a2dd95SBruce Richardson return 0;
44499a2dd95SBruce Richardson }
44599a2dd95SBruce Richardson
44699a2dd95SBruce Richardson static int
action_block_parse(struct action_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)44799a2dd95SBruce Richardson action_block_parse(struct action_spec *s,
44899a2dd95SBruce Richardson uint32_t *block_mask,
44999a2dd95SBruce Richardson char **tokens,
45099a2dd95SBruce Richardson uint32_t n_tokens,
45199a2dd95SBruce Richardson uint32_t n_lines,
45299a2dd95SBruce Richardson uint32_t *err_line,
45399a2dd95SBruce Richardson const char **err_msg)
45499a2dd95SBruce Richardson {
45599a2dd95SBruce Richardson char buffer[RTE_SWX_INSTRUCTION_SIZE], *instr;
45699a2dd95SBruce Richardson const char **new_instructions;
45799a2dd95SBruce Richardson uint32_t i;
45899a2dd95SBruce Richardson
45999a2dd95SBruce Richardson /* Handle end of block. */
46099a2dd95SBruce Richardson if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
46199a2dd95SBruce Richardson *block_mask &= ~(1 << ACTION_BLOCK);
46299a2dd95SBruce Richardson return 0;
46399a2dd95SBruce Richardson }
46499a2dd95SBruce Richardson
46599a2dd95SBruce Richardson /* spec. */
46699a2dd95SBruce Richardson buffer[0] = 0;
46799a2dd95SBruce Richardson for (i = 0; i < n_tokens; i++) {
46899a2dd95SBruce Richardson if (i)
46999a2dd95SBruce Richardson strcat(buffer, " ");
47099a2dd95SBruce Richardson strcat(buffer, tokens[i]);
47199a2dd95SBruce Richardson }
47299a2dd95SBruce Richardson
47399a2dd95SBruce Richardson instr = strdup(buffer);
47499a2dd95SBruce Richardson if (!instr) {
47599a2dd95SBruce Richardson if (err_line)
47699a2dd95SBruce Richardson *err_line = n_lines;
47799a2dd95SBruce Richardson if (err_msg)
47899a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
47999a2dd95SBruce Richardson return -ENOMEM;
48099a2dd95SBruce Richardson }
48199a2dd95SBruce Richardson
48299a2dd95SBruce Richardson new_instructions = realloc(s->instructions,
48399a2dd95SBruce Richardson (s->n_instructions + 1) * sizeof(char *));
48499a2dd95SBruce Richardson if (!new_instructions) {
48599a2dd95SBruce Richardson free(instr);
48699a2dd95SBruce Richardson
48799a2dd95SBruce Richardson if (err_line)
48899a2dd95SBruce Richardson *err_line = n_lines;
48999a2dd95SBruce Richardson if (err_msg)
49099a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
49199a2dd95SBruce Richardson return -ENOMEM;
49299a2dd95SBruce Richardson }
49399a2dd95SBruce Richardson
49499a2dd95SBruce Richardson s->instructions = new_instructions;
49599a2dd95SBruce Richardson s->instructions[s->n_instructions] = instr;
49699a2dd95SBruce Richardson s->n_instructions++;
49799a2dd95SBruce Richardson
49899a2dd95SBruce Richardson return 0;
49999a2dd95SBruce Richardson }
50099a2dd95SBruce Richardson
50199a2dd95SBruce Richardson /*
50299a2dd95SBruce Richardson * table.
50399a2dd95SBruce Richardson */
50499a2dd95SBruce Richardson static void
table_spec_free(struct table_spec * s)50599a2dd95SBruce Richardson table_spec_free(struct table_spec *s)
50699a2dd95SBruce Richardson {
5079560a329SCristian Dumitrescu uintptr_t default_action_name, default_action_args, hash_func_name;
50899a2dd95SBruce Richardson uint32_t i;
50999a2dd95SBruce Richardson
51099a2dd95SBruce Richardson if (!s)
51199a2dd95SBruce Richardson return;
51299a2dd95SBruce Richardson
51399a2dd95SBruce Richardson free(s->name);
51499a2dd95SBruce Richardson s->name = NULL;
51599a2dd95SBruce Richardson
51699a2dd95SBruce Richardson for (i = 0; i < s->params.n_fields; i++) {
51799a2dd95SBruce Richardson uintptr_t name = (uintptr_t)s->params.fields[i].name;
51899a2dd95SBruce Richardson
51999a2dd95SBruce Richardson free((void *)name);
52099a2dd95SBruce Richardson }
52199a2dd95SBruce Richardson
52299a2dd95SBruce Richardson free(s->params.fields);
52399a2dd95SBruce Richardson s->params.fields = NULL;
52499a2dd95SBruce Richardson
52599a2dd95SBruce Richardson s->params.n_fields = 0;
52699a2dd95SBruce Richardson
52799a2dd95SBruce Richardson for (i = 0; i < s->params.n_actions; i++) {
52899a2dd95SBruce Richardson uintptr_t name = (uintptr_t)s->params.action_names[i];
52999a2dd95SBruce Richardson
53099a2dd95SBruce Richardson free((void *)name);
53199a2dd95SBruce Richardson }
53299a2dd95SBruce Richardson
53399a2dd95SBruce Richardson free(s->params.action_names);
53499a2dd95SBruce Richardson s->params.action_names = NULL;
53599a2dd95SBruce Richardson
53699a2dd95SBruce Richardson s->params.n_actions = 0;
53799a2dd95SBruce Richardson
53899a2dd95SBruce Richardson default_action_name = (uintptr_t)s->params.default_action_name;
53999a2dd95SBruce Richardson free((void *)default_action_name);
54099a2dd95SBruce Richardson s->params.default_action_name = NULL;
54199a2dd95SBruce Richardson
54273d94b00SCristian Dumitrescu default_action_args = (uintptr_t)s->params.default_action_args;
54373d94b00SCristian Dumitrescu free((void *)default_action_args);
54473d94b00SCristian Dumitrescu s->params.default_action_args = NULL;
54599a2dd95SBruce Richardson
546cd79e020SYogesh Jangra free(s->params.action_is_for_table_entries);
547cd79e020SYogesh Jangra s->params.action_is_for_table_entries = NULL;
548cd79e020SYogesh Jangra
549cd79e020SYogesh Jangra free(s->params.action_is_for_default_entry);
550cd79e020SYogesh Jangra s->params.action_is_for_default_entry = NULL;
551cd79e020SYogesh Jangra
55299a2dd95SBruce Richardson s->params.default_action_is_const = 0;
55399a2dd95SBruce Richardson
5549560a329SCristian Dumitrescu hash_func_name = (uintptr_t)s->params.hash_func_name;
5559560a329SCristian Dumitrescu free((void *)hash_func_name);
5569560a329SCristian Dumitrescu s->params.hash_func_name = NULL;
5579560a329SCristian Dumitrescu
55899a2dd95SBruce Richardson free(s->recommended_table_type_name);
55999a2dd95SBruce Richardson s->recommended_table_type_name = NULL;
56099a2dd95SBruce Richardson
56199a2dd95SBruce Richardson free(s->args);
56299a2dd95SBruce Richardson s->args = NULL;
56399a2dd95SBruce Richardson
56499a2dd95SBruce Richardson s->size = 0;
56599a2dd95SBruce Richardson }
56699a2dd95SBruce Richardson
56799a2dd95SBruce Richardson static int
table_key_statement_parse(uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)56899a2dd95SBruce Richardson table_key_statement_parse(uint32_t *block_mask,
56999a2dd95SBruce Richardson char **tokens,
57099a2dd95SBruce Richardson uint32_t n_tokens,
57199a2dd95SBruce Richardson uint32_t n_lines,
57299a2dd95SBruce Richardson uint32_t *err_line,
57399a2dd95SBruce Richardson const char **err_msg)
57499a2dd95SBruce Richardson {
57599a2dd95SBruce Richardson /* Check format. */
57699a2dd95SBruce Richardson if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
57799a2dd95SBruce Richardson if (err_line)
57899a2dd95SBruce Richardson *err_line = n_lines;
57999a2dd95SBruce Richardson if (err_msg)
58099a2dd95SBruce Richardson *err_msg = "Invalid key statement.";
58199a2dd95SBruce Richardson return -EINVAL;
58299a2dd95SBruce Richardson }
58399a2dd95SBruce Richardson
58499a2dd95SBruce Richardson /* block_mask. */
58599a2dd95SBruce Richardson *block_mask |= 1 << TABLE_KEY_BLOCK;
58699a2dd95SBruce Richardson
58799a2dd95SBruce Richardson return 0;
58899a2dd95SBruce Richardson }
58999a2dd95SBruce Richardson
59099a2dd95SBruce Richardson static int
table_key_block_parse(struct table_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)59199a2dd95SBruce Richardson table_key_block_parse(struct table_spec *s,
59299a2dd95SBruce Richardson uint32_t *block_mask,
59399a2dd95SBruce Richardson char **tokens,
59499a2dd95SBruce Richardson uint32_t n_tokens,
59599a2dd95SBruce Richardson uint32_t n_lines,
59699a2dd95SBruce Richardson uint32_t *err_line,
59799a2dd95SBruce Richardson const char **err_msg)
59899a2dd95SBruce Richardson {
59999a2dd95SBruce Richardson struct rte_swx_match_field_params *new_fields;
60099a2dd95SBruce Richardson enum rte_swx_table_match_type match_type = RTE_SWX_TABLE_MATCH_WILDCARD;
60199a2dd95SBruce Richardson char *name;
60299a2dd95SBruce Richardson
60399a2dd95SBruce Richardson /* Handle end of block. */
60499a2dd95SBruce Richardson if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
60599a2dd95SBruce Richardson *block_mask &= ~(1 << TABLE_KEY_BLOCK);
60699a2dd95SBruce Richardson return 0;
60799a2dd95SBruce Richardson }
60899a2dd95SBruce Richardson
60999a2dd95SBruce Richardson /* Check input arguments. */
61099a2dd95SBruce Richardson if ((n_tokens != 2) ||
61199a2dd95SBruce Richardson (strcmp(tokens[1], "exact") &&
61299a2dd95SBruce Richardson strcmp(tokens[1], "wildcard") &&
61399a2dd95SBruce Richardson strcmp(tokens[1], "lpm"))) {
61499a2dd95SBruce Richardson if (err_line)
61599a2dd95SBruce Richardson *err_line = n_lines;
61699a2dd95SBruce Richardson if (err_msg)
61799a2dd95SBruce Richardson *err_msg = "Invalid match field statement.";
61899a2dd95SBruce Richardson return -EINVAL;
61999a2dd95SBruce Richardson }
62099a2dd95SBruce Richardson
62199a2dd95SBruce Richardson if (!strcmp(tokens[1], "wildcard"))
62299a2dd95SBruce Richardson match_type = RTE_SWX_TABLE_MATCH_WILDCARD;
62399a2dd95SBruce Richardson if (!strcmp(tokens[1], "lpm"))
62499a2dd95SBruce Richardson match_type = RTE_SWX_TABLE_MATCH_LPM;
62599a2dd95SBruce Richardson if (!strcmp(tokens[1], "exact"))
62699a2dd95SBruce Richardson match_type = RTE_SWX_TABLE_MATCH_EXACT;
62799a2dd95SBruce Richardson
62899a2dd95SBruce Richardson name = strdup(tokens[0]);
62999a2dd95SBruce Richardson if (!name) {
63099a2dd95SBruce Richardson if (err_line)
63199a2dd95SBruce Richardson *err_line = n_lines;
63299a2dd95SBruce Richardson if (err_msg)
63399a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
63499a2dd95SBruce Richardson return -ENOMEM;
63599a2dd95SBruce Richardson }
63699a2dd95SBruce Richardson
63799a2dd95SBruce Richardson new_fields = realloc(s->params.fields,
63899a2dd95SBruce Richardson (s->params.n_fields + 1) * sizeof(struct rte_swx_match_field_params));
63999a2dd95SBruce Richardson if (!new_fields) {
64099a2dd95SBruce Richardson free(name);
64199a2dd95SBruce Richardson
64299a2dd95SBruce Richardson if (err_line)
64399a2dd95SBruce Richardson *err_line = n_lines;
64499a2dd95SBruce Richardson if (err_msg)
64599a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
64699a2dd95SBruce Richardson return -ENOMEM;
64799a2dd95SBruce Richardson }
64899a2dd95SBruce Richardson
64999a2dd95SBruce Richardson s->params.fields = new_fields;
65099a2dd95SBruce Richardson s->params.fields[s->params.n_fields].name = name;
65199a2dd95SBruce Richardson s->params.fields[s->params.n_fields].match_type = match_type;
65299a2dd95SBruce Richardson s->params.n_fields++;
65399a2dd95SBruce Richardson
65499a2dd95SBruce Richardson return 0;
65599a2dd95SBruce Richardson }
65699a2dd95SBruce Richardson
65799a2dd95SBruce Richardson static int
table_actions_statement_parse(uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)65899a2dd95SBruce Richardson table_actions_statement_parse(uint32_t *block_mask,
65999a2dd95SBruce Richardson char **tokens,
66099a2dd95SBruce Richardson uint32_t n_tokens,
66199a2dd95SBruce Richardson uint32_t n_lines,
66299a2dd95SBruce Richardson uint32_t *err_line,
66399a2dd95SBruce Richardson const char **err_msg)
66499a2dd95SBruce Richardson {
66599a2dd95SBruce Richardson /* Check format. */
66699a2dd95SBruce Richardson if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
66799a2dd95SBruce Richardson if (err_line)
66899a2dd95SBruce Richardson *err_line = n_lines;
66999a2dd95SBruce Richardson if (err_msg)
67099a2dd95SBruce Richardson *err_msg = "Invalid actions statement.";
67199a2dd95SBruce Richardson return -EINVAL;
67299a2dd95SBruce Richardson }
67399a2dd95SBruce Richardson
67499a2dd95SBruce Richardson /* block_mask. */
67599a2dd95SBruce Richardson *block_mask |= 1 << TABLE_ACTIONS_BLOCK;
67699a2dd95SBruce Richardson
67799a2dd95SBruce Richardson return 0;
67899a2dd95SBruce Richardson }
67999a2dd95SBruce Richardson
68099a2dd95SBruce Richardson static int
table_actions_block_parse(struct table_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)68199a2dd95SBruce Richardson table_actions_block_parse(struct table_spec *s,
68299a2dd95SBruce Richardson uint32_t *block_mask,
68399a2dd95SBruce Richardson char **tokens,
68499a2dd95SBruce Richardson uint32_t n_tokens,
68599a2dd95SBruce Richardson uint32_t n_lines,
68699a2dd95SBruce Richardson uint32_t *err_line,
68799a2dd95SBruce Richardson const char **err_msg)
68899a2dd95SBruce Richardson {
689cd79e020SYogesh Jangra const char **new_action_names = NULL;
690cd79e020SYogesh Jangra int *new_action_is_for_table_entries = NULL, *new_action_is_for_default_entry = NULL;
691cd79e020SYogesh Jangra char *name = NULL;
692cd79e020SYogesh Jangra int action_is_for_table_entries = 1, action_is_for_default_entry = 1;
69399a2dd95SBruce Richardson
69499a2dd95SBruce Richardson /* Handle end of block. */
69599a2dd95SBruce Richardson if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
69699a2dd95SBruce Richardson *block_mask &= ~(1 << TABLE_ACTIONS_BLOCK);
69799a2dd95SBruce Richardson return 0;
69899a2dd95SBruce Richardson }
69999a2dd95SBruce Richardson
70099a2dd95SBruce Richardson /* Check input arguments. */
701cd79e020SYogesh Jangra if ((n_tokens > 2) ||
702cd79e020SYogesh Jangra ((n_tokens == 2) && strcmp(tokens[1], "@tableonly") &&
703cd79e020SYogesh Jangra strcmp(tokens[1], "@defaultonly"))) {
70499a2dd95SBruce Richardson if (err_line)
70599a2dd95SBruce Richardson *err_line = n_lines;
70699a2dd95SBruce Richardson if (err_msg)
70799a2dd95SBruce Richardson *err_msg = "Invalid action name statement.";
70899a2dd95SBruce Richardson return -EINVAL;
70999a2dd95SBruce Richardson }
71099a2dd95SBruce Richardson
71199a2dd95SBruce Richardson name = strdup(tokens[0]);
712cd79e020SYogesh Jangra
713cd79e020SYogesh Jangra if (n_tokens == 2) {
714cd79e020SYogesh Jangra if (!strcmp(tokens[1], "@tableonly"))
715cd79e020SYogesh Jangra action_is_for_default_entry = 0;
716cd79e020SYogesh Jangra
717cd79e020SYogesh Jangra if (!strcmp(tokens[1], "@defaultonly"))
718cd79e020SYogesh Jangra action_is_for_table_entries = 0;
71999a2dd95SBruce Richardson }
72099a2dd95SBruce Richardson
72199a2dd95SBruce Richardson new_action_names = realloc(s->params.action_names,
72299a2dd95SBruce Richardson (s->params.n_actions + 1) * sizeof(char *));
723cd79e020SYogesh Jangra new_action_is_for_table_entries = realloc(s->params.action_is_for_table_entries,
724cd79e020SYogesh Jangra (s->params.n_actions + 1) * sizeof(int));
725cd79e020SYogesh Jangra new_action_is_for_default_entry = realloc(s->params.action_is_for_default_entry,
726cd79e020SYogesh Jangra (s->params.n_actions + 1) * sizeof(int));
727cd79e020SYogesh Jangra
728cd79e020SYogesh Jangra if (!name ||
729cd79e020SYogesh Jangra !new_action_names ||
730cd79e020SYogesh Jangra !new_action_is_for_table_entries ||
731cd79e020SYogesh Jangra !new_action_is_for_default_entry) {
73299a2dd95SBruce Richardson free(name);
733cd79e020SYogesh Jangra free(new_action_names);
734cd79e020SYogesh Jangra free(new_action_is_for_table_entries);
735cd79e020SYogesh Jangra free(new_action_is_for_default_entry);
73699a2dd95SBruce Richardson
73799a2dd95SBruce Richardson if (err_line)
73899a2dd95SBruce Richardson *err_line = n_lines;
73999a2dd95SBruce Richardson if (err_msg)
74099a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
74199a2dd95SBruce Richardson return -ENOMEM;
74299a2dd95SBruce Richardson }
74399a2dd95SBruce Richardson
74499a2dd95SBruce Richardson s->params.action_names = new_action_names;
74599a2dd95SBruce Richardson s->params.action_names[s->params.n_actions] = name;
746cd79e020SYogesh Jangra
747cd79e020SYogesh Jangra s->params.action_is_for_table_entries = new_action_is_for_table_entries;
748cd79e020SYogesh Jangra s->params.action_is_for_table_entries[s->params.n_actions] = action_is_for_table_entries;
749cd79e020SYogesh Jangra
750cd79e020SYogesh Jangra s->params.action_is_for_default_entry = new_action_is_for_default_entry;
751cd79e020SYogesh Jangra s->params.action_is_for_default_entry[s->params.n_actions] = action_is_for_default_entry;
752cd79e020SYogesh Jangra
75399a2dd95SBruce Richardson s->params.n_actions++;
75499a2dd95SBruce Richardson
75599a2dd95SBruce Richardson return 0;
75699a2dd95SBruce Richardson }
75799a2dd95SBruce Richardson
75899a2dd95SBruce Richardson static int
table_default_action_statement_parse(struct table_spec * s,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)75973d94b00SCristian Dumitrescu table_default_action_statement_parse(struct table_spec *s,
76073d94b00SCristian Dumitrescu char **tokens,
76173d94b00SCristian Dumitrescu uint32_t n_tokens,
76273d94b00SCristian Dumitrescu uint32_t n_lines,
76373d94b00SCristian Dumitrescu uint32_t *err_line,
76473d94b00SCristian Dumitrescu const char **err_msg)
76573d94b00SCristian Dumitrescu {
76673d94b00SCristian Dumitrescu uint32_t i;
76773d94b00SCristian Dumitrescu int status = 0, duplicate = 0;
76873d94b00SCristian Dumitrescu
76973d94b00SCristian Dumitrescu /* Check format. */
77073d94b00SCristian Dumitrescu if ((n_tokens < 4) ||
77173d94b00SCristian Dumitrescu strcmp(tokens[2], "args")) {
77273d94b00SCristian Dumitrescu status = -EINVAL;
77373d94b00SCristian Dumitrescu goto error;
77473d94b00SCristian Dumitrescu }
77573d94b00SCristian Dumitrescu
77673d94b00SCristian Dumitrescu if (s->params.default_action_name) {
77773d94b00SCristian Dumitrescu duplicate = 1;
77873d94b00SCristian Dumitrescu status = -EINVAL;
77973d94b00SCristian Dumitrescu goto error;
78073d94b00SCristian Dumitrescu }
78173d94b00SCristian Dumitrescu
78273d94b00SCristian Dumitrescu s->params.default_action_name = strdup(tokens[1]);
78373d94b00SCristian Dumitrescu if (!s->params.default_action_name) {
78473d94b00SCristian Dumitrescu status = -ENOMEM;
78573d94b00SCristian Dumitrescu goto error;
78673d94b00SCristian Dumitrescu }
78773d94b00SCristian Dumitrescu
78873d94b00SCristian Dumitrescu if (strcmp(tokens[3], "none")) {
78973d94b00SCristian Dumitrescu char buffer[MAX_LINE_LENGTH];
79073d94b00SCristian Dumitrescu uint32_t n_tokens_args = n_tokens - 3;
79173d94b00SCristian Dumitrescu
79273d94b00SCristian Dumitrescu if (!strcmp(tokens[n_tokens - 1], "const"))
79373d94b00SCristian Dumitrescu n_tokens_args--;
79473d94b00SCristian Dumitrescu
79573d94b00SCristian Dumitrescu if (!n_tokens_args) {
79673d94b00SCristian Dumitrescu status = -EINVAL;
79773d94b00SCristian Dumitrescu goto error;
79873d94b00SCristian Dumitrescu }
79973d94b00SCristian Dumitrescu
80073d94b00SCristian Dumitrescu buffer[0] = 0;
80173d94b00SCristian Dumitrescu for (i = 0; i < n_tokens_args; i++) {
80273d94b00SCristian Dumitrescu if (i)
80373d94b00SCristian Dumitrescu strcat(buffer, " ");
80473d94b00SCristian Dumitrescu
80573d94b00SCristian Dumitrescu strcat(buffer, tokens[3 + i]);
80673d94b00SCristian Dumitrescu }
80773d94b00SCristian Dumitrescu
80873d94b00SCristian Dumitrescu s->params.default_action_args = strdup(buffer);
80973d94b00SCristian Dumitrescu if (!s->params.default_action_args) {
81073d94b00SCristian Dumitrescu status = -ENOMEM;
81173d94b00SCristian Dumitrescu goto error;
81273d94b00SCristian Dumitrescu }
81373d94b00SCristian Dumitrescu } else {
81473d94b00SCristian Dumitrescu if (((n_tokens != 4) && (n_tokens != 5)) ||
81573d94b00SCristian Dumitrescu ((n_tokens == 5) && (strcmp(tokens[4], "const")))) {
81673d94b00SCristian Dumitrescu status = -EINVAL;
81773d94b00SCristian Dumitrescu goto error;
81873d94b00SCristian Dumitrescu }
81973d94b00SCristian Dumitrescu }
82073d94b00SCristian Dumitrescu
82173d94b00SCristian Dumitrescu if (!strcmp(tokens[n_tokens - 1], "const"))
82273d94b00SCristian Dumitrescu s->params.default_action_is_const = 1;
82373d94b00SCristian Dumitrescu
82473d94b00SCristian Dumitrescu return 0;
82573d94b00SCristian Dumitrescu
82673d94b00SCristian Dumitrescu error:
82773d94b00SCristian Dumitrescu if (err_line)
82873d94b00SCristian Dumitrescu *err_line = n_lines;
82973d94b00SCristian Dumitrescu
83073d94b00SCristian Dumitrescu if (err_msg)
83173d94b00SCristian Dumitrescu switch (status) {
83273d94b00SCristian Dumitrescu case -ENOMEM:
83373d94b00SCristian Dumitrescu *err_msg = "Memory allocation failed.";
83473d94b00SCristian Dumitrescu break;
83573d94b00SCristian Dumitrescu
83673d94b00SCristian Dumitrescu default:
83773d94b00SCristian Dumitrescu if (duplicate)
83873d94b00SCristian Dumitrescu *err_msg = "Duplicate default_action statement.";
83973d94b00SCristian Dumitrescu
84073d94b00SCristian Dumitrescu *err_msg = "Invalid default_action statement.";
84173d94b00SCristian Dumitrescu }
84273d94b00SCristian Dumitrescu
84373d94b00SCristian Dumitrescu return status;
84473d94b00SCristian Dumitrescu }
84573d94b00SCristian Dumitrescu
84673d94b00SCristian Dumitrescu static int
table_statement_parse(struct table_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)84799a2dd95SBruce Richardson table_statement_parse(struct table_spec *s,
84899a2dd95SBruce Richardson uint32_t *block_mask,
84999a2dd95SBruce Richardson char **tokens,
85099a2dd95SBruce Richardson uint32_t n_tokens,
85199a2dd95SBruce Richardson uint32_t n_lines,
85299a2dd95SBruce Richardson uint32_t *err_line,
85399a2dd95SBruce Richardson const char **err_msg)
85499a2dd95SBruce Richardson {
85599a2dd95SBruce Richardson /* Check format. */
85699a2dd95SBruce Richardson if ((n_tokens != 3) || strcmp(tokens[2], "{")) {
85799a2dd95SBruce Richardson if (err_line)
85899a2dd95SBruce Richardson *err_line = n_lines;
85999a2dd95SBruce Richardson if (err_msg)
86099a2dd95SBruce Richardson *err_msg = "Invalid table statement.";
86199a2dd95SBruce Richardson return -EINVAL;
86299a2dd95SBruce Richardson }
86399a2dd95SBruce Richardson
86499a2dd95SBruce Richardson /* spec. */
86599a2dd95SBruce Richardson s->name = strdup(tokens[1]);
86699a2dd95SBruce Richardson if (!s->name) {
86799a2dd95SBruce Richardson if (err_line)
86899a2dd95SBruce Richardson *err_line = n_lines;
86999a2dd95SBruce Richardson if (err_msg)
87099a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
87199a2dd95SBruce Richardson return -ENOMEM;
87299a2dd95SBruce Richardson }
87399a2dd95SBruce Richardson
87499a2dd95SBruce Richardson /* block_mask. */
87599a2dd95SBruce Richardson *block_mask |= 1 << TABLE_BLOCK;
87699a2dd95SBruce Richardson
87799a2dd95SBruce Richardson return 0;
87899a2dd95SBruce Richardson }
87999a2dd95SBruce Richardson
88099a2dd95SBruce Richardson static int
table_block_parse(struct table_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)88199a2dd95SBruce Richardson table_block_parse(struct table_spec *s,
88299a2dd95SBruce Richardson uint32_t *block_mask,
88399a2dd95SBruce Richardson char **tokens,
88499a2dd95SBruce Richardson uint32_t n_tokens,
88599a2dd95SBruce Richardson uint32_t n_lines,
88699a2dd95SBruce Richardson uint32_t *err_line,
88799a2dd95SBruce Richardson const char **err_msg)
88899a2dd95SBruce Richardson {
88999a2dd95SBruce Richardson if (*block_mask & (1 << TABLE_KEY_BLOCK))
89099a2dd95SBruce Richardson return table_key_block_parse(s,
89199a2dd95SBruce Richardson block_mask,
89299a2dd95SBruce Richardson tokens,
89399a2dd95SBruce Richardson n_tokens,
89499a2dd95SBruce Richardson n_lines,
89599a2dd95SBruce Richardson err_line,
89699a2dd95SBruce Richardson err_msg);
89799a2dd95SBruce Richardson
89899a2dd95SBruce Richardson if (*block_mask & (1 << TABLE_ACTIONS_BLOCK))
89999a2dd95SBruce Richardson return table_actions_block_parse(s,
90099a2dd95SBruce Richardson block_mask,
90199a2dd95SBruce Richardson tokens,
90299a2dd95SBruce Richardson n_tokens,
90399a2dd95SBruce Richardson n_lines,
90499a2dd95SBruce Richardson err_line,
90599a2dd95SBruce Richardson err_msg);
90699a2dd95SBruce Richardson
90799a2dd95SBruce Richardson /* Handle end of block. */
90899a2dd95SBruce Richardson if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
90999a2dd95SBruce Richardson *block_mask &= ~(1 << TABLE_BLOCK);
91099a2dd95SBruce Richardson return 0;
91199a2dd95SBruce Richardson }
91299a2dd95SBruce Richardson
91399a2dd95SBruce Richardson if (!strcmp(tokens[0], "key"))
91499a2dd95SBruce Richardson return table_key_statement_parse(block_mask,
91599a2dd95SBruce Richardson tokens,
91699a2dd95SBruce Richardson n_tokens,
91799a2dd95SBruce Richardson n_lines,
91899a2dd95SBruce Richardson err_line,
91999a2dd95SBruce Richardson err_msg);
92099a2dd95SBruce Richardson
92199a2dd95SBruce Richardson if (!strcmp(tokens[0], "actions"))
92299a2dd95SBruce Richardson return table_actions_statement_parse(block_mask,
92399a2dd95SBruce Richardson tokens,
92499a2dd95SBruce Richardson n_tokens,
92599a2dd95SBruce Richardson n_lines,
92699a2dd95SBruce Richardson err_line,
92799a2dd95SBruce Richardson err_msg);
92899a2dd95SBruce Richardson
92973d94b00SCristian Dumitrescu if (!strcmp(tokens[0], "default_action"))
93073d94b00SCristian Dumitrescu return table_default_action_statement_parse(s,
93173d94b00SCristian Dumitrescu tokens,
93273d94b00SCristian Dumitrescu n_tokens,
93373d94b00SCristian Dumitrescu n_lines,
93473d94b00SCristian Dumitrescu err_line,
93573d94b00SCristian Dumitrescu err_msg);
93699a2dd95SBruce Richardson
9379560a329SCristian Dumitrescu if (!strcmp(tokens[0], "hash")) {
9389560a329SCristian Dumitrescu if (n_tokens != 2) {
9399560a329SCristian Dumitrescu if (err_line)
9409560a329SCristian Dumitrescu *err_line = n_lines;
9419560a329SCristian Dumitrescu if (err_msg)
9429560a329SCristian Dumitrescu *err_msg = "Invalid hash statement.";
9439560a329SCristian Dumitrescu return -EINVAL;
9449560a329SCristian Dumitrescu }
9459560a329SCristian Dumitrescu
9469560a329SCristian Dumitrescu if (s->params.hash_func_name) {
9479560a329SCristian Dumitrescu if (err_line)
9489560a329SCristian Dumitrescu *err_line = n_lines;
9499560a329SCristian Dumitrescu if (err_msg)
9509560a329SCristian Dumitrescu *err_msg = "Duplicate hash statement.";
9519560a329SCristian Dumitrescu return -EINVAL;
9529560a329SCristian Dumitrescu }
9539560a329SCristian Dumitrescu
9549560a329SCristian Dumitrescu s->params.hash_func_name = strdup(tokens[1]);
9559560a329SCristian Dumitrescu if (!s->params.hash_func_name) {
9569560a329SCristian Dumitrescu if (err_line)
9579560a329SCristian Dumitrescu *err_line = n_lines;
9589560a329SCristian Dumitrescu if (err_msg)
9599560a329SCristian Dumitrescu *err_msg = "Memory allocation failed.";
9609560a329SCristian Dumitrescu return -ENOMEM;
9619560a329SCristian Dumitrescu }
9629560a329SCristian Dumitrescu
9639560a329SCristian Dumitrescu return 0;
9649560a329SCristian Dumitrescu }
9659560a329SCristian Dumitrescu
96699a2dd95SBruce Richardson if (!strcmp(tokens[0], "instanceof")) {
96799a2dd95SBruce Richardson if (n_tokens != 2) {
96899a2dd95SBruce Richardson if (err_line)
96999a2dd95SBruce Richardson *err_line = n_lines;
97099a2dd95SBruce Richardson if (err_msg)
97199a2dd95SBruce Richardson *err_msg = "Invalid instanceof statement.";
97299a2dd95SBruce Richardson return -EINVAL;
97399a2dd95SBruce Richardson }
97499a2dd95SBruce Richardson
97599a2dd95SBruce Richardson if (s->recommended_table_type_name) {
97699a2dd95SBruce Richardson if (err_line)
97799a2dd95SBruce Richardson *err_line = n_lines;
97899a2dd95SBruce Richardson if (err_msg)
97999a2dd95SBruce Richardson *err_msg = "Duplicate instanceof statement.";
98099a2dd95SBruce Richardson return -EINVAL;
98199a2dd95SBruce Richardson }
98299a2dd95SBruce Richardson
98399a2dd95SBruce Richardson s->recommended_table_type_name = strdup(tokens[1]);
98499a2dd95SBruce Richardson if (!s->recommended_table_type_name) {
98599a2dd95SBruce Richardson if (err_line)
98699a2dd95SBruce Richardson *err_line = n_lines;
98799a2dd95SBruce Richardson if (err_msg)
98899a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
98999a2dd95SBruce Richardson return -ENOMEM;
99099a2dd95SBruce Richardson }
99199a2dd95SBruce Richardson
99299a2dd95SBruce Richardson return 0;
99399a2dd95SBruce Richardson }
99499a2dd95SBruce Richardson
99599a2dd95SBruce Richardson if (!strcmp(tokens[0], "pragma")) {
99699a2dd95SBruce Richardson if (n_tokens != 2) {
99799a2dd95SBruce Richardson if (err_line)
99899a2dd95SBruce Richardson *err_line = n_lines;
99999a2dd95SBruce Richardson if (err_msg)
100099a2dd95SBruce Richardson *err_msg = "Invalid pragma statement.";
100199a2dd95SBruce Richardson return -EINVAL;
100299a2dd95SBruce Richardson }
100399a2dd95SBruce Richardson
100499a2dd95SBruce Richardson if (s->args) {
100599a2dd95SBruce Richardson if (err_line)
100699a2dd95SBruce Richardson *err_line = n_lines;
100799a2dd95SBruce Richardson if (err_msg)
100899a2dd95SBruce Richardson *err_msg = "Duplicate pragma statement.";
100999a2dd95SBruce Richardson return -EINVAL;
101099a2dd95SBruce Richardson }
101199a2dd95SBruce Richardson
101299a2dd95SBruce Richardson s->args = strdup(tokens[1]);
101399a2dd95SBruce Richardson if (!s->args) {
101499a2dd95SBruce Richardson if (err_line)
101599a2dd95SBruce Richardson *err_line = n_lines;
101699a2dd95SBruce Richardson if (err_msg)
101799a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
101899a2dd95SBruce Richardson return -ENOMEM;
101999a2dd95SBruce Richardson }
102099a2dd95SBruce Richardson
102199a2dd95SBruce Richardson return 0;
102299a2dd95SBruce Richardson }
102399a2dd95SBruce Richardson
102499a2dd95SBruce Richardson if (!strcmp(tokens[0], "size")) {
102599a2dd95SBruce Richardson char *p = tokens[1];
102699a2dd95SBruce Richardson
102799a2dd95SBruce Richardson if (n_tokens != 2) {
102899a2dd95SBruce Richardson if (err_line)
102999a2dd95SBruce Richardson *err_line = n_lines;
103099a2dd95SBruce Richardson if (err_msg)
103199a2dd95SBruce Richardson *err_msg = "Invalid pragma statement.";
103299a2dd95SBruce Richardson return -EINVAL;
103399a2dd95SBruce Richardson }
103499a2dd95SBruce Richardson
103599a2dd95SBruce Richardson s->size = strtoul(p, &p, 0);
103699a2dd95SBruce Richardson if (p[0]) {
103799a2dd95SBruce Richardson if (err_line)
103899a2dd95SBruce Richardson *err_line = n_lines;
103999a2dd95SBruce Richardson if (err_msg)
104099a2dd95SBruce Richardson *err_msg = "Invalid size argument.";
104199a2dd95SBruce Richardson return -EINVAL;
104299a2dd95SBruce Richardson }
104399a2dd95SBruce Richardson
104499a2dd95SBruce Richardson return 0;
104599a2dd95SBruce Richardson }
104699a2dd95SBruce Richardson
104799a2dd95SBruce Richardson /* Anything else. */
104899a2dd95SBruce Richardson if (err_line)
104999a2dd95SBruce Richardson *err_line = n_lines;
105099a2dd95SBruce Richardson if (err_msg)
105199a2dd95SBruce Richardson *err_msg = "Invalid statement.";
105299a2dd95SBruce Richardson return -EINVAL;
105399a2dd95SBruce Richardson }
105499a2dd95SBruce Richardson
105599a2dd95SBruce Richardson /*
1056cdaa937dSCristian Dumitrescu * selector.
1057cdaa937dSCristian Dumitrescu */
1058cdaa937dSCristian Dumitrescu static void
selector_spec_free(struct selector_spec * s)1059cdaa937dSCristian Dumitrescu selector_spec_free(struct selector_spec *s)
1060cdaa937dSCristian Dumitrescu {
1061cdaa937dSCristian Dumitrescu uintptr_t field_name;
1062cdaa937dSCristian Dumitrescu uint32_t i;
1063cdaa937dSCristian Dumitrescu
1064cdaa937dSCristian Dumitrescu if (!s)
1065cdaa937dSCristian Dumitrescu return;
1066cdaa937dSCristian Dumitrescu
1067cdaa937dSCristian Dumitrescu /* name. */
1068cdaa937dSCristian Dumitrescu free(s->name);
1069cdaa937dSCristian Dumitrescu s->name = NULL;
1070cdaa937dSCristian Dumitrescu
1071cdaa937dSCristian Dumitrescu /* params->group_id_field_name. */
1072cdaa937dSCristian Dumitrescu field_name = (uintptr_t)s->params.group_id_field_name;
1073cdaa937dSCristian Dumitrescu free((void *)field_name);
1074cdaa937dSCristian Dumitrescu s->params.group_id_field_name = NULL;
1075cdaa937dSCristian Dumitrescu
1076cdaa937dSCristian Dumitrescu /* params->selector_field_names. */
1077cdaa937dSCristian Dumitrescu for (i = 0; i < s->params.n_selector_fields; i++) {
1078cdaa937dSCristian Dumitrescu field_name = (uintptr_t)s->params.selector_field_names[i];
1079cdaa937dSCristian Dumitrescu
1080cdaa937dSCristian Dumitrescu free((void *)field_name);
1081cdaa937dSCristian Dumitrescu }
1082cdaa937dSCristian Dumitrescu
1083cdaa937dSCristian Dumitrescu free(s->params.selector_field_names);
1084cdaa937dSCristian Dumitrescu s->params.selector_field_names = NULL;
1085cdaa937dSCristian Dumitrescu
1086cdaa937dSCristian Dumitrescu s->params.n_selector_fields = 0;
1087cdaa937dSCristian Dumitrescu
1088cdaa937dSCristian Dumitrescu /* params->member_id_field_name. */
1089cdaa937dSCristian Dumitrescu field_name = (uintptr_t)s->params.member_id_field_name;
1090cdaa937dSCristian Dumitrescu free((void *)field_name);
1091cdaa937dSCristian Dumitrescu s->params.member_id_field_name = NULL;
1092cdaa937dSCristian Dumitrescu
1093cdaa937dSCristian Dumitrescu /* params->n_groups_max. */
1094cdaa937dSCristian Dumitrescu s->params.n_groups_max = 0;
1095cdaa937dSCristian Dumitrescu
1096cdaa937dSCristian Dumitrescu /* params->n_members_per_group_max. */
1097cdaa937dSCristian Dumitrescu s->params.n_members_per_group_max = 0;
1098cdaa937dSCristian Dumitrescu }
1099cdaa937dSCristian Dumitrescu
1100cdaa937dSCristian Dumitrescu static int
selector_statement_parse(struct selector_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)1101cdaa937dSCristian Dumitrescu selector_statement_parse(struct selector_spec *s,
1102cdaa937dSCristian Dumitrescu uint32_t *block_mask,
1103cdaa937dSCristian Dumitrescu char **tokens,
1104cdaa937dSCristian Dumitrescu uint32_t n_tokens,
1105cdaa937dSCristian Dumitrescu uint32_t n_lines,
1106cdaa937dSCristian Dumitrescu uint32_t *err_line,
1107cdaa937dSCristian Dumitrescu const char **err_msg)
1108cdaa937dSCristian Dumitrescu {
1109cdaa937dSCristian Dumitrescu /* Check format. */
1110cdaa937dSCristian Dumitrescu if ((n_tokens != 3) || strcmp(tokens[2], "{")) {
1111cdaa937dSCristian Dumitrescu if (err_line)
1112cdaa937dSCristian Dumitrescu *err_line = n_lines;
1113cdaa937dSCristian Dumitrescu if (err_msg)
1114cdaa937dSCristian Dumitrescu *err_msg = "Invalid selector statement.";
1115cdaa937dSCristian Dumitrescu return -EINVAL;
1116cdaa937dSCristian Dumitrescu }
1117cdaa937dSCristian Dumitrescu
1118cdaa937dSCristian Dumitrescu /* spec. */
1119cdaa937dSCristian Dumitrescu s->name = strdup(tokens[1]);
1120cdaa937dSCristian Dumitrescu if (!s->name) {
1121cdaa937dSCristian Dumitrescu if (err_line)
1122cdaa937dSCristian Dumitrescu *err_line = n_lines;
1123cdaa937dSCristian Dumitrescu if (err_msg)
1124cdaa937dSCristian Dumitrescu *err_msg = "Memory allocation failed.";
1125cdaa937dSCristian Dumitrescu return -ENOMEM;
1126cdaa937dSCristian Dumitrescu }
1127cdaa937dSCristian Dumitrescu
1128cdaa937dSCristian Dumitrescu /* block_mask. */
1129cdaa937dSCristian Dumitrescu *block_mask |= 1 << SELECTOR_BLOCK;
1130cdaa937dSCristian Dumitrescu
1131cdaa937dSCristian Dumitrescu return 0;
1132cdaa937dSCristian Dumitrescu }
1133cdaa937dSCristian Dumitrescu
1134cdaa937dSCristian Dumitrescu static int
selector_selector_statement_parse(uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)1135cdaa937dSCristian Dumitrescu selector_selector_statement_parse(uint32_t *block_mask,
1136cdaa937dSCristian Dumitrescu char **tokens,
1137cdaa937dSCristian Dumitrescu uint32_t n_tokens,
1138cdaa937dSCristian Dumitrescu uint32_t n_lines,
1139cdaa937dSCristian Dumitrescu uint32_t *err_line,
1140cdaa937dSCristian Dumitrescu const char **err_msg)
1141cdaa937dSCristian Dumitrescu {
1142cdaa937dSCristian Dumitrescu /* Check format. */
1143cdaa937dSCristian Dumitrescu if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
1144cdaa937dSCristian Dumitrescu if (err_line)
1145cdaa937dSCristian Dumitrescu *err_line = n_lines;
1146cdaa937dSCristian Dumitrescu if (err_msg)
1147cdaa937dSCristian Dumitrescu *err_msg = "Invalid selector statement.";
1148cdaa937dSCristian Dumitrescu return -EINVAL;
1149cdaa937dSCristian Dumitrescu }
1150cdaa937dSCristian Dumitrescu
1151cdaa937dSCristian Dumitrescu /* block_mask. */
1152cdaa937dSCristian Dumitrescu *block_mask |= 1 << SELECTOR_SELECTOR_BLOCK;
1153cdaa937dSCristian Dumitrescu
1154cdaa937dSCristian Dumitrescu return 0;
1155cdaa937dSCristian Dumitrescu }
1156cdaa937dSCristian Dumitrescu
1157cdaa937dSCristian Dumitrescu static int
selector_selector_block_parse(struct selector_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)1158cdaa937dSCristian Dumitrescu selector_selector_block_parse(struct selector_spec *s,
1159cdaa937dSCristian Dumitrescu uint32_t *block_mask,
1160cdaa937dSCristian Dumitrescu char **tokens,
1161cdaa937dSCristian Dumitrescu uint32_t n_tokens,
1162cdaa937dSCristian Dumitrescu uint32_t n_lines,
1163cdaa937dSCristian Dumitrescu uint32_t *err_line,
1164cdaa937dSCristian Dumitrescu const char **err_msg)
1165cdaa937dSCristian Dumitrescu {
1166cdaa937dSCristian Dumitrescu const char **new_fields;
1167cdaa937dSCristian Dumitrescu char *name;
1168cdaa937dSCristian Dumitrescu
1169cdaa937dSCristian Dumitrescu /* Handle end of block. */
1170cdaa937dSCristian Dumitrescu if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
1171cdaa937dSCristian Dumitrescu *block_mask &= ~(1 << SELECTOR_SELECTOR_BLOCK);
1172cdaa937dSCristian Dumitrescu return 0;
1173cdaa937dSCristian Dumitrescu }
1174cdaa937dSCristian Dumitrescu
1175cdaa937dSCristian Dumitrescu /* Check input arguments. */
1176cdaa937dSCristian Dumitrescu if (n_tokens != 1) {
1177cdaa937dSCristian Dumitrescu if (err_line)
1178cdaa937dSCristian Dumitrescu *err_line = n_lines;
1179cdaa937dSCristian Dumitrescu if (err_msg)
1180cdaa937dSCristian Dumitrescu *err_msg = "Invalid selector field statement.";
1181cdaa937dSCristian Dumitrescu return -EINVAL;
1182cdaa937dSCristian Dumitrescu }
1183cdaa937dSCristian Dumitrescu
1184cdaa937dSCristian Dumitrescu name = strdup(tokens[0]);
1185cdaa937dSCristian Dumitrescu if (!name) {
1186cdaa937dSCristian Dumitrescu if (err_line)
1187cdaa937dSCristian Dumitrescu *err_line = n_lines;
1188cdaa937dSCristian Dumitrescu if (err_msg)
1189cdaa937dSCristian Dumitrescu *err_msg = "Memory allocation failed.";
1190cdaa937dSCristian Dumitrescu return -ENOMEM;
1191cdaa937dSCristian Dumitrescu }
1192cdaa937dSCristian Dumitrescu
1193cdaa937dSCristian Dumitrescu new_fields = realloc(s->params.selector_field_names,
1194cdaa937dSCristian Dumitrescu (s->params.n_selector_fields + 1) * sizeof(char *));
1195cdaa937dSCristian Dumitrescu if (!new_fields) {
1196cdaa937dSCristian Dumitrescu free(name);
1197cdaa937dSCristian Dumitrescu
1198cdaa937dSCristian Dumitrescu if (err_line)
1199cdaa937dSCristian Dumitrescu *err_line = n_lines;
1200cdaa937dSCristian Dumitrescu if (err_msg)
1201cdaa937dSCristian Dumitrescu *err_msg = "Memory allocation failed.";
1202cdaa937dSCristian Dumitrescu return -ENOMEM;
1203cdaa937dSCristian Dumitrescu }
1204cdaa937dSCristian Dumitrescu
1205cdaa937dSCristian Dumitrescu s->params.selector_field_names = new_fields;
1206cdaa937dSCristian Dumitrescu s->params.selector_field_names[s->params.n_selector_fields] = name;
1207cdaa937dSCristian Dumitrescu s->params.n_selector_fields++;
1208cdaa937dSCristian Dumitrescu
1209cdaa937dSCristian Dumitrescu return 0;
1210cdaa937dSCristian Dumitrescu }
1211cdaa937dSCristian Dumitrescu
1212cdaa937dSCristian Dumitrescu static int
selector_block_parse(struct selector_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)1213cdaa937dSCristian Dumitrescu selector_block_parse(struct selector_spec *s,
1214cdaa937dSCristian Dumitrescu uint32_t *block_mask,
1215cdaa937dSCristian Dumitrescu char **tokens,
1216cdaa937dSCristian Dumitrescu uint32_t n_tokens,
1217cdaa937dSCristian Dumitrescu uint32_t n_lines,
1218cdaa937dSCristian Dumitrescu uint32_t *err_line,
1219cdaa937dSCristian Dumitrescu const char **err_msg)
1220cdaa937dSCristian Dumitrescu {
1221cdaa937dSCristian Dumitrescu if (*block_mask & (1 << SELECTOR_SELECTOR_BLOCK))
1222cdaa937dSCristian Dumitrescu return selector_selector_block_parse(s,
1223cdaa937dSCristian Dumitrescu block_mask,
1224cdaa937dSCristian Dumitrescu tokens,
1225cdaa937dSCristian Dumitrescu n_tokens,
1226cdaa937dSCristian Dumitrescu n_lines,
1227cdaa937dSCristian Dumitrescu err_line,
1228cdaa937dSCristian Dumitrescu err_msg);
1229cdaa937dSCristian Dumitrescu
1230cdaa937dSCristian Dumitrescu /* Handle end of block. */
1231cdaa937dSCristian Dumitrescu if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
1232cdaa937dSCristian Dumitrescu *block_mask &= ~(1 << SELECTOR_BLOCK);
1233cdaa937dSCristian Dumitrescu return 0;
1234cdaa937dSCristian Dumitrescu }
1235cdaa937dSCristian Dumitrescu
1236cdaa937dSCristian Dumitrescu if (!strcmp(tokens[0], "group_id")) {
1237cdaa937dSCristian Dumitrescu if (n_tokens != 2) {
1238cdaa937dSCristian Dumitrescu if (err_line)
1239cdaa937dSCristian Dumitrescu *err_line = n_lines;
1240cdaa937dSCristian Dumitrescu if (err_msg)
1241cdaa937dSCristian Dumitrescu *err_msg = "Invalid group_id statement.";
1242cdaa937dSCristian Dumitrescu return -EINVAL;
1243cdaa937dSCristian Dumitrescu }
1244cdaa937dSCristian Dumitrescu
1245cdaa937dSCristian Dumitrescu s->params.group_id_field_name = strdup(tokens[1]);
1246cdaa937dSCristian Dumitrescu if (!s->params.group_id_field_name) {
1247cdaa937dSCristian Dumitrescu if (err_line)
1248cdaa937dSCristian Dumitrescu *err_line = n_lines;
1249cdaa937dSCristian Dumitrescu if (err_msg)
1250cdaa937dSCristian Dumitrescu *err_msg = "Memory allocation failed.";
1251cdaa937dSCristian Dumitrescu return -ENOMEM;
1252cdaa937dSCristian Dumitrescu }
1253cdaa937dSCristian Dumitrescu
1254cdaa937dSCristian Dumitrescu return 0;
1255cdaa937dSCristian Dumitrescu }
1256cdaa937dSCristian Dumitrescu
1257cdaa937dSCristian Dumitrescu if (!strcmp(tokens[0], "selector"))
1258cdaa937dSCristian Dumitrescu return selector_selector_statement_parse(block_mask,
1259cdaa937dSCristian Dumitrescu tokens,
1260cdaa937dSCristian Dumitrescu n_tokens,
1261cdaa937dSCristian Dumitrescu n_lines,
1262cdaa937dSCristian Dumitrescu err_line,
1263cdaa937dSCristian Dumitrescu err_msg);
1264cdaa937dSCristian Dumitrescu
1265cdaa937dSCristian Dumitrescu if (!strcmp(tokens[0], "member_id")) {
1266cdaa937dSCristian Dumitrescu if (n_tokens != 2) {
1267cdaa937dSCristian Dumitrescu if (err_line)
1268cdaa937dSCristian Dumitrescu *err_line = n_lines;
1269cdaa937dSCristian Dumitrescu if (err_msg)
1270cdaa937dSCristian Dumitrescu *err_msg = "Invalid member_id statement.";
1271cdaa937dSCristian Dumitrescu return -EINVAL;
1272cdaa937dSCristian Dumitrescu }
1273cdaa937dSCristian Dumitrescu
1274cdaa937dSCristian Dumitrescu s->params.member_id_field_name = strdup(tokens[1]);
1275cdaa937dSCristian Dumitrescu if (!s->params.member_id_field_name) {
1276cdaa937dSCristian Dumitrescu if (err_line)
1277cdaa937dSCristian Dumitrescu *err_line = n_lines;
1278cdaa937dSCristian Dumitrescu if (err_msg)
1279cdaa937dSCristian Dumitrescu *err_msg = "Memory allocation failed.";
1280cdaa937dSCristian Dumitrescu return -ENOMEM;
1281cdaa937dSCristian Dumitrescu }
1282cdaa937dSCristian Dumitrescu
1283cdaa937dSCristian Dumitrescu return 0;
1284cdaa937dSCristian Dumitrescu }
1285cdaa937dSCristian Dumitrescu
1286cdaa937dSCristian Dumitrescu if (!strcmp(tokens[0], "n_groups_max")) {
1287cdaa937dSCristian Dumitrescu char *p = tokens[1];
1288cdaa937dSCristian Dumitrescu
1289cdaa937dSCristian Dumitrescu if (n_tokens != 2) {
1290cdaa937dSCristian Dumitrescu if (err_line)
1291cdaa937dSCristian Dumitrescu *err_line = n_lines;
1292cdaa937dSCristian Dumitrescu if (err_msg)
1293cdaa937dSCristian Dumitrescu *err_msg = "Invalid n_groups statement.";
1294cdaa937dSCristian Dumitrescu return -EINVAL;
1295cdaa937dSCristian Dumitrescu }
1296cdaa937dSCristian Dumitrescu
1297cdaa937dSCristian Dumitrescu s->params.n_groups_max = strtoul(p, &p, 0);
1298cdaa937dSCristian Dumitrescu if (p[0]) {
1299cdaa937dSCristian Dumitrescu if (err_line)
1300cdaa937dSCristian Dumitrescu *err_line = n_lines;
1301cdaa937dSCristian Dumitrescu if (err_msg)
1302cdaa937dSCristian Dumitrescu *err_msg = "Invalid n_groups argument.";
1303cdaa937dSCristian Dumitrescu return -EINVAL;
1304cdaa937dSCristian Dumitrescu }
1305cdaa937dSCristian Dumitrescu
1306cdaa937dSCristian Dumitrescu return 0;
1307cdaa937dSCristian Dumitrescu }
1308cdaa937dSCristian Dumitrescu
1309cdaa937dSCristian Dumitrescu if (!strcmp(tokens[0], "n_members_per_group_max")) {
1310cdaa937dSCristian Dumitrescu char *p = tokens[1];
1311cdaa937dSCristian Dumitrescu
1312cdaa937dSCristian Dumitrescu if (n_tokens != 2) {
1313cdaa937dSCristian Dumitrescu if (err_line)
1314cdaa937dSCristian Dumitrescu *err_line = n_lines;
1315cdaa937dSCristian Dumitrescu if (err_msg)
1316cdaa937dSCristian Dumitrescu *err_msg = "Invalid n_members_per_group statement.";
1317cdaa937dSCristian Dumitrescu return -EINVAL;
1318cdaa937dSCristian Dumitrescu }
1319cdaa937dSCristian Dumitrescu
1320cdaa937dSCristian Dumitrescu s->params.n_members_per_group_max = strtoul(p, &p, 0);
1321cdaa937dSCristian Dumitrescu if (p[0]) {
1322cdaa937dSCristian Dumitrescu if (err_line)
1323cdaa937dSCristian Dumitrescu *err_line = n_lines;
1324cdaa937dSCristian Dumitrescu if (err_msg)
1325cdaa937dSCristian Dumitrescu *err_msg = "Invalid n_members_per_group argument.";
1326cdaa937dSCristian Dumitrescu return -EINVAL;
1327cdaa937dSCristian Dumitrescu }
1328cdaa937dSCristian Dumitrescu
1329cdaa937dSCristian Dumitrescu return 0;
1330cdaa937dSCristian Dumitrescu }
1331cdaa937dSCristian Dumitrescu
1332cdaa937dSCristian Dumitrescu /* Anything else. */
1333cdaa937dSCristian Dumitrescu if (err_line)
1334cdaa937dSCristian Dumitrescu *err_line = n_lines;
1335cdaa937dSCristian Dumitrescu if (err_msg)
1336cdaa937dSCristian Dumitrescu *err_msg = "Invalid statement.";
1337cdaa937dSCristian Dumitrescu return -EINVAL;
1338cdaa937dSCristian Dumitrescu }
1339cdaa937dSCristian Dumitrescu
1340cdaa937dSCristian Dumitrescu /*
13414f59d372SCristian Dumitrescu * learner.
13424f59d372SCristian Dumitrescu */
13434f59d372SCristian Dumitrescu static void
learner_spec_free(struct learner_spec * s)13444f59d372SCristian Dumitrescu learner_spec_free(struct learner_spec *s)
13454f59d372SCristian Dumitrescu {
1346fa7723b5SCristian Dumitrescu uintptr_t default_action_name, default_action_args, hash_func_name;
13474f59d372SCristian Dumitrescu uint32_t i;
13484f59d372SCristian Dumitrescu
13494f59d372SCristian Dumitrescu if (!s)
13504f59d372SCristian Dumitrescu return;
13514f59d372SCristian Dumitrescu
13524f59d372SCristian Dumitrescu free(s->name);
13534f59d372SCristian Dumitrescu s->name = NULL;
13544f59d372SCristian Dumitrescu
13554f59d372SCristian Dumitrescu for (i = 0; i < s->params.n_fields; i++) {
13564f59d372SCristian Dumitrescu uintptr_t name = (uintptr_t)s->params.field_names[i];
13574f59d372SCristian Dumitrescu
13584f59d372SCristian Dumitrescu free((void *)name);
13594f59d372SCristian Dumitrescu }
13604f59d372SCristian Dumitrescu
13614f59d372SCristian Dumitrescu free(s->params.field_names);
13624f59d372SCristian Dumitrescu s->params.field_names = NULL;
13634f59d372SCristian Dumitrescu
13644f59d372SCristian Dumitrescu s->params.n_fields = 0;
13654f59d372SCristian Dumitrescu
13664f59d372SCristian Dumitrescu for (i = 0; i < s->params.n_actions; i++) {
13674f59d372SCristian Dumitrescu uintptr_t name = (uintptr_t)s->params.action_names[i];
13684f59d372SCristian Dumitrescu
13694f59d372SCristian Dumitrescu free((void *)name);
13704f59d372SCristian Dumitrescu }
13714f59d372SCristian Dumitrescu
13724f59d372SCristian Dumitrescu free(s->params.action_names);
13734f59d372SCristian Dumitrescu s->params.action_names = NULL;
13744f59d372SCristian Dumitrescu
13754f59d372SCristian Dumitrescu s->params.n_actions = 0;
13764f59d372SCristian Dumitrescu
13774f59d372SCristian Dumitrescu default_action_name = (uintptr_t)s->params.default_action_name;
13784f59d372SCristian Dumitrescu free((void *)default_action_name);
13794f59d372SCristian Dumitrescu s->params.default_action_name = NULL;
13804f59d372SCristian Dumitrescu
138173d94b00SCristian Dumitrescu default_action_args = (uintptr_t)s->params.default_action_args;
138273d94b00SCristian Dumitrescu free((void *)default_action_args);
138373d94b00SCristian Dumitrescu s->params.default_action_args = NULL;
13844f59d372SCristian Dumitrescu
1385cd79e020SYogesh Jangra free(s->params.action_is_for_table_entries);
1386cd79e020SYogesh Jangra s->params.action_is_for_table_entries = NULL;
1387cd79e020SYogesh Jangra
1388cd79e020SYogesh Jangra free(s->params.action_is_for_default_entry);
1389cd79e020SYogesh Jangra s->params.action_is_for_default_entry = NULL;
1390cd79e020SYogesh Jangra
13914f59d372SCristian Dumitrescu s->params.default_action_is_const = 0;
13924f59d372SCristian Dumitrescu
1393fa7723b5SCristian Dumitrescu hash_func_name = (uintptr_t)s->params.hash_func_name;
1394fa7723b5SCristian Dumitrescu free((void *)hash_func_name);
1395fa7723b5SCristian Dumitrescu s->params.hash_func_name = NULL;
1396fa7723b5SCristian Dumitrescu
13974f59d372SCristian Dumitrescu s->size = 0;
13984f59d372SCristian Dumitrescu
1399e2ecc535SCristian Dumitrescu free(s->timeout);
1400e2ecc535SCristian Dumitrescu s->timeout = NULL;
1401e2ecc535SCristian Dumitrescu
1402e2ecc535SCristian Dumitrescu s->n_timeouts = 0;
14034f59d372SCristian Dumitrescu }
14044f59d372SCristian Dumitrescu
14054f59d372SCristian Dumitrescu static int
learner_key_statement_parse(uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)14064f59d372SCristian Dumitrescu learner_key_statement_parse(uint32_t *block_mask,
14074f59d372SCristian Dumitrescu char **tokens,
14084f59d372SCristian Dumitrescu uint32_t n_tokens,
14094f59d372SCristian Dumitrescu uint32_t n_lines,
14104f59d372SCristian Dumitrescu uint32_t *err_line,
14114f59d372SCristian Dumitrescu const char **err_msg)
14124f59d372SCristian Dumitrescu {
14134f59d372SCristian Dumitrescu /* Check format. */
14144f59d372SCristian Dumitrescu if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
14154f59d372SCristian Dumitrescu if (err_line)
14164f59d372SCristian Dumitrescu *err_line = n_lines;
14174f59d372SCristian Dumitrescu if (err_msg)
14184f59d372SCristian Dumitrescu *err_msg = "Invalid key statement.";
14194f59d372SCristian Dumitrescu return -EINVAL;
14204f59d372SCristian Dumitrescu }
14214f59d372SCristian Dumitrescu
14224f59d372SCristian Dumitrescu /* block_mask. */
14234f59d372SCristian Dumitrescu *block_mask |= 1 << LEARNER_KEY_BLOCK;
14244f59d372SCristian Dumitrescu
14254f59d372SCristian Dumitrescu return 0;
14264f59d372SCristian Dumitrescu }
14274f59d372SCristian Dumitrescu
14284f59d372SCristian Dumitrescu static int
learner_key_block_parse(struct learner_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)14294f59d372SCristian Dumitrescu learner_key_block_parse(struct learner_spec *s,
14304f59d372SCristian Dumitrescu uint32_t *block_mask,
14314f59d372SCristian Dumitrescu char **tokens,
14324f59d372SCristian Dumitrescu uint32_t n_tokens,
14334f59d372SCristian Dumitrescu uint32_t n_lines,
14344f59d372SCristian Dumitrescu uint32_t *err_line,
14354f59d372SCristian Dumitrescu const char **err_msg)
14364f59d372SCristian Dumitrescu {
14374f59d372SCristian Dumitrescu const char **new_field_names = NULL;
14384f59d372SCristian Dumitrescu char *field_name = NULL;
14394f59d372SCristian Dumitrescu
14404f59d372SCristian Dumitrescu /* Handle end of block. */
14414f59d372SCristian Dumitrescu if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
14424f59d372SCristian Dumitrescu *block_mask &= ~(1 << LEARNER_KEY_BLOCK);
14434f59d372SCristian Dumitrescu return 0;
14444f59d372SCristian Dumitrescu }
14454f59d372SCristian Dumitrescu
14464f59d372SCristian Dumitrescu /* Check input arguments. */
14474f59d372SCristian Dumitrescu if (n_tokens != 1) {
14484f59d372SCristian Dumitrescu if (err_line)
14494f59d372SCristian Dumitrescu *err_line = n_lines;
14504f59d372SCristian Dumitrescu if (err_msg)
14514f59d372SCristian Dumitrescu *err_msg = "Invalid match field statement.";
14524f59d372SCristian Dumitrescu return -EINVAL;
14534f59d372SCristian Dumitrescu }
14544f59d372SCristian Dumitrescu
14554f59d372SCristian Dumitrescu field_name = strdup(tokens[0]);
14564f59d372SCristian Dumitrescu new_field_names = realloc(s->params.field_names, (s->params.n_fields + 1) * sizeof(char *));
14574f59d372SCristian Dumitrescu if (!field_name || !new_field_names) {
14584f59d372SCristian Dumitrescu free(field_name);
14594f59d372SCristian Dumitrescu free(new_field_names);
14604f59d372SCristian Dumitrescu
14614f59d372SCristian Dumitrescu if (err_line)
14624f59d372SCristian Dumitrescu *err_line = n_lines;
14634f59d372SCristian Dumitrescu if (err_msg)
14644f59d372SCristian Dumitrescu *err_msg = "Memory allocation failed.";
14654f59d372SCristian Dumitrescu return -ENOMEM;
14664f59d372SCristian Dumitrescu }
14674f59d372SCristian Dumitrescu
14684f59d372SCristian Dumitrescu s->params.field_names = new_field_names;
14694f59d372SCristian Dumitrescu s->params.field_names[s->params.n_fields] = field_name;
14704f59d372SCristian Dumitrescu s->params.n_fields++;
14714f59d372SCristian Dumitrescu
14724f59d372SCristian Dumitrescu return 0;
14734f59d372SCristian Dumitrescu }
14744f59d372SCristian Dumitrescu
14754f59d372SCristian Dumitrescu static int
learner_actions_statement_parse(uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)14764f59d372SCristian Dumitrescu learner_actions_statement_parse(uint32_t *block_mask,
14774f59d372SCristian Dumitrescu char **tokens,
14784f59d372SCristian Dumitrescu uint32_t n_tokens,
14794f59d372SCristian Dumitrescu uint32_t n_lines,
14804f59d372SCristian Dumitrescu uint32_t *err_line,
14814f59d372SCristian Dumitrescu const char **err_msg)
14824f59d372SCristian Dumitrescu {
14834f59d372SCristian Dumitrescu /* Check format. */
14844f59d372SCristian Dumitrescu if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
14854f59d372SCristian Dumitrescu if (err_line)
14864f59d372SCristian Dumitrescu *err_line = n_lines;
14874f59d372SCristian Dumitrescu if (err_msg)
14884f59d372SCristian Dumitrescu *err_msg = "Invalid actions statement.";
14894f59d372SCristian Dumitrescu return -EINVAL;
14904f59d372SCristian Dumitrescu }
14914f59d372SCristian Dumitrescu
14924f59d372SCristian Dumitrescu /* block_mask. */
14934f59d372SCristian Dumitrescu *block_mask |= 1 << LEARNER_ACTIONS_BLOCK;
14944f59d372SCristian Dumitrescu
14954f59d372SCristian Dumitrescu return 0;
14964f59d372SCristian Dumitrescu }
14974f59d372SCristian Dumitrescu
14984f59d372SCristian Dumitrescu static int
learner_actions_block_parse(struct learner_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)14994f59d372SCristian Dumitrescu learner_actions_block_parse(struct learner_spec *s,
15004f59d372SCristian Dumitrescu uint32_t *block_mask,
15014f59d372SCristian Dumitrescu char **tokens,
15024f59d372SCristian Dumitrescu uint32_t n_tokens,
15034f59d372SCristian Dumitrescu uint32_t n_lines,
15044f59d372SCristian Dumitrescu uint32_t *err_line,
15054f59d372SCristian Dumitrescu const char **err_msg)
15064f59d372SCristian Dumitrescu {
15074f59d372SCristian Dumitrescu const char **new_action_names = NULL;
1508cd79e020SYogesh Jangra int *new_action_is_for_table_entries = NULL, *new_action_is_for_default_entry = NULL;
1509cd79e020SYogesh Jangra char *name = NULL;
1510cd79e020SYogesh Jangra int action_is_for_table_entries = 1, action_is_for_default_entry = 1;
15114f59d372SCristian Dumitrescu
15124f59d372SCristian Dumitrescu /* Handle end of block. */
15134f59d372SCristian Dumitrescu if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
15144f59d372SCristian Dumitrescu *block_mask &= ~(1 << LEARNER_ACTIONS_BLOCK);
15154f59d372SCristian Dumitrescu return 0;
15164f59d372SCristian Dumitrescu }
15174f59d372SCristian Dumitrescu
15184f59d372SCristian Dumitrescu /* Check input arguments. */
1519cd79e020SYogesh Jangra if ((n_tokens > 2) ||
1520cd79e020SYogesh Jangra ((n_tokens == 2) && strcmp(tokens[1], "@tableonly") &&
1521cd79e020SYogesh Jangra strcmp(tokens[1], "@defaultonly"))) {
15224f59d372SCristian Dumitrescu if (err_line)
15234f59d372SCristian Dumitrescu *err_line = n_lines;
15244f59d372SCristian Dumitrescu if (err_msg)
15254f59d372SCristian Dumitrescu *err_msg = "Invalid action name statement.";
15264f59d372SCristian Dumitrescu return -EINVAL;
15274f59d372SCristian Dumitrescu }
15284f59d372SCristian Dumitrescu
1529cd79e020SYogesh Jangra name = strdup(tokens[0]);
1530cd79e020SYogesh Jangra
1531cd79e020SYogesh Jangra if (n_tokens == 2) {
1532cd79e020SYogesh Jangra if (!strcmp(tokens[1], "@tableonly"))
1533cd79e020SYogesh Jangra action_is_for_default_entry = 0;
1534cd79e020SYogesh Jangra
1535cd79e020SYogesh Jangra if (!strcmp(tokens[1], "@defaultonly"))
1536cd79e020SYogesh Jangra action_is_for_table_entries = 0;
1537cd79e020SYogesh Jangra }
15384f59d372SCristian Dumitrescu
15394f59d372SCristian Dumitrescu new_action_names = realloc(s->params.action_names,
15404f59d372SCristian Dumitrescu (s->params.n_actions + 1) * sizeof(char *));
1541cd79e020SYogesh Jangra new_action_is_for_table_entries = realloc(s->params.action_is_for_table_entries,
1542cd79e020SYogesh Jangra (s->params.n_actions + 1) * sizeof(int));
1543cd79e020SYogesh Jangra new_action_is_for_default_entry = realloc(s->params.action_is_for_default_entry,
1544cd79e020SYogesh Jangra (s->params.n_actions + 1) * sizeof(int));
15454f59d372SCristian Dumitrescu
1546cd79e020SYogesh Jangra if (!name ||
1547cd79e020SYogesh Jangra !new_action_names ||
1548cd79e020SYogesh Jangra !new_action_is_for_table_entries ||
1549cd79e020SYogesh Jangra !new_action_is_for_default_entry) {
1550cd79e020SYogesh Jangra free(name);
15514f59d372SCristian Dumitrescu free(new_action_names);
1552cd79e020SYogesh Jangra free(new_action_is_for_table_entries);
1553cd79e020SYogesh Jangra free(new_action_is_for_default_entry);
15544f59d372SCristian Dumitrescu
15554f59d372SCristian Dumitrescu if (err_line)
15564f59d372SCristian Dumitrescu *err_line = n_lines;
15574f59d372SCristian Dumitrescu if (err_msg)
15584f59d372SCristian Dumitrescu *err_msg = "Memory allocation failed.";
15594f59d372SCristian Dumitrescu return -ENOMEM;
15604f59d372SCristian Dumitrescu }
15614f59d372SCristian Dumitrescu
15624f59d372SCristian Dumitrescu s->params.action_names = new_action_names;
1563cd79e020SYogesh Jangra s->params.action_names[s->params.n_actions] = name;
1564cd79e020SYogesh Jangra
1565cd79e020SYogesh Jangra s->params.action_is_for_table_entries = new_action_is_for_table_entries;
1566cd79e020SYogesh Jangra s->params.action_is_for_table_entries[s->params.n_actions] = action_is_for_table_entries;
1567cd79e020SYogesh Jangra
1568cd79e020SYogesh Jangra s->params.action_is_for_default_entry = new_action_is_for_default_entry;
1569cd79e020SYogesh Jangra s->params.action_is_for_default_entry[s->params.n_actions] = action_is_for_default_entry;
1570cd79e020SYogesh Jangra
15714f59d372SCristian Dumitrescu s->params.n_actions++;
15724f59d372SCristian Dumitrescu
15734f59d372SCristian Dumitrescu return 0;
15744f59d372SCristian Dumitrescu }
15754f59d372SCristian Dumitrescu
15764f59d372SCristian Dumitrescu static int
learner_default_action_statement_parse(struct learner_spec * s,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)157773d94b00SCristian Dumitrescu learner_default_action_statement_parse(struct learner_spec *s,
157873d94b00SCristian Dumitrescu char **tokens,
157973d94b00SCristian Dumitrescu uint32_t n_tokens,
158073d94b00SCristian Dumitrescu uint32_t n_lines,
158173d94b00SCristian Dumitrescu uint32_t *err_line,
158273d94b00SCristian Dumitrescu const char **err_msg)
158373d94b00SCristian Dumitrescu {
158473d94b00SCristian Dumitrescu uint32_t i;
158573d94b00SCristian Dumitrescu int status = 0, duplicate = 0;
158673d94b00SCristian Dumitrescu
158773d94b00SCristian Dumitrescu /* Check format. */
158873d94b00SCristian Dumitrescu if ((n_tokens < 4) ||
158973d94b00SCristian Dumitrescu strcmp(tokens[2], "args")) {
159073d94b00SCristian Dumitrescu status = -EINVAL;
159173d94b00SCristian Dumitrescu goto error;
159273d94b00SCristian Dumitrescu }
159373d94b00SCristian Dumitrescu
159473d94b00SCristian Dumitrescu if (s->params.default_action_name) {
159573d94b00SCristian Dumitrescu duplicate = 1;
159673d94b00SCristian Dumitrescu status = -EINVAL;
159773d94b00SCristian Dumitrescu goto error;
159873d94b00SCristian Dumitrescu }
159973d94b00SCristian Dumitrescu
160073d94b00SCristian Dumitrescu s->params.default_action_name = strdup(tokens[1]);
160173d94b00SCristian Dumitrescu if (!s->params.default_action_name) {
160273d94b00SCristian Dumitrescu status = -ENOMEM;
160373d94b00SCristian Dumitrescu goto error;
160473d94b00SCristian Dumitrescu }
160573d94b00SCristian Dumitrescu
160673d94b00SCristian Dumitrescu if (strcmp(tokens[3], "none")) {
160773d94b00SCristian Dumitrescu char buffer[MAX_LINE_LENGTH];
160873d94b00SCristian Dumitrescu uint32_t n_tokens_args = n_tokens - 3;
160973d94b00SCristian Dumitrescu
161073d94b00SCristian Dumitrescu if (!strcmp(tokens[n_tokens - 1], "const"))
161173d94b00SCristian Dumitrescu n_tokens_args--;
161273d94b00SCristian Dumitrescu
161373d94b00SCristian Dumitrescu if (!n_tokens_args) {
161473d94b00SCristian Dumitrescu status = -EINVAL;
161573d94b00SCristian Dumitrescu goto error;
161673d94b00SCristian Dumitrescu }
161773d94b00SCristian Dumitrescu
161873d94b00SCristian Dumitrescu buffer[0] = 0;
161973d94b00SCristian Dumitrescu for (i = 0; i < n_tokens_args; i++) {
162073d94b00SCristian Dumitrescu if (i)
162173d94b00SCristian Dumitrescu strcat(buffer, " ");
162273d94b00SCristian Dumitrescu
162373d94b00SCristian Dumitrescu strcat(buffer, tokens[3 + i]);
162473d94b00SCristian Dumitrescu }
162573d94b00SCristian Dumitrescu
162673d94b00SCristian Dumitrescu s->params.default_action_args = strdup(buffer);
162773d94b00SCristian Dumitrescu if (!s->params.default_action_args) {
162873d94b00SCristian Dumitrescu status = -ENOMEM;
162973d94b00SCristian Dumitrescu goto error;
163073d94b00SCristian Dumitrescu }
163173d94b00SCristian Dumitrescu } else {
163273d94b00SCristian Dumitrescu if (((n_tokens != 4) && (n_tokens != 5)) ||
163373d94b00SCristian Dumitrescu ((n_tokens == 5) && (strcmp(tokens[4], "const")))) {
163473d94b00SCristian Dumitrescu status = -EINVAL;
163573d94b00SCristian Dumitrescu goto error;
163673d94b00SCristian Dumitrescu }
163773d94b00SCristian Dumitrescu }
163873d94b00SCristian Dumitrescu
163973d94b00SCristian Dumitrescu if (!strcmp(tokens[n_tokens - 1], "const"))
164073d94b00SCristian Dumitrescu s->params.default_action_is_const = 1;
164173d94b00SCristian Dumitrescu
164273d94b00SCristian Dumitrescu return 0;
164373d94b00SCristian Dumitrescu
164473d94b00SCristian Dumitrescu error:
164573d94b00SCristian Dumitrescu if (err_line)
164673d94b00SCristian Dumitrescu *err_line = n_lines;
164773d94b00SCristian Dumitrescu
164873d94b00SCristian Dumitrescu if (err_msg)
164973d94b00SCristian Dumitrescu switch (status) {
165073d94b00SCristian Dumitrescu case -ENOMEM:
165173d94b00SCristian Dumitrescu *err_msg = "Memory allocation failed.";
165273d94b00SCristian Dumitrescu break;
165373d94b00SCristian Dumitrescu
165473d94b00SCristian Dumitrescu default:
165573d94b00SCristian Dumitrescu if (duplicate)
165673d94b00SCristian Dumitrescu *err_msg = "Duplicate default_action statement.";
165773d94b00SCristian Dumitrescu
165873d94b00SCristian Dumitrescu *err_msg = "Invalid default_action statement.";
165973d94b00SCristian Dumitrescu }
166073d94b00SCristian Dumitrescu
166173d94b00SCristian Dumitrescu return status;
166273d94b00SCristian Dumitrescu }
166373d94b00SCristian Dumitrescu
166473d94b00SCristian Dumitrescu static int
learner_timeout_statement_parse(uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)1665e2ecc535SCristian Dumitrescu learner_timeout_statement_parse(uint32_t *block_mask,
1666e2ecc535SCristian Dumitrescu char **tokens,
1667e2ecc535SCristian Dumitrescu uint32_t n_tokens,
1668e2ecc535SCristian Dumitrescu uint32_t n_lines,
1669e2ecc535SCristian Dumitrescu uint32_t *err_line,
1670e2ecc535SCristian Dumitrescu const char **err_msg)
1671e2ecc535SCristian Dumitrescu {
1672e2ecc535SCristian Dumitrescu /* Check format. */
1673e2ecc535SCristian Dumitrescu if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
1674e2ecc535SCristian Dumitrescu if (err_line)
1675e2ecc535SCristian Dumitrescu *err_line = n_lines;
1676e2ecc535SCristian Dumitrescu if (err_msg)
1677e2ecc535SCristian Dumitrescu *err_msg = "Invalid timeout statement.";
1678e2ecc535SCristian Dumitrescu return -EINVAL;
1679e2ecc535SCristian Dumitrescu }
1680e2ecc535SCristian Dumitrescu
1681e2ecc535SCristian Dumitrescu /* block_mask. */
1682e2ecc535SCristian Dumitrescu *block_mask |= 1 << LEARNER_TIMEOUT_BLOCK;
1683e2ecc535SCristian Dumitrescu
1684e2ecc535SCristian Dumitrescu return 0;
1685e2ecc535SCristian Dumitrescu }
1686e2ecc535SCristian Dumitrescu
1687e2ecc535SCristian Dumitrescu static int
learner_timeout_block_parse(struct learner_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)1688e2ecc535SCristian Dumitrescu learner_timeout_block_parse(struct learner_spec *s,
1689e2ecc535SCristian Dumitrescu uint32_t *block_mask,
1690e2ecc535SCristian Dumitrescu char **tokens,
1691e2ecc535SCristian Dumitrescu uint32_t n_tokens,
1692e2ecc535SCristian Dumitrescu uint32_t n_lines,
1693e2ecc535SCristian Dumitrescu uint32_t *err_line,
1694e2ecc535SCristian Dumitrescu const char **err_msg)
1695e2ecc535SCristian Dumitrescu {
1696e2ecc535SCristian Dumitrescu uint32_t *new_timeout = NULL;
1697e2ecc535SCristian Dumitrescu char *str;
1698e2ecc535SCristian Dumitrescu uint32_t val;
1699e2ecc535SCristian Dumitrescu int status = 0;
1700e2ecc535SCristian Dumitrescu
1701e2ecc535SCristian Dumitrescu /* Handle end of block. */
1702e2ecc535SCristian Dumitrescu if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
1703e2ecc535SCristian Dumitrescu *block_mask &= ~(1 << LEARNER_TIMEOUT_BLOCK);
1704e2ecc535SCristian Dumitrescu return 0;
1705e2ecc535SCristian Dumitrescu }
1706e2ecc535SCristian Dumitrescu
1707e2ecc535SCristian Dumitrescu /* Check input arguments. */
1708e2ecc535SCristian Dumitrescu if (n_tokens != 1) {
1709e2ecc535SCristian Dumitrescu status = -EINVAL;
1710e2ecc535SCristian Dumitrescu goto error;
1711e2ecc535SCristian Dumitrescu }
1712e2ecc535SCristian Dumitrescu
1713e2ecc535SCristian Dumitrescu str = tokens[0];
1714e2ecc535SCristian Dumitrescu val = strtoul(str, &str, 0);
1715e2ecc535SCristian Dumitrescu if (str[0]) {
1716e2ecc535SCristian Dumitrescu status = -EINVAL;
1717e2ecc535SCristian Dumitrescu goto error;
1718e2ecc535SCristian Dumitrescu }
1719e2ecc535SCristian Dumitrescu
1720e2ecc535SCristian Dumitrescu new_timeout = realloc(s->timeout, (s->n_timeouts + 1) * sizeof(uint32_t));
1721e2ecc535SCristian Dumitrescu if (!new_timeout) {
1722e2ecc535SCristian Dumitrescu status = -ENOMEM;
1723e2ecc535SCristian Dumitrescu goto error;
1724e2ecc535SCristian Dumitrescu }
1725e2ecc535SCristian Dumitrescu
1726e2ecc535SCristian Dumitrescu s->timeout = new_timeout;
1727e2ecc535SCristian Dumitrescu s->timeout[s->n_timeouts] = val;
1728e2ecc535SCristian Dumitrescu s->n_timeouts++;
1729e2ecc535SCristian Dumitrescu
1730e2ecc535SCristian Dumitrescu return 0;
1731e2ecc535SCristian Dumitrescu
1732e2ecc535SCristian Dumitrescu error:
1733e2ecc535SCristian Dumitrescu free(new_timeout);
1734e2ecc535SCristian Dumitrescu
1735e2ecc535SCristian Dumitrescu if (err_line)
1736e2ecc535SCristian Dumitrescu *err_line = n_lines;
1737e2ecc535SCristian Dumitrescu
1738e2ecc535SCristian Dumitrescu if (err_msg)
1739e2ecc535SCristian Dumitrescu switch (status) {
1740e2ecc535SCristian Dumitrescu case -ENOMEM:
1741e2ecc535SCristian Dumitrescu *err_msg = "Memory allocation failed.";
1742e2ecc535SCristian Dumitrescu break;
1743e2ecc535SCristian Dumitrescu
1744e2ecc535SCristian Dumitrescu default:
1745e2ecc535SCristian Dumitrescu *err_msg = "Invalid timeout value statement.";
1746e2ecc535SCristian Dumitrescu break;
1747e2ecc535SCristian Dumitrescu }
1748e2ecc535SCristian Dumitrescu
1749e2ecc535SCristian Dumitrescu return status;
1750e2ecc535SCristian Dumitrescu }
1751e2ecc535SCristian Dumitrescu
1752e2ecc535SCristian Dumitrescu
1753e2ecc535SCristian Dumitrescu static int
learner_statement_parse(struct learner_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)17544f59d372SCristian Dumitrescu learner_statement_parse(struct learner_spec *s,
17554f59d372SCristian Dumitrescu uint32_t *block_mask,
17564f59d372SCristian Dumitrescu char **tokens,
17574f59d372SCristian Dumitrescu uint32_t n_tokens,
17584f59d372SCristian Dumitrescu uint32_t n_lines,
17594f59d372SCristian Dumitrescu uint32_t *err_line,
17604f59d372SCristian Dumitrescu const char **err_msg)
17614f59d372SCristian Dumitrescu {
17624f59d372SCristian Dumitrescu /* Check format. */
17634f59d372SCristian Dumitrescu if ((n_tokens != 3) || strcmp(tokens[2], "{")) {
17644f59d372SCristian Dumitrescu if (err_line)
17654f59d372SCristian Dumitrescu *err_line = n_lines;
17664f59d372SCristian Dumitrescu if (err_msg)
17674f59d372SCristian Dumitrescu *err_msg = "Invalid learner statement.";
17684f59d372SCristian Dumitrescu return -EINVAL;
17694f59d372SCristian Dumitrescu }
17704f59d372SCristian Dumitrescu
17714f59d372SCristian Dumitrescu /* spec. */
17724f59d372SCristian Dumitrescu s->name = strdup(tokens[1]);
17734f59d372SCristian Dumitrescu if (!s->name) {
17744f59d372SCristian Dumitrescu if (err_line)
17754f59d372SCristian Dumitrescu *err_line = n_lines;
17764f59d372SCristian Dumitrescu if (err_msg)
17774f59d372SCristian Dumitrescu *err_msg = "Memory allocation failed.";
17784f59d372SCristian Dumitrescu return -ENOMEM;
17794f59d372SCristian Dumitrescu }
17804f59d372SCristian Dumitrescu
17814f59d372SCristian Dumitrescu /* block_mask. */
17824f59d372SCristian Dumitrescu *block_mask |= 1 << LEARNER_BLOCK;
17834f59d372SCristian Dumitrescu
17844f59d372SCristian Dumitrescu return 0;
17854f59d372SCristian Dumitrescu }
17864f59d372SCristian Dumitrescu
17874f59d372SCristian Dumitrescu static int
learner_block_parse(struct learner_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)17884f59d372SCristian Dumitrescu learner_block_parse(struct learner_spec *s,
17894f59d372SCristian Dumitrescu uint32_t *block_mask,
17904f59d372SCristian Dumitrescu char **tokens,
17914f59d372SCristian Dumitrescu uint32_t n_tokens,
17924f59d372SCristian Dumitrescu uint32_t n_lines,
17934f59d372SCristian Dumitrescu uint32_t *err_line,
17944f59d372SCristian Dumitrescu const char **err_msg)
17954f59d372SCristian Dumitrescu {
17964f59d372SCristian Dumitrescu if (*block_mask & (1 << LEARNER_KEY_BLOCK))
17974f59d372SCristian Dumitrescu return learner_key_block_parse(s,
17984f59d372SCristian Dumitrescu block_mask,
17994f59d372SCristian Dumitrescu tokens,
18004f59d372SCristian Dumitrescu n_tokens,
18014f59d372SCristian Dumitrescu n_lines,
18024f59d372SCristian Dumitrescu err_line,
18034f59d372SCristian Dumitrescu err_msg);
18044f59d372SCristian Dumitrescu
18054f59d372SCristian Dumitrescu if (*block_mask & (1 << LEARNER_ACTIONS_BLOCK))
18064f59d372SCristian Dumitrescu return learner_actions_block_parse(s,
18074f59d372SCristian Dumitrescu block_mask,
18084f59d372SCristian Dumitrescu tokens,
18094f59d372SCristian Dumitrescu n_tokens,
18104f59d372SCristian Dumitrescu n_lines,
18114f59d372SCristian Dumitrescu err_line,
18124f59d372SCristian Dumitrescu err_msg);
18134f59d372SCristian Dumitrescu
1814e2ecc535SCristian Dumitrescu if (*block_mask & (1 << LEARNER_TIMEOUT_BLOCK))
1815e2ecc535SCristian Dumitrescu return learner_timeout_block_parse(s,
1816e2ecc535SCristian Dumitrescu block_mask,
1817e2ecc535SCristian Dumitrescu tokens,
1818e2ecc535SCristian Dumitrescu n_tokens,
1819e2ecc535SCristian Dumitrescu n_lines,
1820e2ecc535SCristian Dumitrescu err_line,
1821e2ecc535SCristian Dumitrescu err_msg);
1822e2ecc535SCristian Dumitrescu
18234f59d372SCristian Dumitrescu /* Handle end of block. */
18244f59d372SCristian Dumitrescu if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
18254f59d372SCristian Dumitrescu *block_mask &= ~(1 << LEARNER_BLOCK);
18264f59d372SCristian Dumitrescu return 0;
18274f59d372SCristian Dumitrescu }
18284f59d372SCristian Dumitrescu
18294f59d372SCristian Dumitrescu if (!strcmp(tokens[0], "key"))
18304f59d372SCristian Dumitrescu return learner_key_statement_parse(block_mask,
18314f59d372SCristian Dumitrescu tokens,
18324f59d372SCristian Dumitrescu n_tokens,
18334f59d372SCristian Dumitrescu n_lines,
18344f59d372SCristian Dumitrescu err_line,
18354f59d372SCristian Dumitrescu err_msg);
18364f59d372SCristian Dumitrescu
18374f59d372SCristian Dumitrescu if (!strcmp(tokens[0], "actions"))
18384f59d372SCristian Dumitrescu return learner_actions_statement_parse(block_mask,
18394f59d372SCristian Dumitrescu tokens,
18404f59d372SCristian Dumitrescu n_tokens,
18414f59d372SCristian Dumitrescu n_lines,
18424f59d372SCristian Dumitrescu err_line,
18434f59d372SCristian Dumitrescu err_msg);
18444f59d372SCristian Dumitrescu
184573d94b00SCristian Dumitrescu if (!strcmp(tokens[0], "default_action"))
184673d94b00SCristian Dumitrescu return learner_default_action_statement_parse(s,
184773d94b00SCristian Dumitrescu tokens,
184873d94b00SCristian Dumitrescu n_tokens,
184973d94b00SCristian Dumitrescu n_lines,
185073d94b00SCristian Dumitrescu err_line,
185173d94b00SCristian Dumitrescu err_msg);
18524f59d372SCristian Dumitrescu
1853fa7723b5SCristian Dumitrescu if (!strcmp(tokens[0], "hash")) {
1854fa7723b5SCristian Dumitrescu if (n_tokens != 2) {
1855fa7723b5SCristian Dumitrescu if (err_line)
1856fa7723b5SCristian Dumitrescu *err_line = n_lines;
1857fa7723b5SCristian Dumitrescu if (err_msg)
1858fa7723b5SCristian Dumitrescu *err_msg = "Invalid hash statement.";
1859fa7723b5SCristian Dumitrescu return -EINVAL;
1860fa7723b5SCristian Dumitrescu }
1861fa7723b5SCristian Dumitrescu
1862fa7723b5SCristian Dumitrescu if (s->params.hash_func_name) {
1863fa7723b5SCristian Dumitrescu if (err_line)
1864fa7723b5SCristian Dumitrescu *err_line = n_lines;
1865fa7723b5SCristian Dumitrescu if (err_msg)
1866fa7723b5SCristian Dumitrescu *err_msg = "Duplicate hash statement.";
1867fa7723b5SCristian Dumitrescu return -EINVAL;
1868fa7723b5SCristian Dumitrescu }
1869fa7723b5SCristian Dumitrescu
1870fa7723b5SCristian Dumitrescu s->params.hash_func_name = strdup(tokens[1]);
1871fa7723b5SCristian Dumitrescu if (!s->params.hash_func_name) {
1872fa7723b5SCristian Dumitrescu if (err_line)
1873fa7723b5SCristian Dumitrescu *err_line = n_lines;
1874fa7723b5SCristian Dumitrescu if (err_msg)
1875fa7723b5SCristian Dumitrescu *err_msg = "Memory allocation failed.";
1876fa7723b5SCristian Dumitrescu return -ENOMEM;
1877fa7723b5SCristian Dumitrescu }
1878fa7723b5SCristian Dumitrescu
1879fa7723b5SCristian Dumitrescu return 0;
1880fa7723b5SCristian Dumitrescu }
1881fa7723b5SCristian Dumitrescu
18824f59d372SCristian Dumitrescu if (!strcmp(tokens[0], "size")) {
18834f59d372SCristian Dumitrescu char *p = tokens[1];
18844f59d372SCristian Dumitrescu
18854f59d372SCristian Dumitrescu if (n_tokens != 2) {
18864f59d372SCristian Dumitrescu if (err_line)
18874f59d372SCristian Dumitrescu *err_line = n_lines;
18884f59d372SCristian Dumitrescu if (err_msg)
18894f59d372SCristian Dumitrescu *err_msg = "Invalid size statement.";
18904f59d372SCristian Dumitrescu return -EINVAL;
18914f59d372SCristian Dumitrescu }
18924f59d372SCristian Dumitrescu
18934f59d372SCristian Dumitrescu s->size = strtoul(p, &p, 0);
18944f59d372SCristian Dumitrescu if (p[0]) {
18954f59d372SCristian Dumitrescu if (err_line)
18964f59d372SCristian Dumitrescu *err_line = n_lines;
18974f59d372SCristian Dumitrescu if (err_msg)
18984f59d372SCristian Dumitrescu *err_msg = "Invalid size argument.";
18994f59d372SCristian Dumitrescu return -EINVAL;
19004f59d372SCristian Dumitrescu }
19014f59d372SCristian Dumitrescu
19024f59d372SCristian Dumitrescu return 0;
19034f59d372SCristian Dumitrescu }
19044f59d372SCristian Dumitrescu
1905e2ecc535SCristian Dumitrescu if (!strcmp(tokens[0], "timeout"))
1906e2ecc535SCristian Dumitrescu return learner_timeout_statement_parse(block_mask,
1907e2ecc535SCristian Dumitrescu tokens,
1908e2ecc535SCristian Dumitrescu n_tokens,
1909e2ecc535SCristian Dumitrescu n_lines,
1910e2ecc535SCristian Dumitrescu err_line,
1911e2ecc535SCristian Dumitrescu err_msg);
19124f59d372SCristian Dumitrescu
19134f59d372SCristian Dumitrescu /* Anything else. */
19144f59d372SCristian Dumitrescu if (err_line)
19154f59d372SCristian Dumitrescu *err_line = n_lines;
19164f59d372SCristian Dumitrescu if (err_msg)
19174f59d372SCristian Dumitrescu *err_msg = "Invalid statement.";
19184f59d372SCristian Dumitrescu return -EINVAL;
19194f59d372SCristian Dumitrescu }
19204f59d372SCristian Dumitrescu
19214f59d372SCristian Dumitrescu /*
192299a2dd95SBruce Richardson * regarray.
192399a2dd95SBruce Richardson */
192499a2dd95SBruce Richardson static void
regarray_spec_free(struct regarray_spec * s)192599a2dd95SBruce Richardson regarray_spec_free(struct regarray_spec *s)
192699a2dd95SBruce Richardson {
192799a2dd95SBruce Richardson if (!s)
192899a2dd95SBruce Richardson return;
192999a2dd95SBruce Richardson
193099a2dd95SBruce Richardson free(s->name);
193199a2dd95SBruce Richardson s->name = NULL;
193299a2dd95SBruce Richardson }
193399a2dd95SBruce Richardson
193499a2dd95SBruce Richardson static int
regarray_statement_parse(struct regarray_spec * s,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)193599a2dd95SBruce Richardson regarray_statement_parse(struct regarray_spec *s,
193699a2dd95SBruce Richardson char **tokens,
193799a2dd95SBruce Richardson uint32_t n_tokens,
193899a2dd95SBruce Richardson uint32_t n_lines,
193999a2dd95SBruce Richardson uint32_t *err_line,
194099a2dd95SBruce Richardson const char **err_msg)
194199a2dd95SBruce Richardson {
194299a2dd95SBruce Richardson char *p;
194399a2dd95SBruce Richardson
194499a2dd95SBruce Richardson /* Check format. */
194599a2dd95SBruce Richardson if ((n_tokens != 6) ||
194699a2dd95SBruce Richardson strcmp(tokens[2], "size") ||
194799a2dd95SBruce Richardson strcmp(tokens[4], "initval")) {
194899a2dd95SBruce Richardson if (err_line)
194999a2dd95SBruce Richardson *err_line = n_lines;
195099a2dd95SBruce Richardson if (err_msg)
195199a2dd95SBruce Richardson *err_msg = "Invalid regarray statement.";
195299a2dd95SBruce Richardson return -EINVAL;
195399a2dd95SBruce Richardson }
195499a2dd95SBruce Richardson
195599a2dd95SBruce Richardson /* spec. */
195699a2dd95SBruce Richardson s->name = strdup(tokens[1]);
195799a2dd95SBruce Richardson if (!s->name) {
195899a2dd95SBruce Richardson if (err_line)
195999a2dd95SBruce Richardson *err_line = n_lines;
196099a2dd95SBruce Richardson if (err_msg)
196199a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
196299a2dd95SBruce Richardson return -ENOMEM;
196399a2dd95SBruce Richardson }
196499a2dd95SBruce Richardson
196599a2dd95SBruce Richardson p = tokens[3];
196699a2dd95SBruce Richardson s->size = strtoul(p, &p, 0);
196799a2dd95SBruce Richardson if (p[0] || !s->size) {
196899a2dd95SBruce Richardson if (err_line)
196999a2dd95SBruce Richardson *err_line = n_lines;
197099a2dd95SBruce Richardson if (err_msg)
197199a2dd95SBruce Richardson *err_msg = "Invalid size argument.";
197299a2dd95SBruce Richardson return -EINVAL;
197399a2dd95SBruce Richardson }
197499a2dd95SBruce Richardson
197599a2dd95SBruce Richardson p = tokens[5];
197699a2dd95SBruce Richardson s->init_val = strtoull(p, &p, 0);
197799a2dd95SBruce Richardson if (p[0]) {
197899a2dd95SBruce Richardson if (err_line)
197999a2dd95SBruce Richardson *err_line = n_lines;
198099a2dd95SBruce Richardson if (err_msg)
198199a2dd95SBruce Richardson *err_msg = "Invalid initval argument.";
198299a2dd95SBruce Richardson return -EINVAL;
198399a2dd95SBruce Richardson }
198499a2dd95SBruce Richardson
198599a2dd95SBruce Richardson return 0;
198699a2dd95SBruce Richardson }
198799a2dd95SBruce Richardson
198899a2dd95SBruce Richardson /*
198999a2dd95SBruce Richardson * metarray.
199099a2dd95SBruce Richardson */
199199a2dd95SBruce Richardson static void
metarray_spec_free(struct metarray_spec * s)199299a2dd95SBruce Richardson metarray_spec_free(struct metarray_spec *s)
199399a2dd95SBruce Richardson {
199499a2dd95SBruce Richardson if (!s)
199599a2dd95SBruce Richardson return;
199699a2dd95SBruce Richardson
199799a2dd95SBruce Richardson free(s->name);
199899a2dd95SBruce Richardson s->name = NULL;
199999a2dd95SBruce Richardson }
200099a2dd95SBruce Richardson
200199a2dd95SBruce Richardson static int
metarray_statement_parse(struct metarray_spec * s,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)200299a2dd95SBruce Richardson metarray_statement_parse(struct metarray_spec *s,
200399a2dd95SBruce Richardson char **tokens,
200499a2dd95SBruce Richardson uint32_t n_tokens,
200599a2dd95SBruce Richardson uint32_t n_lines,
200699a2dd95SBruce Richardson uint32_t *err_line,
200799a2dd95SBruce Richardson const char **err_msg)
200899a2dd95SBruce Richardson {
200999a2dd95SBruce Richardson char *p;
201099a2dd95SBruce Richardson
201199a2dd95SBruce Richardson /* Check format. */
201299a2dd95SBruce Richardson if ((n_tokens != 4) || strcmp(tokens[2], "size")) {
201399a2dd95SBruce Richardson if (err_line)
201499a2dd95SBruce Richardson *err_line = n_lines;
201599a2dd95SBruce Richardson if (err_msg)
201699a2dd95SBruce Richardson *err_msg = "Invalid metarray statement.";
201799a2dd95SBruce Richardson return -EINVAL;
201899a2dd95SBruce Richardson }
201999a2dd95SBruce Richardson
202099a2dd95SBruce Richardson /* spec. */
202199a2dd95SBruce Richardson s->name = strdup(tokens[1]);
202299a2dd95SBruce Richardson if (!s->name) {
202399a2dd95SBruce Richardson if (err_line)
202499a2dd95SBruce Richardson *err_line = n_lines;
202599a2dd95SBruce Richardson if (err_msg)
202699a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
202799a2dd95SBruce Richardson return -ENOMEM;
202899a2dd95SBruce Richardson }
202999a2dd95SBruce Richardson
203099a2dd95SBruce Richardson p = tokens[3];
203199a2dd95SBruce Richardson s->size = strtoul(p, &p, 0);
203299a2dd95SBruce Richardson if (p[0] || !s->size) {
203399a2dd95SBruce Richardson if (err_line)
203499a2dd95SBruce Richardson *err_line = n_lines;
203599a2dd95SBruce Richardson if (err_msg)
203699a2dd95SBruce Richardson *err_msg = "Invalid size argument.";
203799a2dd95SBruce Richardson return -EINVAL;
203899a2dd95SBruce Richardson }
203999a2dd95SBruce Richardson
204099a2dd95SBruce Richardson return 0;
204199a2dd95SBruce Richardson }
204299a2dd95SBruce Richardson
204399a2dd95SBruce Richardson /*
20448ba342ceSCristian Dumitrescu *
20458ba342ceSCristian Dumitrescu * rss
20468ba342ceSCristian Dumitrescu */
20478ba342ceSCristian Dumitrescu
20488ba342ceSCristian Dumitrescu static void
rss_spec_free(struct rss_spec * s)20498ba342ceSCristian Dumitrescu rss_spec_free(struct rss_spec *s)
20508ba342ceSCristian Dumitrescu {
20518ba342ceSCristian Dumitrescu if (!s)
20528ba342ceSCristian Dumitrescu return;
20538ba342ceSCristian Dumitrescu
20548ba342ceSCristian Dumitrescu free(s->name);
20558ba342ceSCristian Dumitrescu s->name = NULL;
20568ba342ceSCristian Dumitrescu }
20578ba342ceSCristian Dumitrescu
20588ba342ceSCristian Dumitrescu static int
rss_statement_parse(struct rss_spec * s,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)20598ba342ceSCristian Dumitrescu rss_statement_parse(struct rss_spec *s,
20608ba342ceSCristian Dumitrescu char **tokens,
20618ba342ceSCristian Dumitrescu uint32_t n_tokens,
20628ba342ceSCristian Dumitrescu uint32_t n_lines,
20638ba342ceSCristian Dumitrescu uint32_t *err_line,
20648ba342ceSCristian Dumitrescu const char **err_msg)
20658ba342ceSCristian Dumitrescu {
20668ba342ceSCristian Dumitrescu /* Check format. */
20678ba342ceSCristian Dumitrescu if ((n_tokens != 2)) {
20688ba342ceSCristian Dumitrescu if (err_line)
20698ba342ceSCristian Dumitrescu *err_line = n_lines;
20708ba342ceSCristian Dumitrescu if (err_msg)
20718ba342ceSCristian Dumitrescu *err_msg = "Invalid rss statement.";
20728ba342ceSCristian Dumitrescu return -EINVAL;
20738ba342ceSCristian Dumitrescu }
20748ba342ceSCristian Dumitrescu
20758ba342ceSCristian Dumitrescu /* spec. */
20768ba342ceSCristian Dumitrescu s->name = strdup(tokens[1]);
20778ba342ceSCristian Dumitrescu if (!s->name) {
20788ba342ceSCristian Dumitrescu if (err_line)
20798ba342ceSCristian Dumitrescu *err_line = n_lines;
20808ba342ceSCristian Dumitrescu if (err_msg)
20818ba342ceSCristian Dumitrescu *err_msg = "Memory allocation failed.";
20828ba342ceSCristian Dumitrescu return -ENOMEM;
20838ba342ceSCristian Dumitrescu }
20848ba342ceSCristian Dumitrescu
20858ba342ceSCristian Dumitrescu return 0;
20868ba342ceSCristian Dumitrescu }
20878ba342ceSCristian Dumitrescu
20888ba342ceSCristian Dumitrescu /*
208999a2dd95SBruce Richardson * apply.
209099a2dd95SBruce Richardson */
209199a2dd95SBruce Richardson static void
apply_spec_free(struct apply_spec * s)209299a2dd95SBruce Richardson apply_spec_free(struct apply_spec *s)
209399a2dd95SBruce Richardson {
209499a2dd95SBruce Richardson uint32_t i;
209599a2dd95SBruce Richardson
209699a2dd95SBruce Richardson if (!s)
209799a2dd95SBruce Richardson return;
209899a2dd95SBruce Richardson
209999a2dd95SBruce Richardson for (i = 0; i < s->n_instructions; i++) {
210099a2dd95SBruce Richardson uintptr_t instr = (uintptr_t)s->instructions[i];
210199a2dd95SBruce Richardson
210299a2dd95SBruce Richardson free((void *)instr);
210399a2dd95SBruce Richardson }
210499a2dd95SBruce Richardson
210599a2dd95SBruce Richardson free(s->instructions);
210699a2dd95SBruce Richardson s->instructions = NULL;
210799a2dd95SBruce Richardson
210899a2dd95SBruce Richardson s->n_instructions = 0;
210999a2dd95SBruce Richardson }
211099a2dd95SBruce Richardson
211199a2dd95SBruce Richardson static int
apply_statement_parse(uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)211299a2dd95SBruce Richardson apply_statement_parse(uint32_t *block_mask,
211399a2dd95SBruce Richardson char **tokens,
211499a2dd95SBruce Richardson uint32_t n_tokens,
211599a2dd95SBruce Richardson uint32_t n_lines,
211699a2dd95SBruce Richardson uint32_t *err_line,
211799a2dd95SBruce Richardson const char **err_msg)
211899a2dd95SBruce Richardson {
211999a2dd95SBruce Richardson /* Check format. */
212099a2dd95SBruce Richardson if ((n_tokens != 2) || strcmp(tokens[1], "{")) {
212199a2dd95SBruce Richardson if (err_line)
212299a2dd95SBruce Richardson *err_line = n_lines;
212399a2dd95SBruce Richardson if (err_msg)
212499a2dd95SBruce Richardson *err_msg = "Invalid apply statement.";
212599a2dd95SBruce Richardson return -EINVAL;
212699a2dd95SBruce Richardson }
212799a2dd95SBruce Richardson
212899a2dd95SBruce Richardson /* block_mask. */
212999a2dd95SBruce Richardson *block_mask |= 1 << APPLY_BLOCK;
213099a2dd95SBruce Richardson
213199a2dd95SBruce Richardson return 0;
213299a2dd95SBruce Richardson }
213399a2dd95SBruce Richardson
213499a2dd95SBruce Richardson static int
apply_block_parse(struct apply_spec * s,uint32_t * block_mask,char ** tokens,uint32_t n_tokens,uint32_t n_lines,uint32_t * err_line,const char ** err_msg)213599a2dd95SBruce Richardson apply_block_parse(struct apply_spec *s,
213699a2dd95SBruce Richardson uint32_t *block_mask,
213799a2dd95SBruce Richardson char **tokens,
213899a2dd95SBruce Richardson uint32_t n_tokens,
213999a2dd95SBruce Richardson uint32_t n_lines,
214099a2dd95SBruce Richardson uint32_t *err_line,
214199a2dd95SBruce Richardson const char **err_msg)
214299a2dd95SBruce Richardson {
214399a2dd95SBruce Richardson char buffer[RTE_SWX_INSTRUCTION_SIZE], *instr;
214499a2dd95SBruce Richardson const char **new_instructions;
214599a2dd95SBruce Richardson uint32_t i;
214699a2dd95SBruce Richardson
214799a2dd95SBruce Richardson /* Handle end of block. */
214899a2dd95SBruce Richardson if ((n_tokens == 1) && !strcmp(tokens[0], "}")) {
214999a2dd95SBruce Richardson *block_mask &= ~(1 << APPLY_BLOCK);
215099a2dd95SBruce Richardson return 0;
215199a2dd95SBruce Richardson }
215299a2dd95SBruce Richardson
215399a2dd95SBruce Richardson /* spec. */
215499a2dd95SBruce Richardson buffer[0] = 0;
215599a2dd95SBruce Richardson for (i = 0; i < n_tokens; i++) {
215699a2dd95SBruce Richardson if (i)
215799a2dd95SBruce Richardson strcat(buffer, " ");
215899a2dd95SBruce Richardson strcat(buffer, tokens[i]);
215999a2dd95SBruce Richardson }
216099a2dd95SBruce Richardson
216199a2dd95SBruce Richardson instr = strdup(buffer);
216299a2dd95SBruce Richardson if (!instr) {
216399a2dd95SBruce Richardson if (err_line)
216499a2dd95SBruce Richardson *err_line = n_lines;
216599a2dd95SBruce Richardson if (err_msg)
216699a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
216799a2dd95SBruce Richardson return -ENOMEM;
216899a2dd95SBruce Richardson }
216999a2dd95SBruce Richardson
217099a2dd95SBruce Richardson new_instructions = realloc(s->instructions,
217199a2dd95SBruce Richardson (s->n_instructions + 1) * sizeof(char *));
217299a2dd95SBruce Richardson if (!new_instructions) {
217399a2dd95SBruce Richardson free(instr);
217499a2dd95SBruce Richardson
217599a2dd95SBruce Richardson if (err_line)
217699a2dd95SBruce Richardson *err_line = n_lines;
217799a2dd95SBruce Richardson if (err_msg)
217899a2dd95SBruce Richardson *err_msg = "Memory allocation failed.";
217999a2dd95SBruce Richardson return -ENOMEM;
218099a2dd95SBruce Richardson }
218199a2dd95SBruce Richardson
218299a2dd95SBruce Richardson s->instructions = new_instructions;
218399a2dd95SBruce Richardson s->instructions[s->n_instructions] = instr;
218499a2dd95SBruce Richardson s->n_instructions++;
218599a2dd95SBruce Richardson
218699a2dd95SBruce Richardson return 0;
218799a2dd95SBruce Richardson }
218899a2dd95SBruce Richardson
218999a2dd95SBruce Richardson /*
219099a2dd95SBruce Richardson * Pipeline.
219199a2dd95SBruce Richardson */
21924684aa75SCristian Dumitrescu void
pipeline_spec_free(struct pipeline_spec * s)21934684aa75SCristian Dumitrescu pipeline_spec_free(struct pipeline_spec *s)
21944684aa75SCristian Dumitrescu {
21954684aa75SCristian Dumitrescu if (!s)
21964684aa75SCristian Dumitrescu return;
21974684aa75SCristian Dumitrescu
21984684aa75SCristian Dumitrescu free(s->extobjs);
21994684aa75SCristian Dumitrescu free(s->structs);
22004684aa75SCristian Dumitrescu free(s->headers);
22014684aa75SCristian Dumitrescu free(s->metadata);
22024684aa75SCristian Dumitrescu free(s->actions);
22034684aa75SCristian Dumitrescu free(s->tables);
22044684aa75SCristian Dumitrescu free(s->selectors);
22054684aa75SCristian Dumitrescu free(s->learners);
22064684aa75SCristian Dumitrescu free(s->regarrays);
22074684aa75SCristian Dumitrescu free(s->metarrays);
22084684aa75SCristian Dumitrescu free(s->apply);
22094684aa75SCristian Dumitrescu
22104684aa75SCristian Dumitrescu memset(s, 0, sizeof(struct pipeline_spec));
22114684aa75SCristian Dumitrescu }
22124684aa75SCristian Dumitrescu
2213894c93e1SCristian Dumitrescu static const char *
match_type_string_get(enum rte_swx_table_match_type match_type)2214894c93e1SCristian Dumitrescu match_type_string_get(enum rte_swx_table_match_type match_type)
2215894c93e1SCristian Dumitrescu {
2216894c93e1SCristian Dumitrescu switch (match_type) {
2217894c93e1SCristian Dumitrescu case RTE_SWX_TABLE_MATCH_WILDCARD: return "RTE_SWX_TABLE_MATCH_WILDCARD";
2218894c93e1SCristian Dumitrescu case RTE_SWX_TABLE_MATCH_LPM: return "RTE_SWX_TABLE_MATCH_LPM";
2219894c93e1SCristian Dumitrescu case RTE_SWX_TABLE_MATCH_EXACT: return "RTE_SWX_TABLE_MATCH_EXACT";
2220894c93e1SCristian Dumitrescu default: return "RTE_SWX_TABLE_MATCH_UNKNOWN";
2221894c93e1SCristian Dumitrescu }
2222894c93e1SCristian Dumitrescu }
2223894c93e1SCristian Dumitrescu
2224894c93e1SCristian Dumitrescu void
pipeline_spec_codegen(FILE * f,struct pipeline_spec * s)2225894c93e1SCristian Dumitrescu pipeline_spec_codegen(FILE *f,
2226894c93e1SCristian Dumitrescu struct pipeline_spec *s)
2227894c93e1SCristian Dumitrescu {
2228894c93e1SCristian Dumitrescu uint32_t i;
2229894c93e1SCristian Dumitrescu
2230894c93e1SCristian Dumitrescu /* Check the input arguments. */
2231894c93e1SCristian Dumitrescu if (!f || !s)
2232894c93e1SCristian Dumitrescu return;
2233894c93e1SCristian Dumitrescu
2234894c93e1SCristian Dumitrescu /* extobj. */
2235894c93e1SCristian Dumitrescu fprintf(f, "static struct extobj_spec extobjs[] = {\n");
2236894c93e1SCristian Dumitrescu
2237894c93e1SCristian Dumitrescu for (i = 0; i < s->n_extobjs; i++) {
2238894c93e1SCristian Dumitrescu struct extobj_spec *extobj_spec = &s->extobjs[i];
2239894c93e1SCristian Dumitrescu
2240894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
2241894c93e1SCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", extobj_spec->name);
2242894c93e1SCristian Dumitrescu fprintf(f, "\t\t.extern_type_name = \"%s\",\n", extobj_spec->extern_type_name);
2243894c93e1SCristian Dumitrescu if (extobj_spec->pragma)
2244894c93e1SCristian Dumitrescu fprintf(f, "\t\t.pragma = \"%s\",\n", extobj_spec->pragma);
2245894c93e1SCristian Dumitrescu else
2246894c93e1SCristian Dumitrescu fprintf(f, "\t\t.pragma = NULL,\n");
2247894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2248894c93e1SCristian Dumitrescu }
2249894c93e1SCristian Dumitrescu
2250894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2251894c93e1SCristian Dumitrescu
2252894c93e1SCristian Dumitrescu /* regarray. */
2253894c93e1SCristian Dumitrescu fprintf(f, "static struct regarray_spec regarrays[] = {\n");
2254894c93e1SCristian Dumitrescu
2255894c93e1SCristian Dumitrescu for (i = 0; i < s->n_regarrays; i++) {
2256894c93e1SCristian Dumitrescu struct regarray_spec *regarray_spec = &s->regarrays[i];
2257894c93e1SCristian Dumitrescu
2258894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
2259894c93e1SCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", regarray_spec->name);
2260894c93e1SCristian Dumitrescu fprintf(f, "\t\t.init_val = %" PRIu64 ",\n", regarray_spec->init_val);
2261894c93e1SCristian Dumitrescu fprintf(f, "\t\t.size = %u,\n", regarray_spec->size);
2262894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2263894c93e1SCristian Dumitrescu }
2264894c93e1SCristian Dumitrescu
2265894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2266894c93e1SCristian Dumitrescu
2267894c93e1SCristian Dumitrescu /* metarray. */
2268894c93e1SCristian Dumitrescu fprintf(f, "static struct metarray_spec metarrays[] = {\n");
2269894c93e1SCristian Dumitrescu
2270894c93e1SCristian Dumitrescu for (i = 0; i < s->n_metarrays; i++) {
2271894c93e1SCristian Dumitrescu struct metarray_spec *metarray_spec = &s->metarrays[i];
2272894c93e1SCristian Dumitrescu
2273894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
2274894c93e1SCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", metarray_spec->name);
2275894c93e1SCristian Dumitrescu fprintf(f, "\t\t.size = %u,\n", metarray_spec->size);
2276894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2277894c93e1SCristian Dumitrescu }
2278894c93e1SCristian Dumitrescu
2279894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2280894c93e1SCristian Dumitrescu
22818ba342ceSCristian Dumitrescu /* rss. */
22828ba342ceSCristian Dumitrescu fprintf(f, "static struct rss_spec rss[] = {\n");
22838ba342ceSCristian Dumitrescu
22848ba342ceSCristian Dumitrescu for (i = 0; i < s->n_rss; i++) {
22858ba342ceSCristian Dumitrescu struct rss_spec *rss_spec = &s->rss[i];
22868ba342ceSCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
22878ba342ceSCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", rss_spec->name);
22888ba342ceSCristian Dumitrescu fprintf(f, "\t},\n");
22898ba342ceSCristian Dumitrescu }
22908ba342ceSCristian Dumitrescu fprintf(f, "};\n\n");
22918ba342ceSCristian Dumitrescu
2292894c93e1SCristian Dumitrescu /* struct. */
2293894c93e1SCristian Dumitrescu for (i = 0; i < s->n_structs; i++) {
2294894c93e1SCristian Dumitrescu struct struct_spec *struct_spec = &s->structs[i];
2295894c93e1SCristian Dumitrescu uint32_t j;
2296894c93e1SCristian Dumitrescu
2297894c93e1SCristian Dumitrescu fprintf(f, "static struct rte_swx_field_params struct_%s_fields[] = {\n",
2298894c93e1SCristian Dumitrescu struct_spec->name);
2299894c93e1SCristian Dumitrescu
2300894c93e1SCristian Dumitrescu for (j = 0; j < struct_spec->n_fields; j++) {
2301894c93e1SCristian Dumitrescu struct rte_swx_field_params *field = &struct_spec->fields[j];
2302894c93e1SCristian Dumitrescu
2303894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", j);
2304894c93e1SCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", field->name);
2305894c93e1SCristian Dumitrescu fprintf(f, "\t\t.n_bits = %u,\n", field->n_bits);
2306894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2307894c93e1SCristian Dumitrescu }
2308894c93e1SCristian Dumitrescu
2309894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2310894c93e1SCristian Dumitrescu }
2311894c93e1SCristian Dumitrescu
2312894c93e1SCristian Dumitrescu fprintf(f, "static struct struct_spec structs[] = {\n");
2313894c93e1SCristian Dumitrescu
2314894c93e1SCristian Dumitrescu for (i = 0; i < s->n_structs; i++) {
2315894c93e1SCristian Dumitrescu struct struct_spec *struct_spec = &s->structs[i];
2316894c93e1SCristian Dumitrescu
2317894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
2318894c93e1SCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", struct_spec->name);
2319894c93e1SCristian Dumitrescu fprintf(f, "\t\t.fields = struct_%s_fields,\n", struct_spec->name);
2320894c93e1SCristian Dumitrescu fprintf(f, "\t\t.n_fields = "
2321894c93e1SCristian Dumitrescu "sizeof(struct_%s_fields) / sizeof(struct_%s_fields[0]),\n",
2322894c93e1SCristian Dumitrescu struct_spec->name,
2323894c93e1SCristian Dumitrescu struct_spec->name);
2324894c93e1SCristian Dumitrescu fprintf(f, "\t\t.varbit = %d,\n", struct_spec->varbit);
2325894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2326894c93e1SCristian Dumitrescu }
2327894c93e1SCristian Dumitrescu
2328894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2329894c93e1SCristian Dumitrescu
2330894c93e1SCristian Dumitrescu /* header. */
2331894c93e1SCristian Dumitrescu fprintf(f, "static struct header_spec headers[] = {\n");
2332894c93e1SCristian Dumitrescu
2333894c93e1SCristian Dumitrescu for (i = 0; i < s->n_headers; i++) {
2334894c93e1SCristian Dumitrescu struct header_spec *header_spec = &s->headers[i];
2335894c93e1SCristian Dumitrescu
2336894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
2337894c93e1SCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", header_spec->name);
2338894c93e1SCristian Dumitrescu fprintf(f, "\t\t.struct_type_name = \"%s\",\n", header_spec->struct_type_name);
2339894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2340894c93e1SCristian Dumitrescu }
2341894c93e1SCristian Dumitrescu
2342894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2343894c93e1SCristian Dumitrescu
2344894c93e1SCristian Dumitrescu /* metadata. */
2345894c93e1SCristian Dumitrescu fprintf(f, "static struct metadata_spec metadata[] = {\n");
2346894c93e1SCristian Dumitrescu
2347894c93e1SCristian Dumitrescu for (i = 0; i < s->n_metadata; i++) {
2348894c93e1SCristian Dumitrescu struct metadata_spec *metadata_spec = &s->metadata[i];
2349894c93e1SCristian Dumitrescu
2350894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
2351894c93e1SCristian Dumitrescu fprintf(f, "\t\t.struct_type_name = \"%s\",\n", metadata_spec->struct_type_name);
2352894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2353894c93e1SCristian Dumitrescu
2354894c93e1SCristian Dumitrescu }
2355894c93e1SCristian Dumitrescu
2356894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2357894c93e1SCristian Dumitrescu
2358894c93e1SCristian Dumitrescu /* action. */
2359894c93e1SCristian Dumitrescu for (i = 0; i < s->n_actions; i++) {
2360894c93e1SCristian Dumitrescu struct action_spec *action_spec = &s->actions[i];
2361894c93e1SCristian Dumitrescu uint32_t j;
2362894c93e1SCristian Dumitrescu
2363894c93e1SCristian Dumitrescu fprintf(f, "static const char *action_%s_initial_instructions[] = {\n",
2364894c93e1SCristian Dumitrescu action_spec->name);
2365894c93e1SCristian Dumitrescu
2366894c93e1SCristian Dumitrescu for (j = 0; j < action_spec->n_instructions; j++) {
2367894c93e1SCristian Dumitrescu const char *instr = action_spec->instructions[j];
2368894c93e1SCristian Dumitrescu
2369894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = \"%s\",\n", j, instr);
2370894c93e1SCristian Dumitrescu }
2371894c93e1SCristian Dumitrescu
2372894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2373894c93e1SCristian Dumitrescu }
2374894c93e1SCristian Dumitrescu
2375894c93e1SCristian Dumitrescu fprintf(f, "static struct action_spec actions[] = {\n");
2376894c93e1SCristian Dumitrescu
2377894c93e1SCristian Dumitrescu for (i = 0; i < s->n_actions; i++) {
2378894c93e1SCristian Dumitrescu struct action_spec *action_spec = &s->actions[i];
2379894c93e1SCristian Dumitrescu
2380894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
2381894c93e1SCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", action_spec->name);
2382894c93e1SCristian Dumitrescu
2383894c93e1SCristian Dumitrescu if (action_spec->args_struct_type_name)
2384894c93e1SCristian Dumitrescu fprintf(f, "\t\t.args_struct_type_name = \"%s\",\n",
2385894c93e1SCristian Dumitrescu action_spec->args_struct_type_name);
2386894c93e1SCristian Dumitrescu else
2387894c93e1SCristian Dumitrescu fprintf(f, "\t\t.args_struct_type_name = NULL,\n");
2388894c93e1SCristian Dumitrescu
2389894c93e1SCristian Dumitrescu fprintf(f, "\t\t.instructions = action_%s_initial_instructions,\n",
2390894c93e1SCristian Dumitrescu action_spec->name);
2391894c93e1SCristian Dumitrescu fprintf(f, "\t\t.n_instructions = "
2392894c93e1SCristian Dumitrescu "sizeof(action_%s_initial_instructions) / "
2393894c93e1SCristian Dumitrescu "sizeof(action_%s_initial_instructions[0]),\n",
2394894c93e1SCristian Dumitrescu action_spec->name,
2395894c93e1SCristian Dumitrescu action_spec->name);
2396894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2397894c93e1SCristian Dumitrescu }
2398894c93e1SCristian Dumitrescu
2399894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2400894c93e1SCristian Dumitrescu
2401894c93e1SCristian Dumitrescu /* table. */
2402894c93e1SCristian Dumitrescu for (i = 0; i < s->n_tables; i++) {
2403894c93e1SCristian Dumitrescu struct table_spec *table_spec = &s->tables[i];
2404894c93e1SCristian Dumitrescu uint32_t j;
2405894c93e1SCristian Dumitrescu
2406894c93e1SCristian Dumitrescu /* fields. */
2407894c93e1SCristian Dumitrescu if (table_spec->params.fields && table_spec->params.n_fields) {
2408894c93e1SCristian Dumitrescu fprintf(f, "static struct rte_swx_match_field_params "
2409894c93e1SCristian Dumitrescu "table_%s_fields[] = {\n",
2410894c93e1SCristian Dumitrescu table_spec->name);
2411894c93e1SCristian Dumitrescu
2412894c93e1SCristian Dumitrescu for (j = 0; j < table_spec->params.n_fields; j++) {
2413894c93e1SCristian Dumitrescu struct rte_swx_match_field_params *field =
2414894c93e1SCristian Dumitrescu &table_spec->params.fields[j];
2415894c93e1SCristian Dumitrescu
2416894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", j);
2417894c93e1SCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", field->name);
2418894c93e1SCristian Dumitrescu fprintf(f, "\t\t.match_type = %s,\n",
2419894c93e1SCristian Dumitrescu match_type_string_get(field->match_type));
2420894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2421894c93e1SCristian Dumitrescu }
2422894c93e1SCristian Dumitrescu
2423894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2424894c93e1SCristian Dumitrescu }
2425894c93e1SCristian Dumitrescu
2426894c93e1SCristian Dumitrescu /* action_names. */
2427894c93e1SCristian Dumitrescu if (table_spec->params.action_names && table_spec->params.n_actions) {
2428894c93e1SCristian Dumitrescu fprintf(f, "static const char *table_%s_action_names[] = {\n",
2429894c93e1SCristian Dumitrescu table_spec->name);
2430894c93e1SCristian Dumitrescu
2431894c93e1SCristian Dumitrescu for (j = 0; j < table_spec->params.n_actions; j++) {
2432894c93e1SCristian Dumitrescu const char *action_name = table_spec->params.action_names[j];
2433894c93e1SCristian Dumitrescu
2434894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = \"%s\",\n", j, action_name);
2435894c93e1SCristian Dumitrescu }
2436894c93e1SCristian Dumitrescu
2437894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2438894c93e1SCristian Dumitrescu }
2439894c93e1SCristian Dumitrescu
2440894c93e1SCristian Dumitrescu /* action_is_for_table_entries. */
2441894c93e1SCristian Dumitrescu if (table_spec->params.action_is_for_table_entries &&
2442894c93e1SCristian Dumitrescu table_spec->params.n_actions) {
2443894c93e1SCristian Dumitrescu fprintf(f, "static int table_%s_action_is_for_table_entries[] = {\n",
2444894c93e1SCristian Dumitrescu table_spec->name);
2445894c93e1SCristian Dumitrescu
2446894c93e1SCristian Dumitrescu for (j = 0; j < table_spec->params.n_actions; j++) {
2447894c93e1SCristian Dumitrescu int value = table_spec->params.action_is_for_table_entries[j];
2448894c93e1SCristian Dumitrescu
2449894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = %d,\n", j, value);
2450894c93e1SCristian Dumitrescu }
2451894c93e1SCristian Dumitrescu
2452894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2453894c93e1SCristian Dumitrescu }
2454894c93e1SCristian Dumitrescu
2455894c93e1SCristian Dumitrescu /* action_is_for_default_entry. */
2456894c93e1SCristian Dumitrescu if (table_spec->params.action_is_for_default_entry &&
2457894c93e1SCristian Dumitrescu table_spec->params.n_actions) {
2458894c93e1SCristian Dumitrescu fprintf(f, "static int table_%s_action_is_for_default_entry[] = {\n",
2459894c93e1SCristian Dumitrescu table_spec->name);
2460894c93e1SCristian Dumitrescu
2461894c93e1SCristian Dumitrescu for (j = 0; j < table_spec->params.n_actions; j++) {
2462894c93e1SCristian Dumitrescu int value = table_spec->params.action_is_for_default_entry[j];
2463894c93e1SCristian Dumitrescu
2464894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = %d,\n", j, value);
2465894c93e1SCristian Dumitrescu }
2466894c93e1SCristian Dumitrescu
2467894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2468894c93e1SCristian Dumitrescu }
2469894c93e1SCristian Dumitrescu }
2470894c93e1SCristian Dumitrescu
2471894c93e1SCristian Dumitrescu fprintf(f, "static struct table_spec tables[] = {\n");
2472894c93e1SCristian Dumitrescu
2473894c93e1SCristian Dumitrescu for (i = 0; i < s->n_tables; i++) {
2474894c93e1SCristian Dumitrescu struct table_spec *table_spec = &s->tables[i];
2475894c93e1SCristian Dumitrescu
2476894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
2477894c93e1SCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", table_spec->name);
2478894c93e1SCristian Dumitrescu
2479894c93e1SCristian Dumitrescu fprintf(f, "\t\t.params = {\n");
2480894c93e1SCristian Dumitrescu
2481894c93e1SCristian Dumitrescu if (table_spec->params.fields && table_spec->params.n_fields) {
2482894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.fields = table_%s_fields,\n", table_spec->name);
2483894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_fields = "
2484894c93e1SCristian Dumitrescu "sizeof(table_%s_fields) / sizeof(table_%s_fields[0]),\n",
2485894c93e1SCristian Dumitrescu table_spec->name,
2486894c93e1SCristian Dumitrescu table_spec->name);
2487894c93e1SCristian Dumitrescu } else {
2488894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.fields = NULL,\n");
2489894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_fields = 0,\n");
2490894c93e1SCristian Dumitrescu }
2491894c93e1SCristian Dumitrescu
2492894c93e1SCristian Dumitrescu if (table_spec->params.action_names && table_spec->params.n_actions)
2493894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_names = table_%s_action_names,\n",
2494894c93e1SCristian Dumitrescu table_spec->name);
2495894c93e1SCristian Dumitrescu else
2496894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_names = NULL,\n");
2497894c93e1SCristian Dumitrescu
2498894c93e1SCristian Dumitrescu if (table_spec->params.action_is_for_table_entries && table_spec->params.n_actions)
2499894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_is_for_table_entries = "
2500894c93e1SCristian Dumitrescu "table_%s_action_is_for_table_entries,\n",
2501894c93e1SCristian Dumitrescu table_spec->name);
2502894c93e1SCristian Dumitrescu else
2503894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_is_for_table_entries = NULL,\n");
2504894c93e1SCristian Dumitrescu
2505894c93e1SCristian Dumitrescu if (table_spec->params.action_is_for_default_entry && table_spec->params.n_actions)
2506894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_is_for_default_entry = "
2507894c93e1SCristian Dumitrescu "table_%s_action_is_for_default_entry,\n",
2508894c93e1SCristian Dumitrescu table_spec->name);
2509894c93e1SCristian Dumitrescu else
2510894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_is_for_default_entry = NULL,\n");
2511894c93e1SCristian Dumitrescu
2512894c93e1SCristian Dumitrescu if (table_spec->params.n_actions)
2513894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_actions = sizeof(table_%s_action_names) / "
2514894c93e1SCristian Dumitrescu "sizeof(table_%s_action_names[0]),\n",
2515894c93e1SCristian Dumitrescu table_spec->name,
2516894c93e1SCristian Dumitrescu table_spec->name);
2517894c93e1SCristian Dumitrescu else
2518894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_actions = 0,\n");
2519894c93e1SCristian Dumitrescu
2520894c93e1SCristian Dumitrescu if (table_spec->params.default_action_name)
2521894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.default_action_name = \"%s\",\n",
2522894c93e1SCristian Dumitrescu table_spec->params.default_action_name);
2523894c93e1SCristian Dumitrescu else
2524894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.default_action_name = NULL,\n");
2525894c93e1SCristian Dumitrescu
2526894c93e1SCristian Dumitrescu if (table_spec->params.default_action_args)
2527894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.default_action_args = \"%s\",\n",
2528894c93e1SCristian Dumitrescu table_spec->params.default_action_args);
2529894c93e1SCristian Dumitrescu else
2530894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.default_action_args = NULL,\n");
2531894c93e1SCristian Dumitrescu
2532894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.default_action_is_const = %d,\n",
2533894c93e1SCristian Dumitrescu table_spec->params.default_action_is_const);
25349560a329SCristian Dumitrescu
25359560a329SCristian Dumitrescu if (table_spec->params.hash_func_name)
25369560a329SCristian Dumitrescu fprintf(f, "\t\t\t.hash_func_name = \"%s\",\n",
25379560a329SCristian Dumitrescu table_spec->params.hash_func_name);
25389560a329SCristian Dumitrescu else
25399560a329SCristian Dumitrescu fprintf(f, "\t\t\t.hash_func_name = NULL,\n");
25409560a329SCristian Dumitrescu
2541894c93e1SCristian Dumitrescu fprintf(f, "\t\t},\n");
2542894c93e1SCristian Dumitrescu
2543894c93e1SCristian Dumitrescu if (table_spec->recommended_table_type_name)
2544894c93e1SCristian Dumitrescu fprintf(f, "\t\t.recommended_table_type_name = \"%s\",\n",
2545894c93e1SCristian Dumitrescu table_spec->recommended_table_type_name);
2546894c93e1SCristian Dumitrescu else
2547894c93e1SCristian Dumitrescu fprintf(f, "\t\t.recommended_table_type_name = NULL,\n");
2548894c93e1SCristian Dumitrescu
2549894c93e1SCristian Dumitrescu if (table_spec->args)
2550894c93e1SCristian Dumitrescu fprintf(f, "\t\t.args = \"%s\",\n", table_spec->args);
2551894c93e1SCristian Dumitrescu else
2552894c93e1SCristian Dumitrescu fprintf(f, "\t\t.args = NULL,\n");
2553894c93e1SCristian Dumitrescu
2554894c93e1SCristian Dumitrescu fprintf(f, "\t\t.size = %u,\n", table_spec->size);
2555894c93e1SCristian Dumitrescu
2556894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2557894c93e1SCristian Dumitrescu }
2558894c93e1SCristian Dumitrescu
2559894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2560894c93e1SCristian Dumitrescu
2561894c93e1SCristian Dumitrescu /* selector. */
2562894c93e1SCristian Dumitrescu for (i = 0; i < s->n_selectors; i++) {
2563894c93e1SCristian Dumitrescu struct selector_spec *selector_spec = &s->selectors[i];
2564894c93e1SCristian Dumitrescu uint32_t j;
2565894c93e1SCristian Dumitrescu
2566894c93e1SCristian Dumitrescu if (selector_spec->params.selector_field_names &&
2567894c93e1SCristian Dumitrescu selector_spec->params.n_selector_fields) {
2568894c93e1SCristian Dumitrescu fprintf(f, "static const char *selector_%s_field_names[] = {\n",
2569894c93e1SCristian Dumitrescu selector_spec->name);
2570894c93e1SCristian Dumitrescu
2571894c93e1SCristian Dumitrescu for (j = 0; j < selector_spec->params.n_selector_fields; j++) {
2572894c93e1SCristian Dumitrescu const char *field_name =
2573894c93e1SCristian Dumitrescu selector_spec->params.selector_field_names[j];
2574894c93e1SCristian Dumitrescu
2575894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = \"%s\",\n", j, field_name);
2576894c93e1SCristian Dumitrescu }
2577894c93e1SCristian Dumitrescu
2578894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2579894c93e1SCristian Dumitrescu }
2580894c93e1SCristian Dumitrescu }
2581894c93e1SCristian Dumitrescu
2582894c93e1SCristian Dumitrescu fprintf(f, "static struct selector_spec selectors[] = {\n");
2583894c93e1SCristian Dumitrescu
2584894c93e1SCristian Dumitrescu for (i = 0; i < s->n_selectors; i++) {
2585894c93e1SCristian Dumitrescu struct selector_spec *selector_spec = &s->selectors[i];
2586894c93e1SCristian Dumitrescu
2587894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
2588894c93e1SCristian Dumitrescu
2589894c93e1SCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", selector_spec->name);
2590894c93e1SCristian Dumitrescu fprintf(f, "\t\t.params = {\n");
2591894c93e1SCristian Dumitrescu
2592894c93e1SCristian Dumitrescu if (selector_spec->params.group_id_field_name)
2593894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.group_id_field_name = \"%s\",\n",
2594894c93e1SCristian Dumitrescu selector_spec->params.group_id_field_name);
2595894c93e1SCristian Dumitrescu else
2596894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.group_id_field_name = NULL,\n");
2597894c93e1SCristian Dumitrescu
2598894c93e1SCristian Dumitrescu if (selector_spec->params.selector_field_names &&
2599894c93e1SCristian Dumitrescu selector_spec->params.n_selector_fields) {
2600894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.selector_field_names = selector_%s_field_names,\n",
2601894c93e1SCristian Dumitrescu selector_spec->name);
2602894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_selector_fields = "
2603894c93e1SCristian Dumitrescu "sizeof(selector_%s_field_names) / sizeof(selector_%s_field_names[0]),\n",
2604894c93e1SCristian Dumitrescu selector_spec->name,
2605894c93e1SCristian Dumitrescu selector_spec->name);
2606894c93e1SCristian Dumitrescu } else {
2607894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.selector_field_names = NULL,\n");
2608894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_selector_fields = 0,\n");
2609894c93e1SCristian Dumitrescu }
2610894c93e1SCristian Dumitrescu
2611894c93e1SCristian Dumitrescu if (selector_spec->params.member_id_field_name)
2612894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.member_id_field_name = \"%s\",\n",
2613894c93e1SCristian Dumitrescu selector_spec->params.member_id_field_name);
2614894c93e1SCristian Dumitrescu else
2615894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.member_id_field_name = NULL,\n");
2616894c93e1SCristian Dumitrescu
2617894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_groups_max = %u,\n", selector_spec->params.n_groups_max);
2618894c93e1SCristian Dumitrescu
2619894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_members_per_group_max = %u,\n",
2620894c93e1SCristian Dumitrescu selector_spec->params.n_members_per_group_max);
2621894c93e1SCristian Dumitrescu
2622894c93e1SCristian Dumitrescu fprintf(f, "\t\t},\n");
2623894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2624894c93e1SCristian Dumitrescu }
2625894c93e1SCristian Dumitrescu
2626894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2627894c93e1SCristian Dumitrescu
2628894c93e1SCristian Dumitrescu /* learner. */
2629894c93e1SCristian Dumitrescu for (i = 0; i < s->n_learners; i++) {
2630894c93e1SCristian Dumitrescu struct learner_spec *learner_spec = &s->learners[i];
2631894c93e1SCristian Dumitrescu uint32_t j;
2632894c93e1SCristian Dumitrescu
2633894c93e1SCristian Dumitrescu /* field_names. */
2634894c93e1SCristian Dumitrescu if (learner_spec->params.field_names && learner_spec->params.n_fields) {
2635894c93e1SCristian Dumitrescu fprintf(f, "static const char *learner_%s_field_names[] = {\n",
2636894c93e1SCristian Dumitrescu learner_spec->name);
2637894c93e1SCristian Dumitrescu
2638894c93e1SCristian Dumitrescu for (j = 0; j < learner_spec->params.n_fields; j++) {
2639894c93e1SCristian Dumitrescu const char *field_name = learner_spec->params.field_names[j];
2640894c93e1SCristian Dumitrescu
2641894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = \"%s\",\n", j, field_name);
2642894c93e1SCristian Dumitrescu }
2643894c93e1SCristian Dumitrescu
2644894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2645894c93e1SCristian Dumitrescu }
2646894c93e1SCristian Dumitrescu
2647894c93e1SCristian Dumitrescu /* action_names. */
2648894c93e1SCristian Dumitrescu if (learner_spec->params.action_names && learner_spec->params.n_actions) {
2649894c93e1SCristian Dumitrescu fprintf(f, "static const char *learner_%s_action_names[] = {\n",
2650894c93e1SCristian Dumitrescu learner_spec->name);
2651894c93e1SCristian Dumitrescu
2652894c93e1SCristian Dumitrescu for (j = 0; j < learner_spec->params.n_actions; j++) {
2653894c93e1SCristian Dumitrescu const char *action_name = learner_spec->params.action_names[j];
2654894c93e1SCristian Dumitrescu
2655894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = \"%s\",\n", j, action_name);
2656894c93e1SCristian Dumitrescu }
2657894c93e1SCristian Dumitrescu
2658894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2659894c93e1SCristian Dumitrescu }
2660894c93e1SCristian Dumitrescu
2661894c93e1SCristian Dumitrescu /* action_is_for_table_entries. */
2662894c93e1SCristian Dumitrescu if (learner_spec->params.action_is_for_table_entries &&
2663894c93e1SCristian Dumitrescu learner_spec->params.n_actions) {
2664894c93e1SCristian Dumitrescu fprintf(f, "static int learner_%s_action_is_for_table_entries[] = {\n",
2665894c93e1SCristian Dumitrescu learner_spec->name);
2666894c93e1SCristian Dumitrescu
2667894c93e1SCristian Dumitrescu for (j = 0; j < learner_spec->params.n_actions; j++) {
2668894c93e1SCristian Dumitrescu int value = learner_spec->params.action_is_for_table_entries[j];
2669894c93e1SCristian Dumitrescu
2670894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = %d,\n", j, value);
2671894c93e1SCristian Dumitrescu }
2672894c93e1SCristian Dumitrescu
2673894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2674894c93e1SCristian Dumitrescu }
2675894c93e1SCristian Dumitrescu
2676894c93e1SCristian Dumitrescu /* action_is_for_default_entry. */
2677894c93e1SCristian Dumitrescu if (learner_spec->params.action_is_for_default_entry &&
2678894c93e1SCristian Dumitrescu learner_spec->params.n_actions) {
2679894c93e1SCristian Dumitrescu fprintf(f, "static int learner_%s_action_is_for_default_entry[] = {\n",
2680894c93e1SCristian Dumitrescu learner_spec->name);
2681894c93e1SCristian Dumitrescu
2682894c93e1SCristian Dumitrescu for (j = 0; j < learner_spec->params.n_actions; j++) {
2683894c93e1SCristian Dumitrescu int value = learner_spec->params.action_is_for_default_entry[j];
2684894c93e1SCristian Dumitrescu
2685894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = %d,\n", j, value);
2686894c93e1SCristian Dumitrescu }
2687894c93e1SCristian Dumitrescu
2688894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2689894c93e1SCristian Dumitrescu }
2690894c93e1SCristian Dumitrescu
2691894c93e1SCristian Dumitrescu /* timeout. */
2692894c93e1SCristian Dumitrescu if (learner_spec->timeout && learner_spec->n_timeouts) {
2693894c93e1SCristian Dumitrescu fprintf(f, "static uint32_t learner_%s_timeout[] = {\n",
2694894c93e1SCristian Dumitrescu learner_spec->name);
2695894c93e1SCristian Dumitrescu
2696894c93e1SCristian Dumitrescu for (j = 0; j < learner_spec->n_timeouts; j++) {
2697894c93e1SCristian Dumitrescu uint32_t value = learner_spec->timeout[j];
2698894c93e1SCristian Dumitrescu
2699894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = %u,\n", j, value);
2700894c93e1SCristian Dumitrescu }
2701894c93e1SCristian Dumitrescu
2702894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2703894c93e1SCristian Dumitrescu }
2704894c93e1SCristian Dumitrescu }
2705894c93e1SCristian Dumitrescu
2706894c93e1SCristian Dumitrescu fprintf(f, "static struct learner_spec learners[] = {\n");
2707894c93e1SCristian Dumitrescu
2708894c93e1SCristian Dumitrescu for (i = 0; i < s->n_learners; i++) {
2709894c93e1SCristian Dumitrescu struct learner_spec *learner_spec = &s->learners[i];
2710894c93e1SCristian Dumitrescu
2711894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
2712894c93e1SCristian Dumitrescu fprintf(f, "\t\t.name = \"%s\",\n", learner_spec->name);
2713894c93e1SCristian Dumitrescu
2714894c93e1SCristian Dumitrescu fprintf(f, "\t\t.params = {\n");
2715894c93e1SCristian Dumitrescu
2716894c93e1SCristian Dumitrescu if (learner_spec->params.field_names && learner_spec->params.n_fields) {
2717894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.field_names = learner_%s_field_names,\n",
2718894c93e1SCristian Dumitrescu learner_spec->name);
2719894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_fields = "
2720894c93e1SCristian Dumitrescu "sizeof(learner_%s_field_names) / "
2721894c93e1SCristian Dumitrescu "sizeof(learner_%s_field_names[0]),\n",
2722894c93e1SCristian Dumitrescu learner_spec->name,
2723894c93e1SCristian Dumitrescu learner_spec->name);
2724894c93e1SCristian Dumitrescu } else {
2725894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.field_names = NULL,\n");
2726894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_fields = 0,\n");
2727894c93e1SCristian Dumitrescu }
2728894c93e1SCristian Dumitrescu
2729894c93e1SCristian Dumitrescu if (learner_spec->params.action_names && learner_spec->params.n_actions)
2730894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_names = learner_%s_action_names,\n",
2731894c93e1SCristian Dumitrescu learner_spec->name);
2732894c93e1SCristian Dumitrescu else
2733894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_names = NULL,\n");
2734894c93e1SCristian Dumitrescu
2735894c93e1SCristian Dumitrescu if (learner_spec->params.action_is_for_table_entries &&
2736894c93e1SCristian Dumitrescu learner_spec->params.n_actions)
2737894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_is_for_table_entries = "
2738894c93e1SCristian Dumitrescu "learner_%s_action_is_for_table_entries,\n",
2739894c93e1SCristian Dumitrescu learner_spec->name);
2740894c93e1SCristian Dumitrescu else
2741894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_is_for_table_entries = NULL,\n");
2742894c93e1SCristian Dumitrescu
2743894c93e1SCristian Dumitrescu if (learner_spec->params.action_is_for_default_entry &&
2744894c93e1SCristian Dumitrescu learner_spec->params.n_actions)
2745894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_is_for_default_entry = "
2746894c93e1SCristian Dumitrescu "learner_%s_action_is_for_default_entry,\n",
2747894c93e1SCristian Dumitrescu learner_spec->name);
2748894c93e1SCristian Dumitrescu else
2749894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.action_is_for_default_entry = NULL,\n");
2750894c93e1SCristian Dumitrescu
2751894c93e1SCristian Dumitrescu if (learner_spec->params.action_names && learner_spec->params.n_actions)
2752894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_actions = "
2753894c93e1SCristian Dumitrescu "sizeof(learner_%s_action_names) / sizeof(learner_%s_action_names[0]),\n",
2754894c93e1SCristian Dumitrescu learner_spec->name,
2755894c93e1SCristian Dumitrescu learner_spec->name);
2756894c93e1SCristian Dumitrescu else
2757894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_actions = NULL,\n");
2758894c93e1SCristian Dumitrescu
2759894c93e1SCristian Dumitrescu if (learner_spec->params.default_action_name)
2760894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.default_action_name = \"%s\",\n",
2761894c93e1SCristian Dumitrescu learner_spec->params.default_action_name);
2762894c93e1SCristian Dumitrescu else
2763894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.default_action_name = NULL,\n");
2764894c93e1SCristian Dumitrescu
2765894c93e1SCristian Dumitrescu if (learner_spec->params.default_action_args)
2766894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.default_action_args = \"%s\",\n",
2767894c93e1SCristian Dumitrescu learner_spec->params.default_action_args);
2768894c93e1SCristian Dumitrescu else
2769894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.default_action_args = NULL,\n");
2770894c93e1SCristian Dumitrescu
2771894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.default_action_is_const = %d,\n",
2772894c93e1SCristian Dumitrescu learner_spec->params.default_action_is_const);
2773894c93e1SCristian Dumitrescu
2774fa7723b5SCristian Dumitrescu if (learner_spec->params.hash_func_name)
2775fa7723b5SCristian Dumitrescu fprintf(f, "\t\t\t.hash_func_name = \"%s\",\n",
2776fa7723b5SCristian Dumitrescu learner_spec->params.hash_func_name);
2777fa7723b5SCristian Dumitrescu else
2778fa7723b5SCristian Dumitrescu fprintf(f, "\t\t\t.hash_func_name = NULL,\n");
2779fa7723b5SCristian Dumitrescu
2780894c93e1SCristian Dumitrescu fprintf(f, "\t\t},\n");
2781894c93e1SCristian Dumitrescu
2782894c93e1SCristian Dumitrescu fprintf(f, "\t\t.size = %u,\n", learner_spec->size);
2783894c93e1SCristian Dumitrescu
2784894c93e1SCristian Dumitrescu if (learner_spec->timeout && learner_spec->n_timeouts) {
2785894c93e1SCristian Dumitrescu fprintf(f, "\t\t.timeout = learner_%s_timeout,\n", learner_spec->name);
2786894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_timeouts = "
2787894c93e1SCristian Dumitrescu "sizeof(learner_%s_timeout) / sizeof(learner_%s_timeout[0]),\n",
2788894c93e1SCristian Dumitrescu learner_spec->name,
2789894c93e1SCristian Dumitrescu learner_spec->name);
2790894c93e1SCristian Dumitrescu } else {
2791894c93e1SCristian Dumitrescu fprintf(f, "\t\t.timeout = NULL,\n");
2792894c93e1SCristian Dumitrescu fprintf(f, "\t\t\t.n_timeouts = 0,\n");
2793894c93e1SCristian Dumitrescu }
2794894c93e1SCristian Dumitrescu
2795894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2796894c93e1SCristian Dumitrescu }
2797894c93e1SCristian Dumitrescu
2798894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2799894c93e1SCristian Dumitrescu
2800894c93e1SCristian Dumitrescu /* apply. */
2801894c93e1SCristian Dumitrescu for (i = 0; i < s->n_apply; i++) {
2802894c93e1SCristian Dumitrescu struct apply_spec *apply_spec = &s->apply[i];
2803894c93e1SCristian Dumitrescu uint32_t j;
2804894c93e1SCristian Dumitrescu
2805894c93e1SCristian Dumitrescu fprintf(f, "static const char *apply%u_initial_instructions[] = {\n", i);
2806894c93e1SCristian Dumitrescu
2807894c93e1SCristian Dumitrescu for (j = 0; j < apply_spec->n_instructions; j++) {
2808894c93e1SCristian Dumitrescu const char *instr = apply_spec->instructions[j];
2809894c93e1SCristian Dumitrescu
2810894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = \"%s\",\n", j, instr);
2811894c93e1SCristian Dumitrescu }
2812894c93e1SCristian Dumitrescu
2813894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2814894c93e1SCristian Dumitrescu }
2815894c93e1SCristian Dumitrescu
2816894c93e1SCristian Dumitrescu fprintf(f, "static struct apply_spec apply[] = {\n");
2817894c93e1SCristian Dumitrescu
2818894c93e1SCristian Dumitrescu for (i = 0; i < s->n_apply; i++) {
2819894c93e1SCristian Dumitrescu fprintf(f, "\t[%d] = {\n", i);
2820894c93e1SCristian Dumitrescu fprintf(f, "\t.instructions = apply%u_initial_instructions,\n", i);
2821894c93e1SCristian Dumitrescu fprintf(f, "\t.n_instructions = "
2822894c93e1SCristian Dumitrescu "sizeof(apply%u_initial_instructions) / "
2823894c93e1SCristian Dumitrescu "sizeof(apply%u_initial_instructions[0]),\n",
2824894c93e1SCristian Dumitrescu i,
2825894c93e1SCristian Dumitrescu i);
2826894c93e1SCristian Dumitrescu fprintf(f, "\t},\n");
2827894c93e1SCristian Dumitrescu }
2828894c93e1SCristian Dumitrescu
2829894c93e1SCristian Dumitrescu fprintf(f, "};\n\n");
2830894c93e1SCristian Dumitrescu
2831894c93e1SCristian Dumitrescu /* pipeline. */
2832894c93e1SCristian Dumitrescu fprintf(f, "struct pipeline_spec pipeline_spec = {\n");
2833894c93e1SCristian Dumitrescu fprintf(f, "\t.extobjs = extobjs,\n");
2834894c93e1SCristian Dumitrescu fprintf(f, "\t.structs = structs,\n");
2835894c93e1SCristian Dumitrescu fprintf(f, "\t.headers = headers,\n");
2836894c93e1SCristian Dumitrescu fprintf(f, "\t.metadata = metadata,\n");
2837894c93e1SCristian Dumitrescu fprintf(f, "\t.actions = actions,\n");
2838894c93e1SCristian Dumitrescu fprintf(f, "\t.tables = tables,\n");
2839894c93e1SCristian Dumitrescu fprintf(f, "\t.selectors = selectors,\n");
2840894c93e1SCristian Dumitrescu fprintf(f, "\t.learners = learners,\n");
2841894c93e1SCristian Dumitrescu fprintf(f, "\t.regarrays = regarrays,\n");
2842894c93e1SCristian Dumitrescu fprintf(f, "\t.metarrays = metarrays,\n");
28438ba342ceSCristian Dumitrescu fprintf(f, "\t.rss = rss,\n");
2844894c93e1SCristian Dumitrescu fprintf(f, "\t.apply = apply,\n");
2845894c93e1SCristian Dumitrescu fprintf(f, "\t.n_extobjs = sizeof(extobjs) / sizeof(extobjs[0]),\n");
2846894c93e1SCristian Dumitrescu fprintf(f, "\t.n_structs = sizeof(structs) / sizeof(structs[0]),\n");
2847894c93e1SCristian Dumitrescu fprintf(f, "\t.n_headers = sizeof(headers) / sizeof(headers[0]),\n");
2848894c93e1SCristian Dumitrescu fprintf(f, "\t.n_metadata = sizeof(metadata) / sizeof(metadata[0]),\n");
2849894c93e1SCristian Dumitrescu fprintf(f, "\t.n_actions = sizeof(actions) / sizeof(actions[0]),\n");
2850894c93e1SCristian Dumitrescu fprintf(f, "\t.n_tables = sizeof(tables) / sizeof(tables[0]),\n");
2851894c93e1SCristian Dumitrescu fprintf(f, "\t.n_selectors = sizeof(selectors) / sizeof(selectors[0]),\n");
2852894c93e1SCristian Dumitrescu fprintf(f, "\t.n_learners = sizeof(learners) / sizeof(learners[0]),\n");
2853894c93e1SCristian Dumitrescu fprintf(f, "\t.n_regarrays = sizeof(regarrays) / sizeof(regarrays[0]),\n");
2854894c93e1SCristian Dumitrescu fprintf(f, "\t.n_metarrays = sizeof(metarrays) / sizeof(metarrays[0]),\n");
28558ba342ceSCristian Dumitrescu fprintf(f, "\t.n_rss = sizeof(rss) / sizeof(rss[0]),\n");
2856894c93e1SCristian Dumitrescu fprintf(f, "\t.n_apply = sizeof(apply) / sizeof(apply[0]),\n");
2857894c93e1SCristian Dumitrescu fprintf(f, "};\n");
2858894c93e1SCristian Dumitrescu }
2859894c93e1SCristian Dumitrescu
286030c4abb9SCristian Dumitrescu struct pipeline_spec *
pipeline_spec_parse(FILE * spec,uint32_t * err_line,const char ** err_msg)286130c4abb9SCristian Dumitrescu pipeline_spec_parse(FILE *spec,
286299a2dd95SBruce Richardson uint32_t *err_line,
286399a2dd95SBruce Richardson const char **err_msg)
286499a2dd95SBruce Richardson {
286599a2dd95SBruce Richardson struct extobj_spec extobj_spec = {0};
286699a2dd95SBruce Richardson struct struct_spec struct_spec = {0};
286799a2dd95SBruce Richardson struct header_spec header_spec = {0};
286899a2dd95SBruce Richardson struct metadata_spec metadata_spec = {0};
286999a2dd95SBruce Richardson struct action_spec action_spec = {0};
287099a2dd95SBruce Richardson struct table_spec table_spec = {0};
2871cdaa937dSCristian Dumitrescu struct selector_spec selector_spec = {0};
28724f59d372SCristian Dumitrescu struct learner_spec learner_spec = {0};
287399a2dd95SBruce Richardson struct regarray_spec regarray_spec = {0};
287499a2dd95SBruce Richardson struct metarray_spec metarray_spec = {0};
28758ba342ceSCristian Dumitrescu struct rss_spec rss_spec = {0};
287699a2dd95SBruce Richardson struct apply_spec apply_spec = {0};
287730c4abb9SCristian Dumitrescu struct pipeline_spec *s = NULL;
287830c4abb9SCristian Dumitrescu uint32_t n_lines = 0;
287999a2dd95SBruce Richardson uint32_t block_mask = 0;
288030c4abb9SCristian Dumitrescu int status = 0;
288199a2dd95SBruce Richardson
288299a2dd95SBruce Richardson /* Check the input arguments. */
288330c4abb9SCristian Dumitrescu if (!spec) {
288499a2dd95SBruce Richardson if (err_line)
288530c4abb9SCristian Dumitrescu *err_line = n_lines;
288699a2dd95SBruce Richardson if (err_msg)
288730c4abb9SCristian Dumitrescu *err_msg = "Invalid input argument.";
288899a2dd95SBruce Richardson status = -EINVAL;
288999a2dd95SBruce Richardson goto error;
289099a2dd95SBruce Richardson }
289199a2dd95SBruce Richardson
289230c4abb9SCristian Dumitrescu /* Memory allocation. */
2893*0594ae0cSFerruh Yigit s = calloc(1, sizeof(struct pipeline_spec));
289430c4abb9SCristian Dumitrescu if (!s) {
289599a2dd95SBruce Richardson if (err_line)
289630c4abb9SCristian Dumitrescu *err_line = n_lines;
289799a2dd95SBruce Richardson if (err_msg)
289830c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
289930c4abb9SCristian Dumitrescu status = -ENOMEM;
290099a2dd95SBruce Richardson goto error;
290199a2dd95SBruce Richardson }
290299a2dd95SBruce Richardson
290399a2dd95SBruce Richardson for (n_lines = 1; ; n_lines++) {
290499a2dd95SBruce Richardson char line[MAX_LINE_LENGTH];
290599a2dd95SBruce Richardson char *tokens[MAX_TOKENS], *ptr = line;
290699a2dd95SBruce Richardson uint32_t n_tokens = 0;
290799a2dd95SBruce Richardson
290899a2dd95SBruce Richardson /* Read next line. */
290999a2dd95SBruce Richardson if (!fgets(line, sizeof(line), spec))
291099a2dd95SBruce Richardson break;
291199a2dd95SBruce Richardson
291299a2dd95SBruce Richardson /* Parse the line into tokens. */
291399a2dd95SBruce Richardson for ( ; ; ) {
291499a2dd95SBruce Richardson char *token;
291599a2dd95SBruce Richardson
291699a2dd95SBruce Richardson /* Get token. */
291799a2dd95SBruce Richardson token = strtok_r(ptr, " \f\n\r\t\v", &ptr);
291899a2dd95SBruce Richardson if (!token)
291999a2dd95SBruce Richardson break;
292099a2dd95SBruce Richardson
292199a2dd95SBruce Richardson /* Handle comments. */
292299a2dd95SBruce Richardson if ((token[0] == '#') ||
292399a2dd95SBruce Richardson (token[0] == ';') ||
292499a2dd95SBruce Richardson ((token[0] == '/') && (token[1] == '/'))) {
292599a2dd95SBruce Richardson break;
292699a2dd95SBruce Richardson }
292799a2dd95SBruce Richardson
292899a2dd95SBruce Richardson /* Handle excessively long lines. */
292973d94b00SCristian Dumitrescu if (n_tokens >= RTE_DIM(tokens)) {
293099a2dd95SBruce Richardson if (err_line)
293199a2dd95SBruce Richardson *err_line = n_lines;
293299a2dd95SBruce Richardson if (err_msg)
293399a2dd95SBruce Richardson *err_msg = "Too many tokens.";
293499a2dd95SBruce Richardson status = -EINVAL;
293599a2dd95SBruce Richardson goto error;
293699a2dd95SBruce Richardson }
293799a2dd95SBruce Richardson
293899a2dd95SBruce Richardson /* Handle excessively long tokens. */
293999a2dd95SBruce Richardson if (strnlen(token, RTE_SWX_NAME_SIZE) >=
294099a2dd95SBruce Richardson RTE_SWX_NAME_SIZE) {
294199a2dd95SBruce Richardson if (err_line)
294299a2dd95SBruce Richardson *err_line = n_lines;
294399a2dd95SBruce Richardson if (err_msg)
294499a2dd95SBruce Richardson *err_msg = "Token too big.";
294599a2dd95SBruce Richardson status = -EINVAL;
294699a2dd95SBruce Richardson goto error;
294799a2dd95SBruce Richardson }
294899a2dd95SBruce Richardson
294999a2dd95SBruce Richardson /* Save token. */
295099a2dd95SBruce Richardson tokens[n_tokens] = token;
295199a2dd95SBruce Richardson n_tokens++;
295299a2dd95SBruce Richardson }
295399a2dd95SBruce Richardson
295499a2dd95SBruce Richardson /* Handle empty lines. */
295599a2dd95SBruce Richardson if (!n_tokens)
295699a2dd95SBruce Richardson continue;
295799a2dd95SBruce Richardson
295899a2dd95SBruce Richardson /* struct block. */
295999a2dd95SBruce Richardson if (block_mask & (1 << STRUCT_BLOCK)) {
296030c4abb9SCristian Dumitrescu struct struct_spec *new_structs;
296130c4abb9SCristian Dumitrescu
296299a2dd95SBruce Richardson status = struct_block_parse(&struct_spec,
296399a2dd95SBruce Richardson &block_mask,
296499a2dd95SBruce Richardson tokens,
296599a2dd95SBruce Richardson n_tokens,
296699a2dd95SBruce Richardson n_lines,
296799a2dd95SBruce Richardson err_line,
296899a2dd95SBruce Richardson err_msg);
296999a2dd95SBruce Richardson if (status)
297099a2dd95SBruce Richardson goto error;
297199a2dd95SBruce Richardson
297299a2dd95SBruce Richardson if (block_mask & (1 << STRUCT_BLOCK))
297399a2dd95SBruce Richardson continue;
297499a2dd95SBruce Richardson
297599a2dd95SBruce Richardson /* End of block. */
297630c4abb9SCristian Dumitrescu new_structs = realloc(s->structs,
297730c4abb9SCristian Dumitrescu (s->n_structs + 1) * sizeof(struct struct_spec));
297830c4abb9SCristian Dumitrescu if (!new_structs) {
297999a2dd95SBruce Richardson if (err_line)
298099a2dd95SBruce Richardson *err_line = n_lines;
298199a2dd95SBruce Richardson if (err_msg)
298230c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
298330c4abb9SCristian Dumitrescu status = -ENOMEM;
298499a2dd95SBruce Richardson goto error;
298599a2dd95SBruce Richardson }
298699a2dd95SBruce Richardson
298730c4abb9SCristian Dumitrescu s->structs = new_structs;
298830c4abb9SCristian Dumitrescu memcpy(&s->structs[s->n_structs], &struct_spec, sizeof(struct struct_spec));
298930c4abb9SCristian Dumitrescu s->n_structs++;
299030c4abb9SCristian Dumitrescu memset(&struct_spec, 0, sizeof(struct struct_spec));
299199a2dd95SBruce Richardson
299299a2dd95SBruce Richardson continue;
299399a2dd95SBruce Richardson }
299499a2dd95SBruce Richardson
299599a2dd95SBruce Richardson /* action block. */
299699a2dd95SBruce Richardson if (block_mask & (1 << ACTION_BLOCK)) {
299730c4abb9SCristian Dumitrescu struct action_spec *new_actions;
299830c4abb9SCristian Dumitrescu
299999a2dd95SBruce Richardson status = action_block_parse(&action_spec,
300099a2dd95SBruce Richardson &block_mask,
300199a2dd95SBruce Richardson tokens,
300299a2dd95SBruce Richardson n_tokens,
300399a2dd95SBruce Richardson n_lines,
300499a2dd95SBruce Richardson err_line,
300599a2dd95SBruce Richardson err_msg);
300699a2dd95SBruce Richardson if (status)
300799a2dd95SBruce Richardson goto error;
300899a2dd95SBruce Richardson
300999a2dd95SBruce Richardson if (block_mask & (1 << ACTION_BLOCK))
301099a2dd95SBruce Richardson continue;
301199a2dd95SBruce Richardson
301299a2dd95SBruce Richardson /* End of block. */
301330c4abb9SCristian Dumitrescu new_actions = realloc(s->actions,
301430c4abb9SCristian Dumitrescu (s->n_actions + 1) * sizeof(struct action_spec));
301530c4abb9SCristian Dumitrescu if (!new_actions) {
301699a2dd95SBruce Richardson if (err_line)
301799a2dd95SBruce Richardson *err_line = n_lines;
301899a2dd95SBruce Richardson if (err_msg)
301930c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
302030c4abb9SCristian Dumitrescu status = -ENOMEM;
302199a2dd95SBruce Richardson goto error;
302299a2dd95SBruce Richardson }
302399a2dd95SBruce Richardson
302430c4abb9SCristian Dumitrescu s->actions = new_actions;
302530c4abb9SCristian Dumitrescu memcpy(&s->actions[s->n_actions], &action_spec, sizeof(struct action_spec));
302630c4abb9SCristian Dumitrescu s->n_actions++;
302730c4abb9SCristian Dumitrescu memset(&action_spec, 0, sizeof(struct action_spec));
302899a2dd95SBruce Richardson
302999a2dd95SBruce Richardson continue;
303099a2dd95SBruce Richardson }
303199a2dd95SBruce Richardson
303299a2dd95SBruce Richardson /* table block. */
303399a2dd95SBruce Richardson if (block_mask & (1 << TABLE_BLOCK)) {
303430c4abb9SCristian Dumitrescu struct table_spec *new_tables;
303530c4abb9SCristian Dumitrescu
303699a2dd95SBruce Richardson status = table_block_parse(&table_spec,
303799a2dd95SBruce Richardson &block_mask,
303899a2dd95SBruce Richardson tokens,
303999a2dd95SBruce Richardson n_tokens,
304099a2dd95SBruce Richardson n_lines,
304199a2dd95SBruce Richardson err_line,
304299a2dd95SBruce Richardson err_msg);
304399a2dd95SBruce Richardson if (status)
304499a2dd95SBruce Richardson goto error;
304599a2dd95SBruce Richardson
304699a2dd95SBruce Richardson if (block_mask & (1 << TABLE_BLOCK))
304799a2dd95SBruce Richardson continue;
304899a2dd95SBruce Richardson
304999a2dd95SBruce Richardson /* End of block. */
305030c4abb9SCristian Dumitrescu new_tables = realloc(s->tables,
305130c4abb9SCristian Dumitrescu (s->n_tables + 1) * sizeof(struct table_spec));
305230c4abb9SCristian Dumitrescu if (!new_tables) {
305399a2dd95SBruce Richardson if (err_line)
305499a2dd95SBruce Richardson *err_line = n_lines;
305599a2dd95SBruce Richardson if (err_msg)
305630c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
305730c4abb9SCristian Dumitrescu status = -ENOMEM;
305899a2dd95SBruce Richardson goto error;
305999a2dd95SBruce Richardson }
306099a2dd95SBruce Richardson
306130c4abb9SCristian Dumitrescu s->tables = new_tables;
306230c4abb9SCristian Dumitrescu memcpy(&s->tables[s->n_tables], &table_spec, sizeof(struct table_spec));
306330c4abb9SCristian Dumitrescu s->n_tables++;
306430c4abb9SCristian Dumitrescu memset(&table_spec, 0, sizeof(struct table_spec));
306599a2dd95SBruce Richardson
306699a2dd95SBruce Richardson continue;
306799a2dd95SBruce Richardson }
306899a2dd95SBruce Richardson
3069cdaa937dSCristian Dumitrescu /* selector block. */
3070cdaa937dSCristian Dumitrescu if (block_mask & (1 << SELECTOR_BLOCK)) {
307130c4abb9SCristian Dumitrescu struct selector_spec *new_selectors;
307230c4abb9SCristian Dumitrescu
3073cdaa937dSCristian Dumitrescu status = selector_block_parse(&selector_spec,
3074cdaa937dSCristian Dumitrescu &block_mask,
3075cdaa937dSCristian Dumitrescu tokens,
3076cdaa937dSCristian Dumitrescu n_tokens,
3077cdaa937dSCristian Dumitrescu n_lines,
3078cdaa937dSCristian Dumitrescu err_line,
3079cdaa937dSCristian Dumitrescu err_msg);
3080cdaa937dSCristian Dumitrescu if (status)
3081cdaa937dSCristian Dumitrescu goto error;
3082cdaa937dSCristian Dumitrescu
3083cdaa937dSCristian Dumitrescu if (block_mask & (1 << SELECTOR_BLOCK))
3084cdaa937dSCristian Dumitrescu continue;
3085cdaa937dSCristian Dumitrescu
3086cdaa937dSCristian Dumitrescu /* End of block. */
308730c4abb9SCristian Dumitrescu new_selectors = realloc(s->selectors,
308830c4abb9SCristian Dumitrescu (s->n_selectors + 1) * sizeof(struct selector_spec));
308930c4abb9SCristian Dumitrescu if (!new_selectors) {
3090cdaa937dSCristian Dumitrescu if (err_line)
3091cdaa937dSCristian Dumitrescu *err_line = n_lines;
3092cdaa937dSCristian Dumitrescu if (err_msg)
309330c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
309430c4abb9SCristian Dumitrescu status = -ENOMEM;
3095cdaa937dSCristian Dumitrescu goto error;
3096cdaa937dSCristian Dumitrescu }
3097cdaa937dSCristian Dumitrescu
309830c4abb9SCristian Dumitrescu s->selectors = new_selectors;
309930c4abb9SCristian Dumitrescu memcpy(&s->selectors[s->n_selectors],
310030c4abb9SCristian Dumitrescu &selector_spec,
310130c4abb9SCristian Dumitrescu sizeof(struct selector_spec));
310230c4abb9SCristian Dumitrescu s->n_selectors++;
310330c4abb9SCristian Dumitrescu memset(&selector_spec, 0, sizeof(struct selector_spec));
3104cdaa937dSCristian Dumitrescu
3105cdaa937dSCristian Dumitrescu continue;
3106cdaa937dSCristian Dumitrescu }
3107cdaa937dSCristian Dumitrescu
31084f59d372SCristian Dumitrescu /* learner block. */
31094f59d372SCristian Dumitrescu if (block_mask & (1 << LEARNER_BLOCK)) {
311030c4abb9SCristian Dumitrescu struct learner_spec *new_learners;
311130c4abb9SCristian Dumitrescu
31124f59d372SCristian Dumitrescu status = learner_block_parse(&learner_spec,
31134f59d372SCristian Dumitrescu &block_mask,
31144f59d372SCristian Dumitrescu tokens,
31154f59d372SCristian Dumitrescu n_tokens,
31164f59d372SCristian Dumitrescu n_lines,
31174f59d372SCristian Dumitrescu err_line,
31184f59d372SCristian Dumitrescu err_msg);
31194f59d372SCristian Dumitrescu if (status)
31204f59d372SCristian Dumitrescu goto error;
31214f59d372SCristian Dumitrescu
31224f59d372SCristian Dumitrescu if (block_mask & (1 << LEARNER_BLOCK))
31234f59d372SCristian Dumitrescu continue;
31244f59d372SCristian Dumitrescu
31254f59d372SCristian Dumitrescu /* End of block. */
312630c4abb9SCristian Dumitrescu new_learners = realloc(s->learners,
312730c4abb9SCristian Dumitrescu (s->n_learners + 1) * sizeof(struct learner_spec));
312830c4abb9SCristian Dumitrescu if (!new_learners) {
31294f59d372SCristian Dumitrescu if (err_line)
31304f59d372SCristian Dumitrescu *err_line = n_lines;
31314f59d372SCristian Dumitrescu if (err_msg)
313230c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
313330c4abb9SCristian Dumitrescu status = -ENOMEM;
31344f59d372SCristian Dumitrescu goto error;
31354f59d372SCristian Dumitrescu }
31364f59d372SCristian Dumitrescu
313730c4abb9SCristian Dumitrescu s->learners = new_learners;
313830c4abb9SCristian Dumitrescu memcpy(&s->learners[s->n_learners],
313930c4abb9SCristian Dumitrescu &learner_spec,
314030c4abb9SCristian Dumitrescu sizeof(struct learner_spec));
314130c4abb9SCristian Dumitrescu s->n_learners++;
314230c4abb9SCristian Dumitrescu memset(&learner_spec, 0, sizeof(struct learner_spec));
31434f59d372SCristian Dumitrescu
31444f59d372SCristian Dumitrescu continue;
31454f59d372SCristian Dumitrescu }
31464f59d372SCristian Dumitrescu
314799a2dd95SBruce Richardson /* apply block. */
314899a2dd95SBruce Richardson if (block_mask & (1 << APPLY_BLOCK)) {
314930c4abb9SCristian Dumitrescu struct apply_spec *new_apply;
315030c4abb9SCristian Dumitrescu
315199a2dd95SBruce Richardson status = apply_block_parse(&apply_spec,
315299a2dd95SBruce Richardson &block_mask,
315399a2dd95SBruce Richardson tokens,
315499a2dd95SBruce Richardson n_tokens,
315599a2dd95SBruce Richardson n_lines,
315699a2dd95SBruce Richardson err_line,
315799a2dd95SBruce Richardson err_msg);
315899a2dd95SBruce Richardson if (status)
315999a2dd95SBruce Richardson goto error;
316099a2dd95SBruce Richardson
316199a2dd95SBruce Richardson if (block_mask & (1 << APPLY_BLOCK))
316299a2dd95SBruce Richardson continue;
316399a2dd95SBruce Richardson
316499a2dd95SBruce Richardson /* End of block. */
316530c4abb9SCristian Dumitrescu new_apply = realloc(s->apply, (s->n_apply + 1) * sizeof(struct apply_spec));
316630c4abb9SCristian Dumitrescu if (!new_apply) {
316799a2dd95SBruce Richardson if (err_line)
316899a2dd95SBruce Richardson *err_line = n_lines;
316999a2dd95SBruce Richardson if (err_msg)
317030c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
317130c4abb9SCristian Dumitrescu status = -ENOMEM;
317299a2dd95SBruce Richardson goto error;
317399a2dd95SBruce Richardson }
317499a2dd95SBruce Richardson
317530c4abb9SCristian Dumitrescu s->apply = new_apply;
317630c4abb9SCristian Dumitrescu memcpy(&s->apply[s->n_apply], &apply_spec, sizeof(struct apply_spec));
317730c4abb9SCristian Dumitrescu s->n_apply++;
317830c4abb9SCristian Dumitrescu memset(&apply_spec, 0, sizeof(struct apply_spec));
317999a2dd95SBruce Richardson
318099a2dd95SBruce Richardson continue;
318199a2dd95SBruce Richardson }
318299a2dd95SBruce Richardson
318399a2dd95SBruce Richardson /* extobj. */
318499a2dd95SBruce Richardson if (!strcmp(tokens[0], "extobj")) {
318530c4abb9SCristian Dumitrescu struct extobj_spec *new_extobjs;
318630c4abb9SCristian Dumitrescu
318799a2dd95SBruce Richardson status = extobj_statement_parse(&extobj_spec,
318899a2dd95SBruce Richardson tokens,
318999a2dd95SBruce Richardson n_tokens,
319099a2dd95SBruce Richardson n_lines,
319199a2dd95SBruce Richardson err_line,
319299a2dd95SBruce Richardson err_msg);
319399a2dd95SBruce Richardson if (status)
319499a2dd95SBruce Richardson goto error;
319599a2dd95SBruce Richardson
319630c4abb9SCristian Dumitrescu new_extobjs = realloc(s->extobjs,
319730c4abb9SCristian Dumitrescu (s->n_extobjs + 1) * sizeof(struct extobj_spec));
319830c4abb9SCristian Dumitrescu if (!new_extobjs) {
319999a2dd95SBruce Richardson if (err_line)
320099a2dd95SBruce Richardson *err_line = n_lines;
320199a2dd95SBruce Richardson if (err_msg)
320230c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
320330c4abb9SCristian Dumitrescu status = -ENOMEM;
320499a2dd95SBruce Richardson goto error;
320599a2dd95SBruce Richardson }
320699a2dd95SBruce Richardson
320730c4abb9SCristian Dumitrescu s->extobjs = new_extobjs;
320830c4abb9SCristian Dumitrescu memcpy(&s->extobjs[s->n_extobjs], &extobj_spec, sizeof(struct extobj_spec));
320930c4abb9SCristian Dumitrescu s->n_extobjs++;
321030c4abb9SCristian Dumitrescu memset(&extobj_spec, 0, sizeof(struct extobj_spec));
321199a2dd95SBruce Richardson
321299a2dd95SBruce Richardson continue;
321399a2dd95SBruce Richardson }
321499a2dd95SBruce Richardson
321599a2dd95SBruce Richardson /* struct. */
321699a2dd95SBruce Richardson if (!strcmp(tokens[0], "struct")) {
321799a2dd95SBruce Richardson status = struct_statement_parse(&struct_spec,
321899a2dd95SBruce Richardson &block_mask,
321999a2dd95SBruce Richardson tokens,
322099a2dd95SBruce Richardson n_tokens,
322199a2dd95SBruce Richardson n_lines,
322299a2dd95SBruce Richardson err_line,
322399a2dd95SBruce Richardson err_msg);
322499a2dd95SBruce Richardson if (status)
322599a2dd95SBruce Richardson goto error;
322699a2dd95SBruce Richardson
322799a2dd95SBruce Richardson continue;
322899a2dd95SBruce Richardson }
322999a2dd95SBruce Richardson
323099a2dd95SBruce Richardson /* header. */
323199a2dd95SBruce Richardson if (!strcmp(tokens[0], "header")) {
323230c4abb9SCristian Dumitrescu struct header_spec *new_headers;
323330c4abb9SCristian Dumitrescu
323499a2dd95SBruce Richardson status = header_statement_parse(&header_spec,
323599a2dd95SBruce Richardson tokens,
323699a2dd95SBruce Richardson n_tokens,
323799a2dd95SBruce Richardson n_lines,
323899a2dd95SBruce Richardson err_line,
323999a2dd95SBruce Richardson err_msg);
324099a2dd95SBruce Richardson if (status)
324199a2dd95SBruce Richardson goto error;
324299a2dd95SBruce Richardson
324330c4abb9SCristian Dumitrescu new_headers = realloc(s->headers,
324430c4abb9SCristian Dumitrescu (s->n_headers + 1) * sizeof(struct header_spec));
324530c4abb9SCristian Dumitrescu if (!new_headers) {
324699a2dd95SBruce Richardson if (err_line)
324799a2dd95SBruce Richardson *err_line = n_lines;
324899a2dd95SBruce Richardson if (err_msg)
324930c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
325030c4abb9SCristian Dumitrescu status = -ENOMEM;
325199a2dd95SBruce Richardson goto error;
325299a2dd95SBruce Richardson }
325399a2dd95SBruce Richardson
325430c4abb9SCristian Dumitrescu s->headers = new_headers;
325530c4abb9SCristian Dumitrescu memcpy(&s->headers[s->n_headers], &header_spec, sizeof(struct header_spec));
325630c4abb9SCristian Dumitrescu s->n_headers++;
325730c4abb9SCristian Dumitrescu memset(&header_spec, 0, sizeof(struct header_spec));
325899a2dd95SBruce Richardson
325999a2dd95SBruce Richardson continue;
326099a2dd95SBruce Richardson }
326199a2dd95SBruce Richardson
326299a2dd95SBruce Richardson /* metadata. */
326399a2dd95SBruce Richardson if (!strcmp(tokens[0], "metadata")) {
326430c4abb9SCristian Dumitrescu struct metadata_spec *new_metadata;
326530c4abb9SCristian Dumitrescu
326699a2dd95SBruce Richardson status = metadata_statement_parse(&metadata_spec,
326799a2dd95SBruce Richardson tokens,
326899a2dd95SBruce Richardson n_tokens,
326999a2dd95SBruce Richardson n_lines,
327099a2dd95SBruce Richardson err_line,
327199a2dd95SBruce Richardson err_msg);
327299a2dd95SBruce Richardson if (status)
327399a2dd95SBruce Richardson goto error;
327499a2dd95SBruce Richardson
327530c4abb9SCristian Dumitrescu new_metadata = realloc(s->metadata,
327630c4abb9SCristian Dumitrescu (s->n_metadata + 1) * sizeof(struct metadata_spec));
327730c4abb9SCristian Dumitrescu if (!new_metadata) {
327899a2dd95SBruce Richardson if (err_line)
327999a2dd95SBruce Richardson *err_line = n_lines;
328099a2dd95SBruce Richardson if (err_msg)
328130c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
328230c4abb9SCristian Dumitrescu status = -ENOMEM;
328399a2dd95SBruce Richardson goto error;
328499a2dd95SBruce Richardson }
328599a2dd95SBruce Richardson
328630c4abb9SCristian Dumitrescu s->metadata = new_metadata;
328730c4abb9SCristian Dumitrescu memcpy(&s->metadata[s->n_metadata],
328830c4abb9SCristian Dumitrescu &metadata_spec,
328930c4abb9SCristian Dumitrescu sizeof(struct metadata_spec));
329030c4abb9SCristian Dumitrescu s->n_metadata++;
329130c4abb9SCristian Dumitrescu memset(&metadata_spec, 0, sizeof(struct metadata_spec));
329299a2dd95SBruce Richardson
329399a2dd95SBruce Richardson continue;
329499a2dd95SBruce Richardson }
329599a2dd95SBruce Richardson
329699a2dd95SBruce Richardson /* action. */
329799a2dd95SBruce Richardson if (!strcmp(tokens[0], "action")) {
329899a2dd95SBruce Richardson status = action_statement_parse(&action_spec,
329999a2dd95SBruce Richardson &block_mask,
330099a2dd95SBruce Richardson tokens,
330199a2dd95SBruce Richardson n_tokens,
330299a2dd95SBruce Richardson n_lines,
330399a2dd95SBruce Richardson err_line,
330499a2dd95SBruce Richardson err_msg);
330599a2dd95SBruce Richardson if (status)
330699a2dd95SBruce Richardson goto error;
330799a2dd95SBruce Richardson
330899a2dd95SBruce Richardson continue;
330999a2dd95SBruce Richardson }
331099a2dd95SBruce Richardson
331199a2dd95SBruce Richardson /* table. */
331299a2dd95SBruce Richardson if (!strcmp(tokens[0], "table")) {
331399a2dd95SBruce Richardson status = table_statement_parse(&table_spec,
331499a2dd95SBruce Richardson &block_mask,
331599a2dd95SBruce Richardson tokens,
331699a2dd95SBruce Richardson n_tokens,
331799a2dd95SBruce Richardson n_lines,
331899a2dd95SBruce Richardson err_line,
331999a2dd95SBruce Richardson err_msg);
332099a2dd95SBruce Richardson if (status)
332199a2dd95SBruce Richardson goto error;
332299a2dd95SBruce Richardson
332399a2dd95SBruce Richardson continue;
332499a2dd95SBruce Richardson }
332599a2dd95SBruce Richardson
3326cdaa937dSCristian Dumitrescu /* selector. */
3327cdaa937dSCristian Dumitrescu if (!strcmp(tokens[0], "selector")) {
3328cdaa937dSCristian Dumitrescu status = selector_statement_parse(&selector_spec,
3329cdaa937dSCristian Dumitrescu &block_mask,
3330cdaa937dSCristian Dumitrescu tokens,
3331cdaa937dSCristian Dumitrescu n_tokens,
3332cdaa937dSCristian Dumitrescu n_lines,
3333cdaa937dSCristian Dumitrescu err_line,
3334cdaa937dSCristian Dumitrescu err_msg);
3335cdaa937dSCristian Dumitrescu if (status)
3336cdaa937dSCristian Dumitrescu goto error;
3337cdaa937dSCristian Dumitrescu
3338cdaa937dSCristian Dumitrescu continue;
3339cdaa937dSCristian Dumitrescu }
3340cdaa937dSCristian Dumitrescu
33414f59d372SCristian Dumitrescu /* learner. */
33424f59d372SCristian Dumitrescu if (!strcmp(tokens[0], "learner")) {
33434f59d372SCristian Dumitrescu status = learner_statement_parse(&learner_spec,
33444f59d372SCristian Dumitrescu &block_mask,
33454f59d372SCristian Dumitrescu tokens,
33464f59d372SCristian Dumitrescu n_tokens,
33474f59d372SCristian Dumitrescu n_lines,
33484f59d372SCristian Dumitrescu err_line,
33494f59d372SCristian Dumitrescu err_msg);
33504f59d372SCristian Dumitrescu if (status)
33514f59d372SCristian Dumitrescu goto error;
33524f59d372SCristian Dumitrescu
33534f59d372SCristian Dumitrescu continue;
33544f59d372SCristian Dumitrescu }
33554f59d372SCristian Dumitrescu
335699a2dd95SBruce Richardson /* regarray. */
335799a2dd95SBruce Richardson if (!strcmp(tokens[0], "regarray")) {
335830c4abb9SCristian Dumitrescu struct regarray_spec *new_regarrays;
335930c4abb9SCristian Dumitrescu
336099a2dd95SBruce Richardson status = regarray_statement_parse(®array_spec,
336199a2dd95SBruce Richardson tokens,
336299a2dd95SBruce Richardson n_tokens,
336399a2dd95SBruce Richardson n_lines,
336499a2dd95SBruce Richardson err_line,
336599a2dd95SBruce Richardson err_msg);
336699a2dd95SBruce Richardson if (status)
336799a2dd95SBruce Richardson goto error;
336899a2dd95SBruce Richardson
336930c4abb9SCristian Dumitrescu new_regarrays = realloc(s->regarrays,
337030c4abb9SCristian Dumitrescu (s->n_regarrays + 1) * sizeof(struct regarray_spec));
337130c4abb9SCristian Dumitrescu if (!new_regarrays) {
337299a2dd95SBruce Richardson if (err_line)
337399a2dd95SBruce Richardson *err_line = n_lines;
337499a2dd95SBruce Richardson if (err_msg)
337530c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
337630c4abb9SCristian Dumitrescu status = -ENOMEM;
337799a2dd95SBruce Richardson goto error;
337899a2dd95SBruce Richardson }
337999a2dd95SBruce Richardson
338030c4abb9SCristian Dumitrescu s->regarrays = new_regarrays;
338130c4abb9SCristian Dumitrescu memcpy(&s->regarrays[s->n_regarrays],
338230c4abb9SCristian Dumitrescu ®array_spec,
338330c4abb9SCristian Dumitrescu sizeof(struct regarray_spec));
338430c4abb9SCristian Dumitrescu s->n_regarrays++;
338530c4abb9SCristian Dumitrescu memset(®array_spec, 0, sizeof(struct regarray_spec));
338699a2dd95SBruce Richardson
338799a2dd95SBruce Richardson continue;
338899a2dd95SBruce Richardson }
338999a2dd95SBruce Richardson
339099a2dd95SBruce Richardson /* metarray. */
339199a2dd95SBruce Richardson if (!strcmp(tokens[0], "metarray")) {
339230c4abb9SCristian Dumitrescu struct metarray_spec *new_metarrays;
339330c4abb9SCristian Dumitrescu
339499a2dd95SBruce Richardson status = metarray_statement_parse(&metarray_spec,
339599a2dd95SBruce Richardson tokens,
339699a2dd95SBruce Richardson n_tokens,
339799a2dd95SBruce Richardson n_lines,
339899a2dd95SBruce Richardson err_line,
339999a2dd95SBruce Richardson err_msg);
340099a2dd95SBruce Richardson if (status)
340199a2dd95SBruce Richardson goto error;
340299a2dd95SBruce Richardson
340330c4abb9SCristian Dumitrescu new_metarrays = realloc(s->metarrays,
340430c4abb9SCristian Dumitrescu (s->n_metarrays + 1) * sizeof(struct metarray_spec));
340530c4abb9SCristian Dumitrescu if (!new_metarrays) {
340699a2dd95SBruce Richardson if (err_line)
340799a2dd95SBruce Richardson *err_line = n_lines;
340899a2dd95SBruce Richardson if (err_msg)
340930c4abb9SCristian Dumitrescu *err_msg = "Memory allocation failed.";
341030c4abb9SCristian Dumitrescu status = -ENOMEM;
341199a2dd95SBruce Richardson goto error;
341299a2dd95SBruce Richardson }
341399a2dd95SBruce Richardson
341430c4abb9SCristian Dumitrescu s->metarrays = new_metarrays;
341530c4abb9SCristian Dumitrescu memcpy(&s->metarrays[s->n_metarrays],
341630c4abb9SCristian Dumitrescu &metarray_spec,
341730c4abb9SCristian Dumitrescu sizeof(struct metarray_spec));
341830c4abb9SCristian Dumitrescu s->n_metarrays++;
341930c4abb9SCristian Dumitrescu memset(&metarray_spec, 0, sizeof(struct metarray_spec));
342099a2dd95SBruce Richardson
342199a2dd95SBruce Richardson continue;
342299a2dd95SBruce Richardson }
342399a2dd95SBruce Richardson
34248ba342ceSCristian Dumitrescu /* rss object configuration */
34258ba342ceSCristian Dumitrescu if (!strcmp(tokens[0], "rss")) {
34268ba342ceSCristian Dumitrescu struct rss_spec *new_rss;
34278ba342ceSCristian Dumitrescu
34288ba342ceSCristian Dumitrescu status = rss_statement_parse(&rss_spec,
34298ba342ceSCristian Dumitrescu tokens,
34308ba342ceSCristian Dumitrescu n_tokens,
34318ba342ceSCristian Dumitrescu n_lines,
34328ba342ceSCristian Dumitrescu err_line,
34338ba342ceSCristian Dumitrescu err_msg);
34348ba342ceSCristian Dumitrescu if (status)
34358ba342ceSCristian Dumitrescu goto error;
34368ba342ceSCristian Dumitrescu
34378ba342ceSCristian Dumitrescu new_rss = realloc(s->rss,
34388ba342ceSCristian Dumitrescu (s->n_rss + 1) * sizeof(struct rss_spec));
34398ba342ceSCristian Dumitrescu if (!new_rss) {
34408ba342ceSCristian Dumitrescu if (err_line)
34418ba342ceSCristian Dumitrescu *err_line = n_lines;
34428ba342ceSCristian Dumitrescu if (err_msg)
34438ba342ceSCristian Dumitrescu *err_msg = "Memory allocation failed.";
34448ba342ceSCristian Dumitrescu status = -ENOMEM;
34458ba342ceSCristian Dumitrescu goto error;
34468ba342ceSCristian Dumitrescu }
34478ba342ceSCristian Dumitrescu
34488ba342ceSCristian Dumitrescu s->rss = new_rss;
34498ba342ceSCristian Dumitrescu memcpy(&s->rss[s->n_rss],
34508ba342ceSCristian Dumitrescu &rss_spec,
34518ba342ceSCristian Dumitrescu sizeof(struct rss_spec));
34528ba342ceSCristian Dumitrescu s->n_rss++;
34538ba342ceSCristian Dumitrescu memset(&rss_spec, 0, sizeof(struct rss_spec));
34548ba342ceSCristian Dumitrescu
34558ba342ceSCristian Dumitrescu continue;
34568ba342ceSCristian Dumitrescu }
34578ba342ceSCristian Dumitrescu
345899a2dd95SBruce Richardson /* apply. */
345999a2dd95SBruce Richardson if (!strcmp(tokens[0], "apply")) {
346099a2dd95SBruce Richardson status = apply_statement_parse(&block_mask,
346199a2dd95SBruce Richardson tokens,
346299a2dd95SBruce Richardson n_tokens,
346399a2dd95SBruce Richardson n_lines,
346499a2dd95SBruce Richardson err_line,
346599a2dd95SBruce Richardson err_msg);
346699a2dd95SBruce Richardson if (status)
346799a2dd95SBruce Richardson goto error;
346899a2dd95SBruce Richardson
346999a2dd95SBruce Richardson continue;
347099a2dd95SBruce Richardson }
347199a2dd95SBruce Richardson
347299a2dd95SBruce Richardson /* Anything else. */
347399a2dd95SBruce Richardson if (err_line)
347499a2dd95SBruce Richardson *err_line = n_lines;
347599a2dd95SBruce Richardson if (err_msg)
347699a2dd95SBruce Richardson *err_msg = "Unknown statement.";
347799a2dd95SBruce Richardson status = -EINVAL;
347899a2dd95SBruce Richardson goto error;
347999a2dd95SBruce Richardson }
348099a2dd95SBruce Richardson
348199a2dd95SBruce Richardson /* Handle unfinished block. */
348299a2dd95SBruce Richardson if (block_mask) {
348399a2dd95SBruce Richardson if (err_line)
348499a2dd95SBruce Richardson *err_line = n_lines;
348599a2dd95SBruce Richardson if (err_msg)
348699a2dd95SBruce Richardson *err_msg = "Missing }.";
348799a2dd95SBruce Richardson status = -EINVAL;
348899a2dd95SBruce Richardson goto error;
348999a2dd95SBruce Richardson }
349099a2dd95SBruce Richardson
349130c4abb9SCristian Dumitrescu return s;
349299a2dd95SBruce Richardson
349399a2dd95SBruce Richardson error:
349499a2dd95SBruce Richardson extobj_spec_free(&extobj_spec);
349599a2dd95SBruce Richardson struct_spec_free(&struct_spec);
349699a2dd95SBruce Richardson header_spec_free(&header_spec);
349799a2dd95SBruce Richardson metadata_spec_free(&metadata_spec);
349899a2dd95SBruce Richardson action_spec_free(&action_spec);
349999a2dd95SBruce Richardson table_spec_free(&table_spec);
3500cdaa937dSCristian Dumitrescu selector_spec_free(&selector_spec);
35014f59d372SCristian Dumitrescu learner_spec_free(&learner_spec);
350299a2dd95SBruce Richardson regarray_spec_free(®array_spec);
350399a2dd95SBruce Richardson metarray_spec_free(&metarray_spec);
35048ba342ceSCristian Dumitrescu rss_spec_free(&rss_spec);
350599a2dd95SBruce Richardson apply_spec_free(&apply_spec);
350630c4abb9SCristian Dumitrescu pipeline_spec_free(s);
350730c4abb9SCristian Dumitrescu
350830c4abb9SCristian Dumitrescu return NULL;
350930c4abb9SCristian Dumitrescu }
351030c4abb9SCristian Dumitrescu
351130c4abb9SCristian Dumitrescu int
pipeline_spec_configure(struct rte_swx_pipeline * p,struct pipeline_spec * s,const char ** err_msg)351230c4abb9SCristian Dumitrescu pipeline_spec_configure(struct rte_swx_pipeline *p,
351330c4abb9SCristian Dumitrescu struct pipeline_spec *s,
351430c4abb9SCristian Dumitrescu const char **err_msg)
351530c4abb9SCristian Dumitrescu {
351630c4abb9SCristian Dumitrescu uint32_t i;
351730c4abb9SCristian Dumitrescu int status = 0;
351830c4abb9SCristian Dumitrescu
351930c4abb9SCristian Dumitrescu /* extobj. */
352030c4abb9SCristian Dumitrescu for (i = 0; i < s->n_extobjs; i++) {
352130c4abb9SCristian Dumitrescu struct extobj_spec *extobj_spec = &s->extobjs[i];
352230c4abb9SCristian Dumitrescu
352330c4abb9SCristian Dumitrescu status = rte_swx_pipeline_extern_object_config(p,
352430c4abb9SCristian Dumitrescu extobj_spec->name,
352530c4abb9SCristian Dumitrescu extobj_spec->extern_type_name,
352630c4abb9SCristian Dumitrescu extobj_spec->pragma);
352730c4abb9SCristian Dumitrescu if (status) {
352830c4abb9SCristian Dumitrescu if (err_msg)
352930c4abb9SCristian Dumitrescu *err_msg = "Extern object configuration error.";
353030c4abb9SCristian Dumitrescu return status;
353130c4abb9SCristian Dumitrescu }
353230c4abb9SCristian Dumitrescu }
353330c4abb9SCristian Dumitrescu
353430c4abb9SCristian Dumitrescu /* regarray. */
353530c4abb9SCristian Dumitrescu for (i = 0; i < s->n_regarrays; i++) {
353630c4abb9SCristian Dumitrescu struct regarray_spec *regarray_spec = &s->regarrays[i];
353730c4abb9SCristian Dumitrescu
353830c4abb9SCristian Dumitrescu status = rte_swx_pipeline_regarray_config(p,
353930c4abb9SCristian Dumitrescu regarray_spec->name,
354030c4abb9SCristian Dumitrescu regarray_spec->size,
354130c4abb9SCristian Dumitrescu regarray_spec->init_val);
354230c4abb9SCristian Dumitrescu if (status) {
354330c4abb9SCristian Dumitrescu if (err_msg)
354430c4abb9SCristian Dumitrescu *err_msg = "Register array configuration error.";
354530c4abb9SCristian Dumitrescu return status;
354630c4abb9SCristian Dumitrescu }
354730c4abb9SCristian Dumitrescu }
354830c4abb9SCristian Dumitrescu
35492cd7722aSYogesh Jangra /* rss. */
35502cd7722aSYogesh Jangra for (i = 0; i < s->n_rss; i++) {
35512cd7722aSYogesh Jangra struct rss_spec *rss_spec = &s->rss[i];
35522cd7722aSYogesh Jangra
35532cd7722aSYogesh Jangra status = rte_swx_pipeline_rss_config(p, rss_spec->name);
35542cd7722aSYogesh Jangra if (status) {
35552cd7722aSYogesh Jangra if (err_msg)
35562cd7722aSYogesh Jangra *err_msg = "rss object configuration error.";
35572cd7722aSYogesh Jangra return status;
35582cd7722aSYogesh Jangra }
35592cd7722aSYogesh Jangra }
35602cd7722aSYogesh Jangra
356130c4abb9SCristian Dumitrescu /* metarray. */
356230c4abb9SCristian Dumitrescu for (i = 0; i < s->n_metarrays; i++) {
356330c4abb9SCristian Dumitrescu struct metarray_spec *metarray_spec = &s->metarrays[i];
356430c4abb9SCristian Dumitrescu
356530c4abb9SCristian Dumitrescu status = rte_swx_pipeline_metarray_config(p,
356630c4abb9SCristian Dumitrescu metarray_spec->name,
356730c4abb9SCristian Dumitrescu metarray_spec->size);
356830c4abb9SCristian Dumitrescu if (status) {
356930c4abb9SCristian Dumitrescu if (err_msg)
357030c4abb9SCristian Dumitrescu *err_msg = "Meter array configuration error.";
357130c4abb9SCristian Dumitrescu return status;
357230c4abb9SCristian Dumitrescu }
357330c4abb9SCristian Dumitrescu }
357430c4abb9SCristian Dumitrescu
357530c4abb9SCristian Dumitrescu /* struct. */
357630c4abb9SCristian Dumitrescu for (i = 0; i < s->n_structs; i++) {
357730c4abb9SCristian Dumitrescu struct struct_spec *struct_spec = &s->structs[i];
357830c4abb9SCristian Dumitrescu
357930c4abb9SCristian Dumitrescu status = rte_swx_pipeline_struct_type_register(p,
358030c4abb9SCristian Dumitrescu struct_spec->name,
358130c4abb9SCristian Dumitrescu struct_spec->fields,
358230c4abb9SCristian Dumitrescu struct_spec->n_fields,
358330c4abb9SCristian Dumitrescu struct_spec->varbit);
358430c4abb9SCristian Dumitrescu if (status) {
358530c4abb9SCristian Dumitrescu if (err_msg)
358630c4abb9SCristian Dumitrescu *err_msg = "Struct type registration error.";
358730c4abb9SCristian Dumitrescu return status;
358830c4abb9SCristian Dumitrescu }
358930c4abb9SCristian Dumitrescu }
359030c4abb9SCristian Dumitrescu
359130c4abb9SCristian Dumitrescu /* header. */
359230c4abb9SCristian Dumitrescu for (i = 0; i < s->n_headers; i++) {
359330c4abb9SCristian Dumitrescu struct header_spec *header_spec = &s->headers[i];
359430c4abb9SCristian Dumitrescu
359530c4abb9SCristian Dumitrescu status = rte_swx_pipeline_packet_header_register(p,
359630c4abb9SCristian Dumitrescu header_spec->name,
359730c4abb9SCristian Dumitrescu header_spec->struct_type_name);
359830c4abb9SCristian Dumitrescu if (status) {
359930c4abb9SCristian Dumitrescu if (err_msg)
360030c4abb9SCristian Dumitrescu *err_msg = "Header configuration error.";
360130c4abb9SCristian Dumitrescu return status;
360230c4abb9SCristian Dumitrescu }
360330c4abb9SCristian Dumitrescu }
360430c4abb9SCristian Dumitrescu
360530c4abb9SCristian Dumitrescu /* metadata. */
360630c4abb9SCristian Dumitrescu for (i = 0; i < s->n_metadata; i++) {
360730c4abb9SCristian Dumitrescu struct metadata_spec *metadata_spec = &s->metadata[i];
360830c4abb9SCristian Dumitrescu
360930c4abb9SCristian Dumitrescu status = rte_swx_pipeline_packet_metadata_register(p,
361030c4abb9SCristian Dumitrescu metadata_spec->struct_type_name);
361130c4abb9SCristian Dumitrescu if (status) {
361230c4abb9SCristian Dumitrescu if (err_msg)
361330c4abb9SCristian Dumitrescu *err_msg = "Meta-data registration error.";
361430c4abb9SCristian Dumitrescu return status;
361530c4abb9SCristian Dumitrescu }
361630c4abb9SCristian Dumitrescu }
361730c4abb9SCristian Dumitrescu
361830c4abb9SCristian Dumitrescu /* action. */
361930c4abb9SCristian Dumitrescu for (i = 0; i < s->n_actions; i++) {
362030c4abb9SCristian Dumitrescu struct action_spec *action_spec = &s->actions[i];
362130c4abb9SCristian Dumitrescu
362230c4abb9SCristian Dumitrescu status = rte_swx_pipeline_action_config(p,
362330c4abb9SCristian Dumitrescu action_spec->name,
362430c4abb9SCristian Dumitrescu action_spec->args_struct_type_name,
362530c4abb9SCristian Dumitrescu action_spec->instructions,
362630c4abb9SCristian Dumitrescu action_spec->n_instructions);
362730c4abb9SCristian Dumitrescu if (status) {
362830c4abb9SCristian Dumitrescu if (err_msg)
362930c4abb9SCristian Dumitrescu *err_msg = "Action configuration error.";
363030c4abb9SCristian Dumitrescu return status;
363130c4abb9SCristian Dumitrescu }
363230c4abb9SCristian Dumitrescu }
363330c4abb9SCristian Dumitrescu
363430c4abb9SCristian Dumitrescu /* table. */
363530c4abb9SCristian Dumitrescu for (i = 0; i < s->n_tables; i++) {
363630c4abb9SCristian Dumitrescu struct table_spec *table_spec = &s->tables[i];
363730c4abb9SCristian Dumitrescu
363830c4abb9SCristian Dumitrescu status = rte_swx_pipeline_table_config(p,
363930c4abb9SCristian Dumitrescu table_spec->name,
364030c4abb9SCristian Dumitrescu &table_spec->params,
364130c4abb9SCristian Dumitrescu table_spec->recommended_table_type_name,
364230c4abb9SCristian Dumitrescu table_spec->args,
364330c4abb9SCristian Dumitrescu table_spec->size);
364430c4abb9SCristian Dumitrescu if (status) {
364530c4abb9SCristian Dumitrescu if (err_msg)
364630c4abb9SCristian Dumitrescu *err_msg = "Table configuration error.";
364730c4abb9SCristian Dumitrescu return status;
364830c4abb9SCristian Dumitrescu }
364930c4abb9SCristian Dumitrescu }
365030c4abb9SCristian Dumitrescu
365130c4abb9SCristian Dumitrescu /* selector. */
365230c4abb9SCristian Dumitrescu for (i = 0; i < s->n_selectors; i++) {
365330c4abb9SCristian Dumitrescu struct selector_spec *selector_spec = &s->selectors[i];
365430c4abb9SCristian Dumitrescu
365530c4abb9SCristian Dumitrescu status = rte_swx_pipeline_selector_config(p,
365630c4abb9SCristian Dumitrescu selector_spec->name,
365730c4abb9SCristian Dumitrescu &selector_spec->params);
365830c4abb9SCristian Dumitrescu if (status) {
365930c4abb9SCristian Dumitrescu if (err_msg)
366030c4abb9SCristian Dumitrescu *err_msg = "Selector table configuration error.";
366130c4abb9SCristian Dumitrescu return status;
366230c4abb9SCristian Dumitrescu }
366330c4abb9SCristian Dumitrescu }
366430c4abb9SCristian Dumitrescu
366530c4abb9SCristian Dumitrescu /* learner. */
366630c4abb9SCristian Dumitrescu for (i = 0; i < s->n_learners; i++) {
366730c4abb9SCristian Dumitrescu struct learner_spec *learner_spec = &s->learners[i];
366830c4abb9SCristian Dumitrescu
366930c4abb9SCristian Dumitrescu status = rte_swx_pipeline_learner_config(p,
367030c4abb9SCristian Dumitrescu learner_spec->name,
367130c4abb9SCristian Dumitrescu &learner_spec->params,
367230c4abb9SCristian Dumitrescu learner_spec->size,
367330c4abb9SCristian Dumitrescu learner_spec->timeout,
367430c4abb9SCristian Dumitrescu learner_spec->n_timeouts);
367530c4abb9SCristian Dumitrescu if (status) {
367630c4abb9SCristian Dumitrescu if (err_msg)
367730c4abb9SCristian Dumitrescu *err_msg = "Learner table configuration error.";
367830c4abb9SCristian Dumitrescu return status;
367930c4abb9SCristian Dumitrescu }
368030c4abb9SCristian Dumitrescu }
368130c4abb9SCristian Dumitrescu
368230c4abb9SCristian Dumitrescu /* apply. */
368330c4abb9SCristian Dumitrescu for (i = 0; i < s->n_apply; i++) {
368430c4abb9SCristian Dumitrescu struct apply_spec *apply_spec = &s->apply[i];
368530c4abb9SCristian Dumitrescu
368630c4abb9SCristian Dumitrescu status = rte_swx_pipeline_instructions_config(p,
368730c4abb9SCristian Dumitrescu apply_spec->instructions,
368830c4abb9SCristian Dumitrescu apply_spec->n_instructions);
368930c4abb9SCristian Dumitrescu if (status) {
369030c4abb9SCristian Dumitrescu if (err_msg)
369130c4abb9SCristian Dumitrescu *err_msg = "Pipeline instructions configuration error.";
369230c4abb9SCristian Dumitrescu return status;
369330c4abb9SCristian Dumitrescu }
369430c4abb9SCristian Dumitrescu }
369530c4abb9SCristian Dumitrescu
369630c4abb9SCristian Dumitrescu return 0;
369730c4abb9SCristian Dumitrescu }
369830c4abb9SCristian Dumitrescu
369954cae37eSCristian Dumitrescu static void
port_in_params_free(void * params,const char * port_type)370054cae37eSCristian Dumitrescu port_in_params_free(void *params, const char *port_type)
370154cae37eSCristian Dumitrescu {
370254cae37eSCristian Dumitrescu uintptr_t dev_name;
370354cae37eSCristian Dumitrescu
370454cae37eSCristian Dumitrescu if (!params || !port_type)
370554cae37eSCristian Dumitrescu return;
370654cae37eSCristian Dumitrescu
370754cae37eSCristian Dumitrescu if (!strcmp(port_type, "ethdev")) {
370854cae37eSCristian Dumitrescu struct rte_swx_port_ethdev_reader_params *p = params;
370954cae37eSCristian Dumitrescu
371054cae37eSCristian Dumitrescu dev_name = (uintptr_t)p->dev_name;
371154cae37eSCristian Dumitrescu } else if (!strcmp(port_type, "ring")) {
371254cae37eSCristian Dumitrescu struct rte_swx_port_ring_reader_params *p = params;
371354cae37eSCristian Dumitrescu
371454cae37eSCristian Dumitrescu dev_name = (uintptr_t)p->name;
371554cae37eSCristian Dumitrescu } else if (!strcmp(port_type, "source")) {
371654cae37eSCristian Dumitrescu struct rte_swx_port_source_params *p = params;
371754cae37eSCristian Dumitrescu
371854cae37eSCristian Dumitrescu dev_name = (uintptr_t)p->file_name;
371954cae37eSCristian Dumitrescu } else
372054cae37eSCristian Dumitrescu dev_name = (uintptr_t)NULL;
372154cae37eSCristian Dumitrescu
372254cae37eSCristian Dumitrescu free((void *)dev_name);
372354cae37eSCristian Dumitrescu free(params);
372454cae37eSCristian Dumitrescu }
372554cae37eSCristian Dumitrescu
372654cae37eSCristian Dumitrescu static void
port_out_params_free(void * params,const char * port_type)372754cae37eSCristian Dumitrescu port_out_params_free(void *params, const char *port_type)
372854cae37eSCristian Dumitrescu {
372954cae37eSCristian Dumitrescu uintptr_t dev_name;
373054cae37eSCristian Dumitrescu
373154cae37eSCristian Dumitrescu if (!params || !port_type)
373254cae37eSCristian Dumitrescu return;
373354cae37eSCristian Dumitrescu
373454cae37eSCristian Dumitrescu if (!strcmp(port_type, "ethdev")) {
373554cae37eSCristian Dumitrescu struct rte_swx_port_ethdev_writer_params *p = params;
373654cae37eSCristian Dumitrescu
373754cae37eSCristian Dumitrescu dev_name = (uintptr_t)p->dev_name;
373854cae37eSCristian Dumitrescu } else if (!strcmp(port_type, "ring")) {
373954cae37eSCristian Dumitrescu struct rte_swx_port_ring_writer_params *p = params;
374054cae37eSCristian Dumitrescu
374154cae37eSCristian Dumitrescu dev_name = (uintptr_t)p->name;
374254cae37eSCristian Dumitrescu } else if (!strcmp(port_type, "sink")) {
374354cae37eSCristian Dumitrescu struct rte_swx_port_sink_params *p = params;
374454cae37eSCristian Dumitrescu
374554cae37eSCristian Dumitrescu dev_name = (uintptr_t)p->file_name;
374654cae37eSCristian Dumitrescu } else
374754cae37eSCristian Dumitrescu dev_name = (uintptr_t)NULL;
374854cae37eSCristian Dumitrescu
374954cae37eSCristian Dumitrescu free((void *)dev_name);
375054cae37eSCristian Dumitrescu free(params);
375154cae37eSCristian Dumitrescu }
375254cae37eSCristian Dumitrescu
375354cae37eSCristian Dumitrescu void
pipeline_iospec_free(struct pipeline_iospec * s)375454cae37eSCristian Dumitrescu pipeline_iospec_free(struct pipeline_iospec *s)
375554cae37eSCristian Dumitrescu {
375654cae37eSCristian Dumitrescu uint32_t i;
375754cae37eSCristian Dumitrescu
375854cae37eSCristian Dumitrescu if (!s)
375954cae37eSCristian Dumitrescu return;
376054cae37eSCristian Dumitrescu
376154cae37eSCristian Dumitrescu /* Input ports. */
376254cae37eSCristian Dumitrescu for (i = 0; i < s->n_ports_in; i++) {
376354cae37eSCristian Dumitrescu uintptr_t name = (uintptr_t)s->port_in_type[i];
376454cae37eSCristian Dumitrescu
376554cae37eSCristian Dumitrescu port_in_params_free(s->port_in_params[i], s->port_in_type[i]);
376654cae37eSCristian Dumitrescu free((void *)name);
376754cae37eSCristian Dumitrescu }
376854cae37eSCristian Dumitrescu
376954cae37eSCristian Dumitrescu free(s->port_in_type);
377054cae37eSCristian Dumitrescu free(s->port_in_params);
377154cae37eSCristian Dumitrescu
377254cae37eSCristian Dumitrescu /* Output ports. */
377354cae37eSCristian Dumitrescu for (i = 0; i < s->n_ports_out; i++) {
377454cae37eSCristian Dumitrescu uintptr_t name = (uintptr_t)s->port_out_type[i];
377554cae37eSCristian Dumitrescu
377654cae37eSCristian Dumitrescu port_out_params_free(s->port_out_params[i], s->port_out_type[i]);
377754cae37eSCristian Dumitrescu free((void *)name);
377854cae37eSCristian Dumitrescu }
377954cae37eSCristian Dumitrescu
378054cae37eSCristian Dumitrescu free(s->port_out_type);
378154cae37eSCristian Dumitrescu free(s->port_out_params);
378254cae37eSCristian Dumitrescu
378354cae37eSCristian Dumitrescu free(s);
378454cae37eSCristian Dumitrescu }
378554cae37eSCristian Dumitrescu
378654cae37eSCristian Dumitrescu static int
mirroring_parse(struct rte_swx_pipeline_mirroring_params * p,char ** tokens,uint32_t n_tokens,const char ** err_msg)378754cae37eSCristian Dumitrescu mirroring_parse(struct rte_swx_pipeline_mirroring_params *p,
378854cae37eSCristian Dumitrescu char **tokens,
378954cae37eSCristian Dumitrescu uint32_t n_tokens,
379054cae37eSCristian Dumitrescu const char **err_msg)
379154cae37eSCristian Dumitrescu {
379254cae37eSCristian Dumitrescu char *token;
379354cae37eSCristian Dumitrescu
379454cae37eSCristian Dumitrescu if ((n_tokens != 4) || strcmp(tokens[0], "slots") || strcmp(tokens[2], "sessions")) {
379554cae37eSCristian Dumitrescu if (err_msg)
379654cae37eSCristian Dumitrescu *err_msg = "Invalid statement.";
379754cae37eSCristian Dumitrescu return -EINVAL;
379854cae37eSCristian Dumitrescu }
379954cae37eSCristian Dumitrescu
380054cae37eSCristian Dumitrescu /* <n_slots>. */
380154cae37eSCristian Dumitrescu token = tokens[1];
380254cae37eSCristian Dumitrescu p->n_slots = strtoul(token, &token, 0);
380354cae37eSCristian Dumitrescu if (token[0]) {
380454cae37eSCristian Dumitrescu if (err_msg)
380554cae37eSCristian Dumitrescu *err_msg = "Invalid <n_slots> parameter.";
380654cae37eSCristian Dumitrescu return -EINVAL;
380754cae37eSCristian Dumitrescu }
380854cae37eSCristian Dumitrescu
380954cae37eSCristian Dumitrescu /* <n_sessions>. */
381054cae37eSCristian Dumitrescu token = tokens[3];
381154cae37eSCristian Dumitrescu p->n_sessions = strtoul(token, &token, 0);
381254cae37eSCristian Dumitrescu if (token[0]) {
381354cae37eSCristian Dumitrescu if (err_msg)
381454cae37eSCristian Dumitrescu *err_msg = "Invalid <n_sessions> parameter.";
381554cae37eSCristian Dumitrescu return -EINVAL;
381654cae37eSCristian Dumitrescu }
381754cae37eSCristian Dumitrescu
381854cae37eSCristian Dumitrescu return 0;
381954cae37eSCristian Dumitrescu }
382054cae37eSCristian Dumitrescu
382154cae37eSCristian Dumitrescu static void *
port_in_ethdev_parse(char ** tokens,uint32_t n_tokens,const char ** err_msg)382254cae37eSCristian Dumitrescu port_in_ethdev_parse(char **tokens, uint32_t n_tokens, const char **err_msg)
382354cae37eSCristian Dumitrescu {
382454cae37eSCristian Dumitrescu struct rte_swx_port_ethdev_reader_params *p = NULL;
382554cae37eSCristian Dumitrescu char *token, *dev_name = NULL;
382654cae37eSCristian Dumitrescu uint32_t queue_id, burst_size;
382754cae37eSCristian Dumitrescu
382854cae37eSCristian Dumitrescu if ((n_tokens != 5) || strcmp(tokens[1], "rxq") || strcmp(tokens[3], "bsz")) {
382954cae37eSCristian Dumitrescu if (err_msg)
383054cae37eSCristian Dumitrescu *err_msg = "Invalid statement.";
383154cae37eSCristian Dumitrescu return NULL;
383254cae37eSCristian Dumitrescu }
383354cae37eSCristian Dumitrescu
383454cae37eSCristian Dumitrescu /* <queue_id>. */
383554cae37eSCristian Dumitrescu token = tokens[2];
383654cae37eSCristian Dumitrescu queue_id = strtoul(token, &token, 0);
383754cae37eSCristian Dumitrescu if (token[0]) {
383854cae37eSCristian Dumitrescu if (err_msg)
383954cae37eSCristian Dumitrescu *err_msg = "Invalid <queue_id> parameter.";
384054cae37eSCristian Dumitrescu return NULL;
384154cae37eSCristian Dumitrescu }
384254cae37eSCristian Dumitrescu
384354cae37eSCristian Dumitrescu /* <burst_size>. */
384454cae37eSCristian Dumitrescu token = tokens[4];
384554cae37eSCristian Dumitrescu burst_size = strtoul(token, &token, 0);
384654cae37eSCristian Dumitrescu if (token[0]) {
384754cae37eSCristian Dumitrescu if (err_msg)
384854cae37eSCristian Dumitrescu *err_msg = "Invalid <burst_size> parameter.";
384954cae37eSCristian Dumitrescu return NULL;
385054cae37eSCristian Dumitrescu }
385154cae37eSCristian Dumitrescu
385254cae37eSCristian Dumitrescu /* Memory allocation. */
385354cae37eSCristian Dumitrescu dev_name = strdup(tokens[0]);
385454cae37eSCristian Dumitrescu p = malloc(sizeof(struct rte_swx_port_ethdev_reader_params));
385554cae37eSCristian Dumitrescu if (!dev_name || !p) {
385654cae37eSCristian Dumitrescu free(dev_name);
385754cae37eSCristian Dumitrescu free(p);
385854cae37eSCristian Dumitrescu
385954cae37eSCristian Dumitrescu if (err_msg)
386054cae37eSCristian Dumitrescu *err_msg = "Memory allocation failed.";
386154cae37eSCristian Dumitrescu return NULL;
386254cae37eSCristian Dumitrescu }
386354cae37eSCristian Dumitrescu
386454cae37eSCristian Dumitrescu /* Initialization. */
386554cae37eSCristian Dumitrescu p->dev_name = dev_name;
386654cae37eSCristian Dumitrescu p->queue_id = queue_id;
386754cae37eSCristian Dumitrescu p->burst_size = burst_size;
386854cae37eSCristian Dumitrescu
386954cae37eSCristian Dumitrescu return p;
387054cae37eSCristian Dumitrescu }
387154cae37eSCristian Dumitrescu
387254cae37eSCristian Dumitrescu static void *
port_in_ring_parse(char ** tokens,uint32_t n_tokens,const char ** err_msg)387354cae37eSCristian Dumitrescu port_in_ring_parse(char **tokens, uint32_t n_tokens, const char **err_msg)
387454cae37eSCristian Dumitrescu {
387554cae37eSCristian Dumitrescu struct rte_swx_port_ring_reader_params *p = NULL;
387654cae37eSCristian Dumitrescu char *token, *name = NULL;
387754cae37eSCristian Dumitrescu uint32_t burst_size;
387854cae37eSCristian Dumitrescu
387954cae37eSCristian Dumitrescu if ((n_tokens != 3) || strcmp(tokens[1], "bsz")) {
388054cae37eSCristian Dumitrescu if (err_msg)
388154cae37eSCristian Dumitrescu *err_msg = "Invalid statement.";
388254cae37eSCristian Dumitrescu return NULL;
388354cae37eSCristian Dumitrescu }
388454cae37eSCristian Dumitrescu
388554cae37eSCristian Dumitrescu /* <burst_size>. */
388654cae37eSCristian Dumitrescu token = tokens[2];
388754cae37eSCristian Dumitrescu burst_size = strtoul(token, &token, 0);
388854cae37eSCristian Dumitrescu if (token[0]) {
388954cae37eSCristian Dumitrescu if (err_msg)
389054cae37eSCristian Dumitrescu *err_msg = "Invalid <burst_size> parameter.";
389154cae37eSCristian Dumitrescu return NULL;
389254cae37eSCristian Dumitrescu }
389354cae37eSCristian Dumitrescu
389454cae37eSCristian Dumitrescu /* Memory allocation. */
389554cae37eSCristian Dumitrescu name = strdup(tokens[0]);
389654cae37eSCristian Dumitrescu p = malloc(sizeof(struct rte_swx_port_ring_reader_params));
389754cae37eSCristian Dumitrescu if (!name || !p) {
389854cae37eSCristian Dumitrescu free(name);
389954cae37eSCristian Dumitrescu free(p);
390054cae37eSCristian Dumitrescu
390154cae37eSCristian Dumitrescu if (err_msg)
390254cae37eSCristian Dumitrescu *err_msg = "Memory allocation failed.";
390354cae37eSCristian Dumitrescu return NULL;
390454cae37eSCristian Dumitrescu }
390554cae37eSCristian Dumitrescu
390654cae37eSCristian Dumitrescu /* Initialization. */
390754cae37eSCristian Dumitrescu p->name = name;
390854cae37eSCristian Dumitrescu p->burst_size = burst_size;
390954cae37eSCristian Dumitrescu
391054cae37eSCristian Dumitrescu return p;
391154cae37eSCristian Dumitrescu }
391254cae37eSCristian Dumitrescu
391354cae37eSCristian Dumitrescu static void *
port_in_source_parse(char ** tokens,uint32_t n_tokens,const char ** err_msg)391454cae37eSCristian Dumitrescu port_in_source_parse(char **tokens, uint32_t n_tokens, const char **err_msg)
391554cae37eSCristian Dumitrescu {
391654cae37eSCristian Dumitrescu struct rte_swx_port_source_params *p = NULL;
391754cae37eSCristian Dumitrescu struct rte_mempool *pool = NULL;
391854cae37eSCristian Dumitrescu char *token, *file_name = NULL;
391954cae37eSCristian Dumitrescu uint32_t n_loops, n_pkts_max;
392054cae37eSCristian Dumitrescu
392154cae37eSCristian Dumitrescu if ((n_tokens != 8) ||
392254cae37eSCristian Dumitrescu strcmp(tokens[0], "mempool") ||
392354cae37eSCristian Dumitrescu strcmp(tokens[2], "file") ||
392454cae37eSCristian Dumitrescu strcmp(tokens[4], "loop") ||
392554cae37eSCristian Dumitrescu strcmp(tokens[6], "packets")) {
392654cae37eSCristian Dumitrescu if (err_msg)
392754cae37eSCristian Dumitrescu *err_msg = "Invalid statement.";
392854cae37eSCristian Dumitrescu return NULL;
392954cae37eSCristian Dumitrescu }
393054cae37eSCristian Dumitrescu
393154cae37eSCristian Dumitrescu /* <mempool_name>. */
393254cae37eSCristian Dumitrescu pool = rte_mempool_lookup(tokens[1]);
393354cae37eSCristian Dumitrescu if (!pool) {
393454cae37eSCristian Dumitrescu if (err_msg)
393554cae37eSCristian Dumitrescu *err_msg = "Invalid <mempool_name> parameter.";
393654cae37eSCristian Dumitrescu return NULL;
393754cae37eSCristian Dumitrescu }
393854cae37eSCristian Dumitrescu
393954cae37eSCristian Dumitrescu /* <n_loops>. */
394054cae37eSCristian Dumitrescu token = tokens[5];
394154cae37eSCristian Dumitrescu n_loops = strtoul(token, &token, 0);
394254cae37eSCristian Dumitrescu if (token[0]) {
394354cae37eSCristian Dumitrescu if (err_msg)
394454cae37eSCristian Dumitrescu *err_msg = "Invalid <n_loops> parameter.";
394554cae37eSCristian Dumitrescu return NULL;
394654cae37eSCristian Dumitrescu }
394754cae37eSCristian Dumitrescu
394854cae37eSCristian Dumitrescu /* <n_pkts_max>. */
394954cae37eSCristian Dumitrescu token = tokens[7];
395054cae37eSCristian Dumitrescu n_pkts_max = strtoul(token, &token, 0);
395154cae37eSCristian Dumitrescu if (token[0]) {
395254cae37eSCristian Dumitrescu if (err_msg)
395354cae37eSCristian Dumitrescu *err_msg = "Invalid <n_pkts_max> parameter.";
395454cae37eSCristian Dumitrescu return NULL;
395554cae37eSCristian Dumitrescu }
395654cae37eSCristian Dumitrescu
395754cae37eSCristian Dumitrescu /* Memory allocation. */
395854cae37eSCristian Dumitrescu file_name = strdup(tokens[3]);
395954cae37eSCristian Dumitrescu p = malloc(sizeof(struct rte_swx_port_source_params));
396054cae37eSCristian Dumitrescu if (!file_name || !p) {
396154cae37eSCristian Dumitrescu free(file_name);
396254cae37eSCristian Dumitrescu free(p);
396354cae37eSCristian Dumitrescu
396454cae37eSCristian Dumitrescu if (err_msg)
396554cae37eSCristian Dumitrescu *err_msg = "Memory allocation failed.";
396654cae37eSCristian Dumitrescu return NULL;
396754cae37eSCristian Dumitrescu }
396854cae37eSCristian Dumitrescu
396954cae37eSCristian Dumitrescu /* Initialization. */
397054cae37eSCristian Dumitrescu p->pool = pool;
397154cae37eSCristian Dumitrescu p->file_name = file_name;
397254cae37eSCristian Dumitrescu p->n_loops = n_loops;
397354cae37eSCristian Dumitrescu p->n_pkts_max = n_pkts_max;
397454cae37eSCristian Dumitrescu
397554cae37eSCristian Dumitrescu return p;
397654cae37eSCristian Dumitrescu }
397754cae37eSCristian Dumitrescu
397854cae37eSCristian Dumitrescu static void *
port_in_fd_parse(char ** tokens,uint32_t n_tokens,const char ** err_msg)397954cae37eSCristian Dumitrescu port_in_fd_parse(char **tokens,
398054cae37eSCristian Dumitrescu uint32_t n_tokens,
398154cae37eSCristian Dumitrescu const char **err_msg)
398254cae37eSCristian Dumitrescu {
398354cae37eSCristian Dumitrescu struct rte_swx_port_fd_reader_params *p = NULL;
398454cae37eSCristian Dumitrescu struct rte_mempool *mempool = NULL;
398554cae37eSCristian Dumitrescu char *token;
398654cae37eSCristian Dumitrescu uint32_t mtu, burst_size;
398754cae37eSCristian Dumitrescu int fd;
398854cae37eSCristian Dumitrescu
398954cae37eSCristian Dumitrescu if ((n_tokens != 7) ||
399054cae37eSCristian Dumitrescu strcmp(tokens[1], "mtu") ||
399154cae37eSCristian Dumitrescu strcmp(tokens[3], "mempool") ||
399254cae37eSCristian Dumitrescu strcmp(tokens[5], "bsz")) {
399354cae37eSCristian Dumitrescu if (err_msg)
399454cae37eSCristian Dumitrescu *err_msg = "Invalid statement.";
399554cae37eSCristian Dumitrescu return NULL;
399654cae37eSCristian Dumitrescu }
399754cae37eSCristian Dumitrescu
399854cae37eSCristian Dumitrescu /* <file_descriptor>. */
399954cae37eSCristian Dumitrescu token = tokens[0];
400054cae37eSCristian Dumitrescu fd = strtol(token, &token, 0);
400154cae37eSCristian Dumitrescu if (token[0]) {
400254cae37eSCristian Dumitrescu if (err_msg)
400354cae37eSCristian Dumitrescu *err_msg = "Invalid <file_descriptor> parameter.";
400454cae37eSCristian Dumitrescu return NULL;
400554cae37eSCristian Dumitrescu }
400654cae37eSCristian Dumitrescu
400754cae37eSCristian Dumitrescu /* <mtu>. */
400854cae37eSCristian Dumitrescu token = tokens[2];
400954cae37eSCristian Dumitrescu mtu = strtoul(token, &token, 0);
401054cae37eSCristian Dumitrescu if (token[0]) {
401154cae37eSCristian Dumitrescu if (err_msg)
401254cae37eSCristian Dumitrescu *err_msg = "Invalid <mtu> parameter.";
401354cae37eSCristian Dumitrescu return NULL;
401454cae37eSCristian Dumitrescu }
401554cae37eSCristian Dumitrescu
401654cae37eSCristian Dumitrescu /* <mempool_name>. */
401754cae37eSCristian Dumitrescu mempool = rte_mempool_lookup(tokens[4]);
401854cae37eSCristian Dumitrescu if (!mempool) {
401954cae37eSCristian Dumitrescu if (err_msg)
402054cae37eSCristian Dumitrescu *err_msg = "Invalid <mempool_name> parameter.";
402154cae37eSCristian Dumitrescu return NULL;
402254cae37eSCristian Dumitrescu }
402354cae37eSCristian Dumitrescu
402454cae37eSCristian Dumitrescu /* <burst_size>. */
402554cae37eSCristian Dumitrescu token = tokens[6];
402654cae37eSCristian Dumitrescu burst_size = strtoul(token, &token, 0);
402754cae37eSCristian Dumitrescu if (token[0]) {
402854cae37eSCristian Dumitrescu if (err_msg)
402954cae37eSCristian Dumitrescu *err_msg = "Invalid <burst_size> parameter.";
403054cae37eSCristian Dumitrescu return NULL;
403154cae37eSCristian Dumitrescu }
403254cae37eSCristian Dumitrescu
403354cae37eSCristian Dumitrescu /* Memory allocation. */
403454cae37eSCristian Dumitrescu p = malloc(sizeof(struct rte_swx_port_fd_reader_params));
403554cae37eSCristian Dumitrescu if (!p) {
403654cae37eSCristian Dumitrescu if (err_msg)
403754cae37eSCristian Dumitrescu *err_msg = "Memory allocation failed.";
403854cae37eSCristian Dumitrescu return NULL;
403954cae37eSCristian Dumitrescu }
404054cae37eSCristian Dumitrescu
404154cae37eSCristian Dumitrescu /* Initialization. */
404254cae37eSCristian Dumitrescu p->fd = fd;
404354cae37eSCristian Dumitrescu p->mtu = mtu;
404454cae37eSCristian Dumitrescu p->mempool = mempool;
404554cae37eSCristian Dumitrescu p->burst_size = burst_size;
404654cae37eSCristian Dumitrescu
404754cae37eSCristian Dumitrescu return p;
404854cae37eSCristian Dumitrescu }
404954cae37eSCristian Dumitrescu
405054cae37eSCristian Dumitrescu static void *
port_out_ethdev_parse(char ** tokens,uint32_t n_tokens,const char ** err_msg)405154cae37eSCristian Dumitrescu port_out_ethdev_parse(char **tokens, uint32_t n_tokens, const char **err_msg)
405254cae37eSCristian Dumitrescu {
405354cae37eSCristian Dumitrescu struct rte_swx_port_ethdev_writer_params *p = NULL;
405454cae37eSCristian Dumitrescu char *token, *dev_name = NULL;
405554cae37eSCristian Dumitrescu uint32_t queue_id, burst_size;
405654cae37eSCristian Dumitrescu
405754cae37eSCristian Dumitrescu if ((n_tokens != 5) || strcmp(tokens[1], "txq") || strcmp(tokens[3], "bsz")) {
405854cae37eSCristian Dumitrescu if (err_msg)
405954cae37eSCristian Dumitrescu *err_msg = "Invalid statement.";
406054cae37eSCristian Dumitrescu return NULL;
406154cae37eSCristian Dumitrescu }
406254cae37eSCristian Dumitrescu
406354cae37eSCristian Dumitrescu /* <queue_id>. */
406454cae37eSCristian Dumitrescu token = tokens[2];
406554cae37eSCristian Dumitrescu queue_id = strtoul(token, &token, 0);
406654cae37eSCristian Dumitrescu if (token[0]) {
406754cae37eSCristian Dumitrescu if (err_msg)
406854cae37eSCristian Dumitrescu *err_msg = "Invalid <queue_id> parameter.";
406954cae37eSCristian Dumitrescu return NULL;
407054cae37eSCristian Dumitrescu }
407154cae37eSCristian Dumitrescu
407254cae37eSCristian Dumitrescu /* <burst_size>. */
407354cae37eSCristian Dumitrescu token = tokens[4];
407454cae37eSCristian Dumitrescu burst_size = strtoul(token, &token, 0);
407554cae37eSCristian Dumitrescu if (token[0]) {
407654cae37eSCristian Dumitrescu if (err_msg)
407754cae37eSCristian Dumitrescu *err_msg = "Invalid <burst_size> parameter.";
407854cae37eSCristian Dumitrescu return NULL;
407954cae37eSCristian Dumitrescu }
408054cae37eSCristian Dumitrescu
408154cae37eSCristian Dumitrescu /* Memory allocation. */
408254cae37eSCristian Dumitrescu dev_name = strdup(tokens[0]);
408354cae37eSCristian Dumitrescu p = malloc(sizeof(struct rte_swx_port_ethdev_writer_params));
408454cae37eSCristian Dumitrescu if (!dev_name || !p) {
408554cae37eSCristian Dumitrescu free(dev_name);
408654cae37eSCristian Dumitrescu free(p);
408754cae37eSCristian Dumitrescu
408854cae37eSCristian Dumitrescu if (err_msg)
408954cae37eSCristian Dumitrescu *err_msg = "Memory allocation failed.";
409054cae37eSCristian Dumitrescu return NULL;
409154cae37eSCristian Dumitrescu }
409254cae37eSCristian Dumitrescu
409354cae37eSCristian Dumitrescu /* Initialization. */
409454cae37eSCristian Dumitrescu p->dev_name = dev_name;
409554cae37eSCristian Dumitrescu p->queue_id = queue_id;
409654cae37eSCristian Dumitrescu p->burst_size = burst_size;
409754cae37eSCristian Dumitrescu
409854cae37eSCristian Dumitrescu return p;
409954cae37eSCristian Dumitrescu }
410054cae37eSCristian Dumitrescu
410154cae37eSCristian Dumitrescu static void *
port_out_ring_parse(char ** tokens,uint32_t n_tokens,const char ** err_msg)410254cae37eSCristian Dumitrescu port_out_ring_parse(char **tokens, uint32_t n_tokens, const char **err_msg)
410354cae37eSCristian Dumitrescu {
410454cae37eSCristian Dumitrescu struct rte_swx_port_ring_writer_params *p = NULL;
410554cae37eSCristian Dumitrescu char *token, *name = NULL;
410654cae37eSCristian Dumitrescu uint32_t burst_size;
410754cae37eSCristian Dumitrescu
410854cae37eSCristian Dumitrescu if ((n_tokens != 3) || strcmp(tokens[1], "bsz")) {
410954cae37eSCristian Dumitrescu if (err_msg)
411054cae37eSCristian Dumitrescu *err_msg = "Invalid statement.";
411154cae37eSCristian Dumitrescu return NULL;
411254cae37eSCristian Dumitrescu }
411354cae37eSCristian Dumitrescu
411454cae37eSCristian Dumitrescu /* <burst_size>. */
411554cae37eSCristian Dumitrescu token = tokens[2];
411654cae37eSCristian Dumitrescu burst_size = strtoul(token, &token, 0);
411754cae37eSCristian Dumitrescu if (token[0]) {
411854cae37eSCristian Dumitrescu if (err_msg)
411954cae37eSCristian Dumitrescu *err_msg = "Invalid <burst_size> parameter.";
412054cae37eSCristian Dumitrescu return NULL;
412154cae37eSCristian Dumitrescu }
412254cae37eSCristian Dumitrescu
412354cae37eSCristian Dumitrescu /* Memory allocation. */
412454cae37eSCristian Dumitrescu name = strdup(tokens[0]);
412554cae37eSCristian Dumitrescu p = malloc(sizeof(struct rte_swx_port_ring_writer_params));
412654cae37eSCristian Dumitrescu if (!name || !p) {
412754cae37eSCristian Dumitrescu free(name);
412854cae37eSCristian Dumitrescu free(p);
412954cae37eSCristian Dumitrescu
413054cae37eSCristian Dumitrescu if (err_msg)
413154cae37eSCristian Dumitrescu *err_msg = "Memory allocation failed.";
413254cae37eSCristian Dumitrescu return NULL;
413354cae37eSCristian Dumitrescu }
413454cae37eSCristian Dumitrescu
413554cae37eSCristian Dumitrescu /* Initialization. */
413654cae37eSCristian Dumitrescu p->name = name;
413754cae37eSCristian Dumitrescu p->burst_size = burst_size;
413854cae37eSCristian Dumitrescu
413954cae37eSCristian Dumitrescu return p;
414054cae37eSCristian Dumitrescu }
414154cae37eSCristian Dumitrescu
414254cae37eSCristian Dumitrescu static void *
port_out_sink_parse(char ** tokens,uint32_t n_tokens,const char ** err_msg)414354cae37eSCristian Dumitrescu port_out_sink_parse(char **tokens, uint32_t n_tokens, const char **err_msg)
414454cae37eSCristian Dumitrescu {
414554cae37eSCristian Dumitrescu struct rte_swx_port_sink_params *p = NULL;
414654cae37eSCristian Dumitrescu char *file_name = NULL;
414754cae37eSCristian Dumitrescu int file_name_valid = 0;
414854cae37eSCristian Dumitrescu
414954cae37eSCristian Dumitrescu if ((n_tokens != 2) || strcmp(tokens[0], "file")) {
415054cae37eSCristian Dumitrescu if (err_msg)
415154cae37eSCristian Dumitrescu *err_msg = "Invalid statement.";
415254cae37eSCristian Dumitrescu return NULL;
415354cae37eSCristian Dumitrescu }
415454cae37eSCristian Dumitrescu
415554cae37eSCristian Dumitrescu /* Memory allocation. */
415654cae37eSCristian Dumitrescu if (strcmp(tokens[1], "none")) {
415754cae37eSCristian Dumitrescu file_name_valid = 1;
415854cae37eSCristian Dumitrescu file_name = strdup(tokens[1]);
415954cae37eSCristian Dumitrescu }
416054cae37eSCristian Dumitrescu
416154cae37eSCristian Dumitrescu p = malloc(sizeof(struct rte_swx_port_ring_writer_params));
416254cae37eSCristian Dumitrescu if ((file_name_valid && !file_name) || !p) {
416354cae37eSCristian Dumitrescu free(file_name);
416454cae37eSCristian Dumitrescu free(p);
416554cae37eSCristian Dumitrescu
416654cae37eSCristian Dumitrescu if (err_msg)
416754cae37eSCristian Dumitrescu *err_msg = "Memory allocation failed.";
416854cae37eSCristian Dumitrescu return NULL;
416954cae37eSCristian Dumitrescu }
417054cae37eSCristian Dumitrescu
417154cae37eSCristian Dumitrescu /* Initialization. */
417254cae37eSCristian Dumitrescu p->file_name = file_name;
417354cae37eSCristian Dumitrescu
417454cae37eSCristian Dumitrescu return p;
417554cae37eSCristian Dumitrescu }
417654cae37eSCristian Dumitrescu
417754cae37eSCristian Dumitrescu static void *
port_out_fd_parse(char ** tokens,uint32_t n_tokens,const char ** err_msg)417854cae37eSCristian Dumitrescu port_out_fd_parse(char **tokens,
417954cae37eSCristian Dumitrescu uint32_t n_tokens,
418054cae37eSCristian Dumitrescu const char **err_msg)
418154cae37eSCristian Dumitrescu {
418254cae37eSCristian Dumitrescu struct rte_swx_port_fd_writer_params *p = NULL;
418354cae37eSCristian Dumitrescu char *token;
418454cae37eSCristian Dumitrescu uint32_t burst_size;
418554cae37eSCristian Dumitrescu int fd;
418654cae37eSCristian Dumitrescu
418754cae37eSCristian Dumitrescu if ((n_tokens != 3) || strcmp(tokens[1], "bsz")) {
418854cae37eSCristian Dumitrescu if (err_msg)
418954cae37eSCristian Dumitrescu *err_msg = "Invalid statement.";
419054cae37eSCristian Dumitrescu return NULL;
419154cae37eSCristian Dumitrescu }
419254cae37eSCristian Dumitrescu
419354cae37eSCristian Dumitrescu /* <file_descriptor>. */
419454cae37eSCristian Dumitrescu token = tokens[0];
419554cae37eSCristian Dumitrescu fd = strtol(token, &token, 0);
419654cae37eSCristian Dumitrescu if (token[0]) {
419754cae37eSCristian Dumitrescu if (err_msg)
419854cae37eSCristian Dumitrescu *err_msg = "Invalid <file_descriptor> parameter.";
419954cae37eSCristian Dumitrescu return NULL;
420054cae37eSCristian Dumitrescu }
420154cae37eSCristian Dumitrescu
420254cae37eSCristian Dumitrescu /* <burst_size>. */
420354cae37eSCristian Dumitrescu token = tokens[2];
420454cae37eSCristian Dumitrescu burst_size = strtoul(token, &token, 0);
420554cae37eSCristian Dumitrescu if (token[0]) {
420654cae37eSCristian Dumitrescu if (err_msg)
420754cae37eSCristian Dumitrescu *err_msg = "Invalid <burst_size> parameter.";
420854cae37eSCristian Dumitrescu return NULL;
420954cae37eSCristian Dumitrescu }
421054cae37eSCristian Dumitrescu
421154cae37eSCristian Dumitrescu /* Memory allocation. */
421254cae37eSCristian Dumitrescu p = malloc(sizeof(struct rte_swx_port_fd_writer_params));
421354cae37eSCristian Dumitrescu if (!p) {
421454cae37eSCristian Dumitrescu if (err_msg)
421554cae37eSCristian Dumitrescu *err_msg = "Memory allocation failed.";
421654cae37eSCristian Dumitrescu return NULL;
421754cae37eSCristian Dumitrescu }
421854cae37eSCristian Dumitrescu
421954cae37eSCristian Dumitrescu /* Initialization. */
422054cae37eSCristian Dumitrescu p->fd = fd;
422154cae37eSCristian Dumitrescu p->burst_size = burst_size;
422254cae37eSCristian Dumitrescu
422354cae37eSCristian Dumitrescu return p;
422454cae37eSCristian Dumitrescu }
422554cae37eSCristian Dumitrescu
422654cae37eSCristian Dumitrescu struct pipeline_iospec *
pipeline_iospec_parse(FILE * spec,uint32_t * err_line,const char ** err_msg)422754cae37eSCristian Dumitrescu pipeline_iospec_parse(FILE *spec,
422854cae37eSCristian Dumitrescu uint32_t *err_line,
422954cae37eSCristian Dumitrescu const char **err_msg)
423054cae37eSCristian Dumitrescu {
423154cae37eSCristian Dumitrescu struct pipeline_iospec *s = NULL;
423254cae37eSCristian Dumitrescu uint32_t n_lines = 0;
423354cae37eSCristian Dumitrescu
423454cae37eSCristian Dumitrescu /* Check the input arguments. */
423554cae37eSCristian Dumitrescu if (!spec) {
423654cae37eSCristian Dumitrescu if (err_line)
423754cae37eSCristian Dumitrescu *err_line = n_lines;
423854cae37eSCristian Dumitrescu if (err_msg)
423954cae37eSCristian Dumitrescu *err_msg = "Invalid input argument.";
424054cae37eSCristian Dumitrescu goto error;
424154cae37eSCristian Dumitrescu }
424254cae37eSCristian Dumitrescu
424354cae37eSCristian Dumitrescu /* Memory allocation. */
4244*0594ae0cSFerruh Yigit s = calloc(1, sizeof(struct pipeline_iospec));
424554cae37eSCristian Dumitrescu if (!s) {
424654cae37eSCristian Dumitrescu if (err_line)
424754cae37eSCristian Dumitrescu *err_line = n_lines;
424854cae37eSCristian Dumitrescu if (err_msg)
424954cae37eSCristian Dumitrescu *err_msg = "Memory allocation failed.";
425054cae37eSCristian Dumitrescu goto error;
425154cae37eSCristian Dumitrescu }
425254cae37eSCristian Dumitrescu
425354cae37eSCristian Dumitrescu /* Initialize with the default values. */
425454cae37eSCristian Dumitrescu s->mirroring_params.n_slots = RTE_SWX_PACKET_MIRRORING_SLOTS_DEFAULT;
425554cae37eSCristian Dumitrescu s->mirroring_params.n_sessions = RTE_SWX_PACKET_MIRRORING_SESSIONS_DEFAULT;
425654cae37eSCristian Dumitrescu
425754cae37eSCristian Dumitrescu for (n_lines = 1; ; n_lines++) {
425854cae37eSCristian Dumitrescu char line[MAX_LINE_LENGTH];
425954cae37eSCristian Dumitrescu char *tokens[MAX_TOKENS], *ptr = line;
426054cae37eSCristian Dumitrescu uint32_t n_tokens = 0;
426154cae37eSCristian Dumitrescu
426254cae37eSCristian Dumitrescu /* Read next line. */
426354cae37eSCristian Dumitrescu if (!fgets(line, sizeof(line), spec))
426454cae37eSCristian Dumitrescu break;
426554cae37eSCristian Dumitrescu
426654cae37eSCristian Dumitrescu /* Parse the line into tokens. */
426754cae37eSCristian Dumitrescu for ( ; ; ) {
426854cae37eSCristian Dumitrescu char *token;
426954cae37eSCristian Dumitrescu
427054cae37eSCristian Dumitrescu /* Get token. */
427154cae37eSCristian Dumitrescu token = strtok_r(ptr, " \f\n\r\t\v", &ptr);
427254cae37eSCristian Dumitrescu if (!token)
427354cae37eSCristian Dumitrescu break;
427454cae37eSCristian Dumitrescu
427554cae37eSCristian Dumitrescu /* Handle comments. */
427654cae37eSCristian Dumitrescu if ((token[0] == '#') ||
427754cae37eSCristian Dumitrescu (token[0] == ';') ||
427854cae37eSCristian Dumitrescu ((token[0] == '/') && (token[1] == '/'))) {
427954cae37eSCristian Dumitrescu break;
428054cae37eSCristian Dumitrescu }
428154cae37eSCristian Dumitrescu
428254cae37eSCristian Dumitrescu /* Handle excessively long lines. */
428354cae37eSCristian Dumitrescu if (n_tokens >= RTE_DIM(tokens)) {
428454cae37eSCristian Dumitrescu if (err_line)
428554cae37eSCristian Dumitrescu *err_line = n_lines;
428654cae37eSCristian Dumitrescu if (err_msg)
428754cae37eSCristian Dumitrescu *err_msg = "Too many tokens.";
428854cae37eSCristian Dumitrescu goto error;
428954cae37eSCristian Dumitrescu }
429054cae37eSCristian Dumitrescu
429154cae37eSCristian Dumitrescu /* Handle excessively long tokens. */
429254cae37eSCristian Dumitrescu if (strnlen(token, RTE_SWX_NAME_SIZE) >=
429354cae37eSCristian Dumitrescu RTE_SWX_NAME_SIZE) {
429454cae37eSCristian Dumitrescu if (err_line)
429554cae37eSCristian Dumitrescu *err_line = n_lines;
429654cae37eSCristian Dumitrescu if (err_msg)
429754cae37eSCristian Dumitrescu *err_msg = "Token too big.";
429854cae37eSCristian Dumitrescu goto error;
429954cae37eSCristian Dumitrescu }
430054cae37eSCristian Dumitrescu
430154cae37eSCristian Dumitrescu /* Save token. */
430254cae37eSCristian Dumitrescu tokens[n_tokens] = token;
430354cae37eSCristian Dumitrescu n_tokens++;
430454cae37eSCristian Dumitrescu }
430554cae37eSCristian Dumitrescu
430654cae37eSCristian Dumitrescu /* Handle empty lines. */
430754cae37eSCristian Dumitrescu if (!n_tokens)
430854cae37eSCristian Dumitrescu continue;
430954cae37eSCristian Dumitrescu
431054cae37eSCristian Dumitrescu /* mirroring. */
431154cae37eSCristian Dumitrescu if ((n_tokens >= 1) && !strcmp(tokens[0], "mirroring")) {
431254cae37eSCristian Dumitrescu int status = 0;
431354cae37eSCristian Dumitrescu
431454cae37eSCristian Dumitrescu status = mirroring_parse(&s->mirroring_params,
431554cae37eSCristian Dumitrescu &tokens[1],
431654cae37eSCristian Dumitrescu n_tokens - 1,
431754cae37eSCristian Dumitrescu err_msg);
431854cae37eSCristian Dumitrescu if (status) {
431954cae37eSCristian Dumitrescu if (err_line)
432054cae37eSCristian Dumitrescu *err_line = n_lines;
432154cae37eSCristian Dumitrescu goto error;
432254cae37eSCristian Dumitrescu }
432354cae37eSCristian Dumitrescu
432454cae37eSCristian Dumitrescu continue;
432554cae37eSCristian Dumitrescu }
432654cae37eSCristian Dumitrescu
432754cae37eSCristian Dumitrescu /* port in. */
432854cae37eSCristian Dumitrescu if ((n_tokens >= 4) && !strcmp(tokens[0], "port") && !strcmp(tokens[1], "in")) {
432954cae37eSCristian Dumitrescu char *token = tokens[2];
433054cae37eSCristian Dumitrescu uint32_t *new_id = NULL;
433154cae37eSCristian Dumitrescu const char **new_type = NULL, *port_type = NULL;
433254cae37eSCristian Dumitrescu void **new_params = NULL, *p = NULL;
433354cae37eSCristian Dumitrescu uint32_t port_id;
433454cae37eSCristian Dumitrescu
433554cae37eSCristian Dumitrescu /* <port_id>. */
433654cae37eSCristian Dumitrescu port_id = strtoul(token, &token, 0);
433754cae37eSCristian Dumitrescu if (token[0]) {
433854cae37eSCristian Dumitrescu if (err_line)
433954cae37eSCristian Dumitrescu *err_line = n_lines;
434054cae37eSCristian Dumitrescu if (err_msg)
434154cae37eSCristian Dumitrescu *err_msg = "Invalid port ID.";
434254cae37eSCristian Dumitrescu goto error;
434354cae37eSCristian Dumitrescu }
434454cae37eSCristian Dumitrescu
434554cae37eSCristian Dumitrescu /* <port_type>. */
434654cae37eSCristian Dumitrescu if (!strcmp(tokens[3], "ethdev"))
434754cae37eSCristian Dumitrescu p = port_in_ethdev_parse(&tokens[4], n_tokens - 4, err_msg);
434854cae37eSCristian Dumitrescu else if (!strcmp(tokens[3], "ring"))
434954cae37eSCristian Dumitrescu p = port_in_ring_parse(&tokens[4], n_tokens - 4, err_msg);
435054cae37eSCristian Dumitrescu else if (!strcmp(tokens[3], "source"))
435154cae37eSCristian Dumitrescu p = port_in_source_parse(&tokens[4], n_tokens - 4, err_msg);
435254cae37eSCristian Dumitrescu else if (!strcmp(tokens[3], "fd"))
435354cae37eSCristian Dumitrescu p = port_in_fd_parse(&tokens[4], n_tokens - 4, err_msg);
435454cae37eSCristian Dumitrescu else {
435554cae37eSCristian Dumitrescu p = NULL;
435654cae37eSCristian Dumitrescu if (err_msg)
435754cae37eSCristian Dumitrescu *err_msg = "Invalid port type.";
435854cae37eSCristian Dumitrescu }
435954cae37eSCristian Dumitrescu
436054cae37eSCristian Dumitrescu if (!p) {
436154cae37eSCristian Dumitrescu if (err_line)
436254cae37eSCristian Dumitrescu *err_line = n_lines;
436354cae37eSCristian Dumitrescu goto error;
436454cae37eSCristian Dumitrescu }
436554cae37eSCristian Dumitrescu
436654cae37eSCristian Dumitrescu /* New port. */
436754cae37eSCristian Dumitrescu port_type = strdup(tokens[3]);
436854cae37eSCristian Dumitrescu new_id = realloc(s->port_in_id,
436954cae37eSCristian Dumitrescu (s->n_ports_in + 1) * sizeof(uint32_t));
437054cae37eSCristian Dumitrescu new_type = realloc(s->port_in_type,
437154cae37eSCristian Dumitrescu (s->n_ports_in + 1) * sizeof(char *));
437254cae37eSCristian Dumitrescu new_params = realloc(s->port_in_params,
437354cae37eSCristian Dumitrescu (s->n_ports_in + 1) * sizeof(void *));
437454cae37eSCristian Dumitrescu if (!port_type || !new_id || !new_type || !new_params) {
437554cae37eSCristian Dumitrescu uintptr_t pt = (uintptr_t)port_type;
437654cae37eSCristian Dumitrescu
437754cae37eSCristian Dumitrescu port_in_params_free(p, tokens[3]);
437854cae37eSCristian Dumitrescu free((void *)pt);
437954cae37eSCristian Dumitrescu free(new_id);
438054cae37eSCristian Dumitrescu free(new_type);
438154cae37eSCristian Dumitrescu free(new_params);
438254cae37eSCristian Dumitrescu
438354cae37eSCristian Dumitrescu if (err_line)
438454cae37eSCristian Dumitrescu *err_line = n_lines;
438554cae37eSCristian Dumitrescu if (err_msg)
438654cae37eSCristian Dumitrescu *err_msg = "Memory allocation failed.";
438754cae37eSCristian Dumitrescu goto error;
438854cae37eSCristian Dumitrescu }
438954cae37eSCristian Dumitrescu
439054cae37eSCristian Dumitrescu s->port_in_id = new_id;
439154cae37eSCristian Dumitrescu s->port_in_type = new_type;
439254cae37eSCristian Dumitrescu s->port_in_params = new_params;
439354cae37eSCristian Dumitrescu
439454cae37eSCristian Dumitrescu s->port_in_id[s->n_ports_in] = port_id;
439554cae37eSCristian Dumitrescu s->port_in_type[s->n_ports_in] = port_type;
439654cae37eSCristian Dumitrescu s->port_in_params[s->n_ports_in] = p;
439754cae37eSCristian Dumitrescu s->n_ports_in++;
439854cae37eSCristian Dumitrescu
439954cae37eSCristian Dumitrescu continue;
440054cae37eSCristian Dumitrescu }
440154cae37eSCristian Dumitrescu
440254cae37eSCristian Dumitrescu /* port out. */
440354cae37eSCristian Dumitrescu if ((n_tokens >= 4) && !strcmp(tokens[0], "port") && !strcmp(tokens[1], "out")) {
440454cae37eSCristian Dumitrescu char *token = tokens[2];
440554cae37eSCristian Dumitrescu uint32_t *new_id = NULL;
440654cae37eSCristian Dumitrescu const char **new_type = NULL, *port_type = NULL;
440754cae37eSCristian Dumitrescu void **new_params = NULL, *p = NULL;
440854cae37eSCristian Dumitrescu uint32_t port_id;
440954cae37eSCristian Dumitrescu
441054cae37eSCristian Dumitrescu /* <port_id>. */
441154cae37eSCristian Dumitrescu port_id = strtoul(token, &token, 0);
441254cae37eSCristian Dumitrescu if (token[0]) {
441354cae37eSCristian Dumitrescu if (err_line)
441454cae37eSCristian Dumitrescu *err_line = n_lines;
441554cae37eSCristian Dumitrescu if (err_msg)
441654cae37eSCristian Dumitrescu *err_msg = "Invalid port ID.";
441754cae37eSCristian Dumitrescu goto error;
441854cae37eSCristian Dumitrescu }
441954cae37eSCristian Dumitrescu
442054cae37eSCristian Dumitrescu /* <port_type>. */
442154cae37eSCristian Dumitrescu if (!strcmp(tokens[3], "ethdev"))
442254cae37eSCristian Dumitrescu p = port_out_ethdev_parse(&tokens[4], n_tokens - 4, err_msg);
442354cae37eSCristian Dumitrescu else if (!strcmp(tokens[3], "ring"))
442454cae37eSCristian Dumitrescu p = port_out_ring_parse(&tokens[4], n_tokens - 4, err_msg);
442554cae37eSCristian Dumitrescu else if (!strcmp(tokens[3], "sink"))
442654cae37eSCristian Dumitrescu p = port_out_sink_parse(&tokens[4], n_tokens - 4, err_msg);
442754cae37eSCristian Dumitrescu else if (!strcmp(tokens[3], "fd"))
442854cae37eSCristian Dumitrescu p = port_out_fd_parse(&tokens[4], n_tokens - 4, err_msg);
442954cae37eSCristian Dumitrescu else {
443054cae37eSCristian Dumitrescu p = NULL;
443154cae37eSCristian Dumitrescu if (err_msg)
443254cae37eSCristian Dumitrescu *err_msg = "Invalid port type.";
443354cae37eSCristian Dumitrescu }
443454cae37eSCristian Dumitrescu
443554cae37eSCristian Dumitrescu if (!p) {
443654cae37eSCristian Dumitrescu if (err_line)
443754cae37eSCristian Dumitrescu *err_line = n_lines;
443854cae37eSCristian Dumitrescu goto error;
443954cae37eSCristian Dumitrescu }
444054cae37eSCristian Dumitrescu
444154cae37eSCristian Dumitrescu /* New port. */
444254cae37eSCristian Dumitrescu port_type = strdup(tokens[3]);
444354cae37eSCristian Dumitrescu new_id = realloc(s->port_out_id,
444454cae37eSCristian Dumitrescu (s->n_ports_out + 1) * sizeof(uint32_t));
444554cae37eSCristian Dumitrescu new_type = realloc(s->port_out_type,
444654cae37eSCristian Dumitrescu (s->n_ports_out + 1) * sizeof(char *));
444754cae37eSCristian Dumitrescu new_params = realloc(s->port_out_params,
444854cae37eSCristian Dumitrescu (s->n_ports_out + 1) * sizeof(void *));
444954cae37eSCristian Dumitrescu if (!port_type || !new_id || !new_type || !new_params) {
445054cae37eSCristian Dumitrescu uintptr_t pt = (uintptr_t)port_type;
445154cae37eSCristian Dumitrescu
445254cae37eSCristian Dumitrescu port_out_params_free(p, tokens[3]);
445354cae37eSCristian Dumitrescu free((void *)pt);
445454cae37eSCristian Dumitrescu free(new_id);
445554cae37eSCristian Dumitrescu free(new_type);
445654cae37eSCristian Dumitrescu free(new_params);
445754cae37eSCristian Dumitrescu
445854cae37eSCristian Dumitrescu if (err_line)
445954cae37eSCristian Dumitrescu *err_line = n_lines;
446054cae37eSCristian Dumitrescu if (err_msg)
446154cae37eSCristian Dumitrescu *err_msg = "Memory allocation failed.";
446254cae37eSCristian Dumitrescu goto error;
446354cae37eSCristian Dumitrescu }
446454cae37eSCristian Dumitrescu
446554cae37eSCristian Dumitrescu s->port_out_id = new_id;
446654cae37eSCristian Dumitrescu s->port_out_type = new_type;
446754cae37eSCristian Dumitrescu s->port_out_params = new_params;
446854cae37eSCristian Dumitrescu
446954cae37eSCristian Dumitrescu s->port_out_id[s->n_ports_out] = port_id;
447054cae37eSCristian Dumitrescu s->port_out_type[s->n_ports_out] = port_type;
447154cae37eSCristian Dumitrescu s->port_out_params[s->n_ports_out] = p;
447254cae37eSCristian Dumitrescu s->n_ports_out++;
447354cae37eSCristian Dumitrescu
447454cae37eSCristian Dumitrescu continue;
447554cae37eSCristian Dumitrescu }
447654cae37eSCristian Dumitrescu
447754cae37eSCristian Dumitrescu /* Anything else. */
447854cae37eSCristian Dumitrescu if (err_line)
447954cae37eSCristian Dumitrescu *err_line = n_lines;
448054cae37eSCristian Dumitrescu if (err_msg)
448154cae37eSCristian Dumitrescu *err_msg = "Unknown I/O statement.";
448254cae37eSCristian Dumitrescu goto error;
448354cae37eSCristian Dumitrescu }
448454cae37eSCristian Dumitrescu
448554cae37eSCristian Dumitrescu return s;
448654cae37eSCristian Dumitrescu
448754cae37eSCristian Dumitrescu error:
448854cae37eSCristian Dumitrescu pipeline_iospec_free(s);
448954cae37eSCristian Dumitrescu
449054cae37eSCristian Dumitrescu return NULL;
449154cae37eSCristian Dumitrescu }
449254cae37eSCristian Dumitrescu
449354cae37eSCristian Dumitrescu int
pipeline_iospec_configure(struct rte_swx_pipeline * p,struct pipeline_iospec * s,const char ** err_msg)449454cae37eSCristian Dumitrescu pipeline_iospec_configure(struct rte_swx_pipeline *p,
449554cae37eSCristian Dumitrescu struct pipeline_iospec *s,
449654cae37eSCristian Dumitrescu const char **err_msg)
449754cae37eSCristian Dumitrescu {
449854cae37eSCristian Dumitrescu uint32_t i;
449954cae37eSCristian Dumitrescu int status = 0;
450054cae37eSCristian Dumitrescu
450154cae37eSCristian Dumitrescu /* Check input arguments. */
450254cae37eSCristian Dumitrescu if (!p || !s) {
450354cae37eSCristian Dumitrescu if (err_msg)
450454cae37eSCristian Dumitrescu *err_msg = "Invalid input argument";
450554cae37eSCristian Dumitrescu return -EINVAL;
450654cae37eSCristian Dumitrescu }
450754cae37eSCristian Dumitrescu
450854cae37eSCristian Dumitrescu /* Mirroring. */
450954cae37eSCristian Dumitrescu status = rte_swx_pipeline_mirroring_config(p, &s->mirroring_params);
451054cae37eSCristian Dumitrescu if (status) {
451154cae37eSCristian Dumitrescu if (err_msg)
451254cae37eSCristian Dumitrescu *err_msg = "Pipeline mirroring configuration error.";
451354cae37eSCristian Dumitrescu return status;
451454cae37eSCristian Dumitrescu }
451554cae37eSCristian Dumitrescu
451654cae37eSCristian Dumitrescu /* Input ports. */
451754cae37eSCristian Dumitrescu for (i = 0; i < s->n_ports_in; i++) {
451854cae37eSCristian Dumitrescu status = rte_swx_pipeline_port_in_config(p,
451954cae37eSCristian Dumitrescu i,
452054cae37eSCristian Dumitrescu s->port_in_type[i],
452154cae37eSCristian Dumitrescu s->port_in_params[i]);
452254cae37eSCristian Dumitrescu if (status) {
452354cae37eSCristian Dumitrescu if (err_msg)
452454cae37eSCristian Dumitrescu *err_msg = "Pipeline input port configuration error.";
452554cae37eSCristian Dumitrescu return status;
452654cae37eSCristian Dumitrescu }
452754cae37eSCristian Dumitrescu }
452854cae37eSCristian Dumitrescu
452954cae37eSCristian Dumitrescu /* Output ports. */
453054cae37eSCristian Dumitrescu for (i = 0; i < s->n_ports_out; i++) {
453154cae37eSCristian Dumitrescu status = rte_swx_pipeline_port_out_config(p,
453254cae37eSCristian Dumitrescu i,
453354cae37eSCristian Dumitrescu s->port_out_type[i],
453454cae37eSCristian Dumitrescu s->port_out_params[i]);
453554cae37eSCristian Dumitrescu if (status) {
453654cae37eSCristian Dumitrescu if (err_msg)
453754cae37eSCristian Dumitrescu *err_msg = "Pipeline output port configuration error.";
453854cae37eSCristian Dumitrescu return status;
453954cae37eSCristian Dumitrescu }
454054cae37eSCristian Dumitrescu }
454154cae37eSCristian Dumitrescu
454254cae37eSCristian Dumitrescu return 0;
454354cae37eSCristian Dumitrescu }
4544