app/testpmd: parse flow command line for ESP
[dpdk.git] / app / test-pmd / cmdline_flow.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2016 6WIND S.A.
3  * Copyright 2016 Mellanox Technologies, Ltd
4  */
5
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <inttypes.h>
10 #include <errno.h>
11 #include <ctype.h>
12 #include <string.h>
13 #include <arpa/inet.h>
14 #include <sys/socket.h>
15
16 #include <rte_string_fns.h>
17 #include <rte_common.h>
18 #include <rte_ethdev.h>
19 #include <rte_byteorder.h>
20 #include <cmdline_parse.h>
21 #include <cmdline_parse_etheraddr.h>
22 #include <cmdline_parse_string.h>
23 #include <cmdline_parse_num.h>
24 #include <rte_flow.h>
25 #include <rte_hexdump.h>
26
27 #include "testpmd.h"
28
29 /** Parser token indices. */
30 enum index {
31         /* Special tokens. */
32         ZERO = 0,
33         END,
34         START_SET,
35         END_SET,
36
37         /* Common tokens. */
38         INTEGER,
39         UNSIGNED,
40         PREFIX,
41         BOOLEAN,
42         STRING,
43         HEX,
44         MAC_ADDR,
45         IPV4_ADDR,
46         IPV6_ADDR,
47         RULE_ID,
48         PORT_ID,
49         GROUP_ID,
50         PRIORITY_LEVEL,
51
52         /* Top-level command. */
53         SET,
54         /* Sub-leve commands. */
55         SET_RAW_ENCAP,
56         SET_RAW_DECAP,
57         SET_RAW_INDEX,
58
59         /* Top-level command. */
60         FLOW,
61         /* Sub-level commands. */
62         VALIDATE,
63         CREATE,
64         DESTROY,
65         FLUSH,
66         QUERY,
67         LIST,
68         ISOLATE,
69
70         /* Destroy arguments. */
71         DESTROY_RULE,
72
73         /* Query arguments. */
74         QUERY_ACTION,
75
76         /* List arguments. */
77         LIST_GROUP,
78
79         /* Validate/create arguments. */
80         GROUP,
81         PRIORITY,
82         INGRESS,
83         EGRESS,
84         TRANSFER,
85
86         /* Validate/create pattern. */
87         PATTERN,
88         ITEM_PARAM_IS,
89         ITEM_PARAM_SPEC,
90         ITEM_PARAM_LAST,
91         ITEM_PARAM_MASK,
92         ITEM_PARAM_PREFIX,
93         ITEM_NEXT,
94         ITEM_END,
95         ITEM_VOID,
96         ITEM_INVERT,
97         ITEM_ANY,
98         ITEM_ANY_NUM,
99         ITEM_PF,
100         ITEM_VF,
101         ITEM_VF_ID,
102         ITEM_PHY_PORT,
103         ITEM_PHY_PORT_INDEX,
104         ITEM_PORT_ID,
105         ITEM_PORT_ID_ID,
106         ITEM_MARK,
107         ITEM_MARK_ID,
108         ITEM_RAW,
109         ITEM_RAW_RELATIVE,
110         ITEM_RAW_SEARCH,
111         ITEM_RAW_OFFSET,
112         ITEM_RAW_LIMIT,
113         ITEM_RAW_PATTERN,
114         ITEM_ETH,
115         ITEM_ETH_DST,
116         ITEM_ETH_SRC,
117         ITEM_ETH_TYPE,
118         ITEM_VLAN,
119         ITEM_VLAN_TCI,
120         ITEM_VLAN_PCP,
121         ITEM_VLAN_DEI,
122         ITEM_VLAN_VID,
123         ITEM_VLAN_INNER_TYPE,
124         ITEM_IPV4,
125         ITEM_IPV4_TOS,
126         ITEM_IPV4_TTL,
127         ITEM_IPV4_PROTO,
128         ITEM_IPV4_SRC,
129         ITEM_IPV4_DST,
130         ITEM_IPV6,
131         ITEM_IPV6_TC,
132         ITEM_IPV6_FLOW,
133         ITEM_IPV6_PROTO,
134         ITEM_IPV6_HOP,
135         ITEM_IPV6_SRC,
136         ITEM_IPV6_DST,
137         ITEM_ICMP,
138         ITEM_ICMP_TYPE,
139         ITEM_ICMP_CODE,
140         ITEM_UDP,
141         ITEM_UDP_SRC,
142         ITEM_UDP_DST,
143         ITEM_TCP,
144         ITEM_TCP_SRC,
145         ITEM_TCP_DST,
146         ITEM_TCP_FLAGS,
147         ITEM_SCTP,
148         ITEM_SCTP_SRC,
149         ITEM_SCTP_DST,
150         ITEM_SCTP_TAG,
151         ITEM_SCTP_CKSUM,
152         ITEM_VXLAN,
153         ITEM_VXLAN_VNI,
154         ITEM_E_TAG,
155         ITEM_E_TAG_GRP_ECID_B,
156         ITEM_NVGRE,
157         ITEM_NVGRE_TNI,
158         ITEM_MPLS,
159         ITEM_MPLS_LABEL,
160         ITEM_MPLS_TC,
161         ITEM_MPLS_S,
162         ITEM_GRE,
163         ITEM_GRE_PROTO,
164         ITEM_GRE_C_RSVD0_VER,
165         ITEM_GRE_C_BIT,
166         ITEM_GRE_K_BIT,
167         ITEM_GRE_S_BIT,
168         ITEM_FUZZY,
169         ITEM_FUZZY_THRESH,
170         ITEM_GTP,
171         ITEM_GTP_TEID,
172         ITEM_GTPC,
173         ITEM_GTPU,
174         ITEM_GENEVE,
175         ITEM_GENEVE_VNI,
176         ITEM_GENEVE_PROTO,
177         ITEM_VXLAN_GPE,
178         ITEM_VXLAN_GPE_VNI,
179         ITEM_ARP_ETH_IPV4,
180         ITEM_ARP_ETH_IPV4_SHA,
181         ITEM_ARP_ETH_IPV4_SPA,
182         ITEM_ARP_ETH_IPV4_THA,
183         ITEM_ARP_ETH_IPV4_TPA,
184         ITEM_IPV6_EXT,
185         ITEM_IPV6_EXT_NEXT_HDR,
186         ITEM_ICMP6,
187         ITEM_ICMP6_TYPE,
188         ITEM_ICMP6_CODE,
189         ITEM_ICMP6_ND_NS,
190         ITEM_ICMP6_ND_NS_TARGET_ADDR,
191         ITEM_ICMP6_ND_NA,
192         ITEM_ICMP6_ND_NA_TARGET_ADDR,
193         ITEM_ICMP6_ND_OPT,
194         ITEM_ICMP6_ND_OPT_TYPE,
195         ITEM_ICMP6_ND_OPT_SLA_ETH,
196         ITEM_ICMP6_ND_OPT_SLA_ETH_SLA,
197         ITEM_ICMP6_ND_OPT_TLA_ETH,
198         ITEM_ICMP6_ND_OPT_TLA_ETH_TLA,
199         ITEM_META,
200         ITEM_META_DATA,
201         ITEM_GRE_KEY,
202         ITEM_GRE_KEY_VALUE,
203         ITEM_GTP_PSC,
204         ITEM_GTP_PSC_QFI,
205         ITEM_GTP_PSC_PDU_T,
206         ITEM_PPPOES,
207         ITEM_PPPOED,
208         ITEM_PPPOE_SEID,
209         ITEM_PPPOE_PROTO_ID,
210         ITEM_HIGIG2,
211         ITEM_HIGIG2_CLASSIFICATION,
212         ITEM_HIGIG2_VID,
213         ITEM_TAG,
214         ITEM_TAG_DATA,
215         ITEM_TAG_INDEX,
216         ITEM_L2TPV3OIP,
217         ITEM_L2TPV3OIP_SESSION_ID,
218         ITEM_ESP,
219         ITEM_ESP_SPI,
220
221         /* Validate/create actions. */
222         ACTIONS,
223         ACTION_NEXT,
224         ACTION_END,
225         ACTION_VOID,
226         ACTION_PASSTHRU,
227         ACTION_JUMP,
228         ACTION_JUMP_GROUP,
229         ACTION_MARK,
230         ACTION_MARK_ID,
231         ACTION_FLAG,
232         ACTION_QUEUE,
233         ACTION_QUEUE_INDEX,
234         ACTION_DROP,
235         ACTION_COUNT,
236         ACTION_COUNT_SHARED,
237         ACTION_COUNT_ID,
238         ACTION_RSS,
239         ACTION_RSS_FUNC,
240         ACTION_RSS_LEVEL,
241         ACTION_RSS_FUNC_DEFAULT,
242         ACTION_RSS_FUNC_TOEPLITZ,
243         ACTION_RSS_FUNC_SIMPLE_XOR,
244         ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ,
245         ACTION_RSS_TYPES,
246         ACTION_RSS_TYPE,
247         ACTION_RSS_KEY,
248         ACTION_RSS_KEY_LEN,
249         ACTION_RSS_QUEUES,
250         ACTION_RSS_QUEUE,
251         ACTION_PF,
252         ACTION_VF,
253         ACTION_VF_ORIGINAL,
254         ACTION_VF_ID,
255         ACTION_PHY_PORT,
256         ACTION_PHY_PORT_ORIGINAL,
257         ACTION_PHY_PORT_INDEX,
258         ACTION_PORT_ID,
259         ACTION_PORT_ID_ORIGINAL,
260         ACTION_PORT_ID_ID,
261         ACTION_METER,
262         ACTION_METER_ID,
263         ACTION_OF_SET_MPLS_TTL,
264         ACTION_OF_SET_MPLS_TTL_MPLS_TTL,
265         ACTION_OF_DEC_MPLS_TTL,
266         ACTION_OF_SET_NW_TTL,
267         ACTION_OF_SET_NW_TTL_NW_TTL,
268         ACTION_OF_DEC_NW_TTL,
269         ACTION_OF_COPY_TTL_OUT,
270         ACTION_OF_COPY_TTL_IN,
271         ACTION_OF_POP_VLAN,
272         ACTION_OF_PUSH_VLAN,
273         ACTION_OF_PUSH_VLAN_ETHERTYPE,
274         ACTION_OF_SET_VLAN_VID,
275         ACTION_OF_SET_VLAN_VID_VLAN_VID,
276         ACTION_OF_SET_VLAN_PCP,
277         ACTION_OF_SET_VLAN_PCP_VLAN_PCP,
278         ACTION_OF_POP_MPLS,
279         ACTION_OF_POP_MPLS_ETHERTYPE,
280         ACTION_OF_PUSH_MPLS,
281         ACTION_OF_PUSH_MPLS_ETHERTYPE,
282         ACTION_VXLAN_ENCAP,
283         ACTION_VXLAN_DECAP,
284         ACTION_NVGRE_ENCAP,
285         ACTION_NVGRE_DECAP,
286         ACTION_L2_ENCAP,
287         ACTION_L2_DECAP,
288         ACTION_MPLSOGRE_ENCAP,
289         ACTION_MPLSOGRE_DECAP,
290         ACTION_MPLSOUDP_ENCAP,
291         ACTION_MPLSOUDP_DECAP,
292         ACTION_SET_IPV4_SRC,
293         ACTION_SET_IPV4_SRC_IPV4_SRC,
294         ACTION_SET_IPV4_DST,
295         ACTION_SET_IPV4_DST_IPV4_DST,
296         ACTION_SET_IPV6_SRC,
297         ACTION_SET_IPV6_SRC_IPV6_SRC,
298         ACTION_SET_IPV6_DST,
299         ACTION_SET_IPV6_DST_IPV6_DST,
300         ACTION_SET_TP_SRC,
301         ACTION_SET_TP_SRC_TP_SRC,
302         ACTION_SET_TP_DST,
303         ACTION_SET_TP_DST_TP_DST,
304         ACTION_MAC_SWAP,
305         ACTION_DEC_TTL,
306         ACTION_SET_TTL,
307         ACTION_SET_TTL_TTL,
308         ACTION_SET_MAC_SRC,
309         ACTION_SET_MAC_SRC_MAC_SRC,
310         ACTION_SET_MAC_DST,
311         ACTION_SET_MAC_DST_MAC_DST,
312         ACTION_INC_TCP_SEQ,
313         ACTION_INC_TCP_SEQ_VALUE,
314         ACTION_DEC_TCP_SEQ,
315         ACTION_DEC_TCP_SEQ_VALUE,
316         ACTION_INC_TCP_ACK,
317         ACTION_INC_TCP_ACK_VALUE,
318         ACTION_DEC_TCP_ACK,
319         ACTION_DEC_TCP_ACK_VALUE,
320         ACTION_RAW_ENCAP,
321         ACTION_RAW_DECAP,
322         ACTION_RAW_ENCAP_INDEX,
323         ACTION_RAW_ENCAP_INDEX_VALUE,
324         ACTION_RAW_DECAP_INDEX,
325         ACTION_RAW_DECAP_INDEX_VALUE,
326         ACTION_SET_TAG,
327         ACTION_SET_TAG_DATA,
328         ACTION_SET_TAG_INDEX,
329         ACTION_SET_TAG_MASK,
330         ACTION_SET_META,
331         ACTION_SET_META_DATA,
332         ACTION_SET_META_MASK,
333         ACTION_SET_IPV4_DSCP,
334         ACTION_SET_IPV4_DSCP_VALUE,
335         ACTION_SET_IPV6_DSCP,
336         ACTION_SET_IPV6_DSCP_VALUE,
337 };
338
339 /** Maximum size for pattern in struct rte_flow_item_raw. */
340 #define ITEM_RAW_PATTERN_SIZE 40
341
342 /** Storage size for struct rte_flow_item_raw including pattern. */
343 #define ITEM_RAW_SIZE \
344         (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
345
346 /** Maximum number of queue indices in struct rte_flow_action_rss. */
347 #define ACTION_RSS_QUEUE_NUM 128
348
349 /** Storage for struct rte_flow_action_rss including external data. */
350 struct action_rss_data {
351         struct rte_flow_action_rss conf;
352         uint8_t key[RSS_HASH_KEY_LENGTH];
353         uint16_t queue[ACTION_RSS_QUEUE_NUM];
354 };
355
356 /** Maximum data size in struct rte_flow_action_raw_encap. */
357 #define ACTION_RAW_ENCAP_MAX_DATA 128
358 #define RAW_ENCAP_CONFS_MAX_NUM 8
359
360 /** Storage for struct rte_flow_action_raw_encap. */
361 struct raw_encap_conf {
362         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
363         uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA];
364         size_t size;
365 };
366
367 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM];
368
369 /** Storage for struct rte_flow_action_raw_encap including external data. */
370 struct action_raw_encap_data {
371         struct rte_flow_action_raw_encap conf;
372         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
373         uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA];
374         uint16_t idx;
375 };
376
377 /** Storage for struct rte_flow_action_raw_decap. */
378 struct raw_decap_conf {
379         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
380         size_t size;
381 };
382
383 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM];
384
385 /** Storage for struct rte_flow_action_raw_decap including external data. */
386 struct action_raw_decap_data {
387         struct rte_flow_action_raw_decap conf;
388         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
389         uint16_t idx;
390 };
391
392 struct vxlan_encap_conf vxlan_encap_conf = {
393         .select_ipv4 = 1,
394         .select_vlan = 0,
395         .select_tos_ttl = 0,
396         .vni = "\x00\x00\x00",
397         .udp_src = 0,
398         .udp_dst = RTE_BE16(4789),
399         .ipv4_src = RTE_IPV4(127, 0, 0, 1),
400         .ipv4_dst = RTE_IPV4(255, 255, 255, 255),
401         .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
402                 "\x00\x00\x00\x00\x00\x00\x00\x01",
403         .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
404                 "\x00\x00\x00\x00\x00\x00\x11\x11",
405         .vlan_tci = 0,
406         .ip_tos = 0,
407         .ip_ttl = 255,
408         .eth_src = "\x00\x00\x00\x00\x00\x00",
409         .eth_dst = "\xff\xff\xff\xff\xff\xff",
410 };
411
412 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */
413 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6
414
415 /** Storage for struct rte_flow_action_vxlan_encap including external data. */
416 struct action_vxlan_encap_data {
417         struct rte_flow_action_vxlan_encap conf;
418         struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM];
419         struct rte_flow_item_eth item_eth;
420         struct rte_flow_item_vlan item_vlan;
421         union {
422                 struct rte_flow_item_ipv4 item_ipv4;
423                 struct rte_flow_item_ipv6 item_ipv6;
424         };
425         struct rte_flow_item_udp item_udp;
426         struct rte_flow_item_vxlan item_vxlan;
427 };
428
429 struct nvgre_encap_conf nvgre_encap_conf = {
430         .select_ipv4 = 1,
431         .select_vlan = 0,
432         .tni = "\x00\x00\x00",
433         .ipv4_src = RTE_IPV4(127, 0, 0, 1),
434         .ipv4_dst = RTE_IPV4(255, 255, 255, 255),
435         .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
436                 "\x00\x00\x00\x00\x00\x00\x00\x01",
437         .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
438                 "\x00\x00\x00\x00\x00\x00\x11\x11",
439         .vlan_tci = 0,
440         .eth_src = "\x00\x00\x00\x00\x00\x00",
441         .eth_dst = "\xff\xff\xff\xff\xff\xff",
442 };
443
444 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */
445 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5
446
447 /** Storage for struct rte_flow_action_nvgre_encap including external data. */
448 struct action_nvgre_encap_data {
449         struct rte_flow_action_nvgre_encap conf;
450         struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM];
451         struct rte_flow_item_eth item_eth;
452         struct rte_flow_item_vlan item_vlan;
453         union {
454                 struct rte_flow_item_ipv4 item_ipv4;
455                 struct rte_flow_item_ipv6 item_ipv6;
456         };
457         struct rte_flow_item_nvgre item_nvgre;
458 };
459
460 struct l2_encap_conf l2_encap_conf;
461
462 struct l2_decap_conf l2_decap_conf;
463
464 struct mplsogre_encap_conf mplsogre_encap_conf;
465
466 struct mplsogre_decap_conf mplsogre_decap_conf;
467
468 struct mplsoudp_encap_conf mplsoudp_encap_conf;
469
470 struct mplsoudp_decap_conf mplsoudp_decap_conf;
471
472 /** Maximum number of subsequent tokens and arguments on the stack. */
473 #define CTX_STACK_SIZE 16
474
475 /** Parser context. */
476 struct context {
477         /** Stack of subsequent token lists to process. */
478         const enum index *next[CTX_STACK_SIZE];
479         /** Arguments for stacked tokens. */
480         const void *args[CTX_STACK_SIZE];
481         enum index curr; /**< Current token index. */
482         enum index prev; /**< Index of the last token seen. */
483         int next_num; /**< Number of entries in next[]. */
484         int args_num; /**< Number of entries in args[]. */
485         uint32_t eol:1; /**< EOL has been detected. */
486         uint32_t last:1; /**< No more arguments. */
487         portid_t port; /**< Current port ID (for completions). */
488         uint32_t objdata; /**< Object-specific data. */
489         void *object; /**< Address of current object for relative offsets. */
490         void *objmask; /**< Object a full mask must be written to. */
491 };
492
493 /** Token argument. */
494 struct arg {
495         uint32_t hton:1; /**< Use network byte ordering. */
496         uint32_t sign:1; /**< Value is signed. */
497         uint32_t bounded:1; /**< Value is bounded. */
498         uintmax_t min; /**< Minimum value if bounded. */
499         uintmax_t max; /**< Maximum value if bounded. */
500         uint32_t offset; /**< Relative offset from ctx->object. */
501         uint32_t size; /**< Field size. */
502         const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */
503 };
504
505 /** Parser token definition. */
506 struct token {
507         /** Type displayed during completion (defaults to "TOKEN"). */
508         const char *type;
509         /** Help displayed during completion (defaults to token name). */
510         const char *help;
511         /** Private data used by parser functions. */
512         const void *priv;
513         /**
514          * Lists of subsequent tokens to push on the stack. Each call to the
515          * parser consumes the last entry of that stack.
516          */
517         const enum index *const *next;
518         /** Arguments stack for subsequent tokens that need them. */
519         const struct arg *const *args;
520         /**
521          * Token-processing callback, returns -1 in case of error, the
522          * length of the matched string otherwise. If NULL, attempts to
523          * match the token name.
524          *
525          * If buf is not NULL, the result should be stored in it according
526          * to context. An error is returned if not large enough.
527          */
528         int (*call)(struct context *ctx, const struct token *token,
529                     const char *str, unsigned int len,
530                     void *buf, unsigned int size);
531         /**
532          * Callback that provides possible values for this token, used for
533          * completion. Returns -1 in case of error, the number of possible
534          * values otherwise. If NULL, the token name is used.
535          *
536          * If buf is not NULL, entry index ent is written to buf and the
537          * full length of the entry is returned (same behavior as
538          * snprintf()).
539          */
540         int (*comp)(struct context *ctx, const struct token *token,
541                     unsigned int ent, char *buf, unsigned int size);
542         /** Mandatory token name, no default value. */
543         const char *name;
544 };
545
546 /** Static initializer for the next field. */
547 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, }
548
549 /** Static initializer for a NEXT() entry. */
550 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, }
551
552 /** Static initializer for the args field. */
553 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, }
554
555 /** Static initializer for ARGS() to target a field. */
556 #define ARGS_ENTRY(s, f) \
557         (&(const struct arg){ \
558                 .offset = offsetof(s, f), \
559                 .size = sizeof(((s *)0)->f), \
560         })
561
562 /** Static initializer for ARGS() to target a bit-field. */
563 #define ARGS_ENTRY_BF(s, f, b) \
564         (&(const struct arg){ \
565                 .size = sizeof(s), \
566                 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \
567         })
568
569 /** Static initializer for ARGS() to target an arbitrary bit-mask. */
570 #define ARGS_ENTRY_MASK(s, f, m) \
571         (&(const struct arg){ \
572                 .offset = offsetof(s, f), \
573                 .size = sizeof(((s *)0)->f), \
574                 .mask = (const void *)(m), \
575         })
576
577 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */
578 #define ARGS_ENTRY_MASK_HTON(s, f, m) \
579         (&(const struct arg){ \
580                 .hton = 1, \
581                 .offset = offsetof(s, f), \
582                 .size = sizeof(((s *)0)->f), \
583                 .mask = (const void *)(m), \
584         })
585
586 /** Static initializer for ARGS() to target a pointer. */
587 #define ARGS_ENTRY_PTR(s, f) \
588         (&(const struct arg){ \
589                 .size = sizeof(*((s *)0)->f), \
590         })
591
592 /** Static initializer for ARGS() with arbitrary offset and size. */
593 #define ARGS_ENTRY_ARB(o, s) \
594         (&(const struct arg){ \
595                 .offset = (o), \
596                 .size = (s), \
597         })
598
599 /** Same as ARGS_ENTRY_ARB() with bounded values. */
600 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \
601         (&(const struct arg){ \
602                 .bounded = 1, \
603                 .min = (i), \
604                 .max = (a), \
605                 .offset = (o), \
606                 .size = (s), \
607         })
608
609 /** Same as ARGS_ENTRY() using network byte ordering. */
610 #define ARGS_ENTRY_HTON(s, f) \
611         (&(const struct arg){ \
612                 .hton = 1, \
613                 .offset = offsetof(s, f), \
614                 .size = sizeof(((s *)0)->f), \
615         })
616
617 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */
618 #define ARG_ENTRY_HTON(s) \
619         (&(const struct arg){ \
620                 .hton = 1, \
621                 .offset = 0, \
622                 .size = sizeof(s), \
623         })
624
625 /** Parser output buffer layout expected by cmd_flow_parsed(). */
626 struct buffer {
627         enum index command; /**< Flow command. */
628         portid_t port; /**< Affected port ID. */
629         union {
630                 struct {
631                         struct rte_flow_attr attr;
632                         struct rte_flow_item *pattern;
633                         struct rte_flow_action *actions;
634                         uint32_t pattern_n;
635                         uint32_t actions_n;
636                         uint8_t *data;
637                 } vc; /**< Validate/create arguments. */
638                 struct {
639                         uint32_t *rule;
640                         uint32_t rule_n;
641                 } destroy; /**< Destroy arguments. */
642                 struct {
643                         uint32_t rule;
644                         struct rte_flow_action action;
645                 } query; /**< Query arguments. */
646                 struct {
647                         uint32_t *group;
648                         uint32_t group_n;
649                 } list; /**< List arguments. */
650                 struct {
651                         int set;
652                 } isolate; /**< Isolated mode arguments. */
653         } args; /**< Command arguments. */
654 };
655
656 /** Private data for pattern items. */
657 struct parse_item_priv {
658         enum rte_flow_item_type type; /**< Item type. */
659         uint32_t size; /**< Size of item specification structure. */
660 };
661
662 #define PRIV_ITEM(t, s) \
663         (&(const struct parse_item_priv){ \
664                 .type = RTE_FLOW_ITEM_TYPE_ ## t, \
665                 .size = s, \
666         })
667
668 /** Private data for actions. */
669 struct parse_action_priv {
670         enum rte_flow_action_type type; /**< Action type. */
671         uint32_t size; /**< Size of action configuration structure. */
672 };
673
674 #define PRIV_ACTION(t, s) \
675         (&(const struct parse_action_priv){ \
676                 .type = RTE_FLOW_ACTION_TYPE_ ## t, \
677                 .size = s, \
678         })
679
680 static const enum index next_vc_attr[] = {
681         GROUP,
682         PRIORITY,
683         INGRESS,
684         EGRESS,
685         TRANSFER,
686         PATTERN,
687         ZERO,
688 };
689
690 static const enum index next_destroy_attr[] = {
691         DESTROY_RULE,
692         END,
693         ZERO,
694 };
695
696 static const enum index next_list_attr[] = {
697         LIST_GROUP,
698         END,
699         ZERO,
700 };
701
702 static const enum index item_param[] = {
703         ITEM_PARAM_IS,
704         ITEM_PARAM_SPEC,
705         ITEM_PARAM_LAST,
706         ITEM_PARAM_MASK,
707         ITEM_PARAM_PREFIX,
708         ZERO,
709 };
710
711 static const enum index next_item[] = {
712         ITEM_END,
713         ITEM_VOID,
714         ITEM_INVERT,
715         ITEM_ANY,
716         ITEM_PF,
717         ITEM_VF,
718         ITEM_PHY_PORT,
719         ITEM_PORT_ID,
720         ITEM_MARK,
721         ITEM_RAW,
722         ITEM_ETH,
723         ITEM_VLAN,
724         ITEM_IPV4,
725         ITEM_IPV6,
726         ITEM_ICMP,
727         ITEM_UDP,
728         ITEM_TCP,
729         ITEM_SCTP,
730         ITEM_VXLAN,
731         ITEM_E_TAG,
732         ITEM_NVGRE,
733         ITEM_MPLS,
734         ITEM_GRE,
735         ITEM_FUZZY,
736         ITEM_GTP,
737         ITEM_GTPC,
738         ITEM_GTPU,
739         ITEM_GENEVE,
740         ITEM_VXLAN_GPE,
741         ITEM_ARP_ETH_IPV4,
742         ITEM_IPV6_EXT,
743         ITEM_ICMP6,
744         ITEM_ICMP6_ND_NS,
745         ITEM_ICMP6_ND_NA,
746         ITEM_ICMP6_ND_OPT,
747         ITEM_ICMP6_ND_OPT_SLA_ETH,
748         ITEM_ICMP6_ND_OPT_TLA_ETH,
749         ITEM_META,
750         ITEM_GRE_KEY,
751         ITEM_GTP_PSC,
752         ITEM_PPPOES,
753         ITEM_PPPOED,
754         ITEM_PPPOE_PROTO_ID,
755         ITEM_HIGIG2,
756         ITEM_TAG,
757         ITEM_L2TPV3OIP,
758         ITEM_ESP,
759         END_SET,
760         ZERO,
761 };
762
763 static const enum index item_fuzzy[] = {
764         ITEM_FUZZY_THRESH,
765         ITEM_NEXT,
766         ZERO,
767 };
768
769 static const enum index item_any[] = {
770         ITEM_ANY_NUM,
771         ITEM_NEXT,
772         ZERO,
773 };
774
775 static const enum index item_vf[] = {
776         ITEM_VF_ID,
777         ITEM_NEXT,
778         ZERO,
779 };
780
781 static const enum index item_phy_port[] = {
782         ITEM_PHY_PORT_INDEX,
783         ITEM_NEXT,
784         ZERO,
785 };
786
787 static const enum index item_port_id[] = {
788         ITEM_PORT_ID_ID,
789         ITEM_NEXT,
790         ZERO,
791 };
792
793 static const enum index item_mark[] = {
794         ITEM_MARK_ID,
795         ITEM_NEXT,
796         ZERO,
797 };
798
799 static const enum index item_raw[] = {
800         ITEM_RAW_RELATIVE,
801         ITEM_RAW_SEARCH,
802         ITEM_RAW_OFFSET,
803         ITEM_RAW_LIMIT,
804         ITEM_RAW_PATTERN,
805         ITEM_NEXT,
806         ZERO,
807 };
808
809 static const enum index item_eth[] = {
810         ITEM_ETH_DST,
811         ITEM_ETH_SRC,
812         ITEM_ETH_TYPE,
813         ITEM_NEXT,
814         ZERO,
815 };
816
817 static const enum index item_vlan[] = {
818         ITEM_VLAN_TCI,
819         ITEM_VLAN_PCP,
820         ITEM_VLAN_DEI,
821         ITEM_VLAN_VID,
822         ITEM_VLAN_INNER_TYPE,
823         ITEM_NEXT,
824         ZERO,
825 };
826
827 static const enum index item_ipv4[] = {
828         ITEM_IPV4_TOS,
829         ITEM_IPV4_TTL,
830         ITEM_IPV4_PROTO,
831         ITEM_IPV4_SRC,
832         ITEM_IPV4_DST,
833         ITEM_NEXT,
834         ZERO,
835 };
836
837 static const enum index item_ipv6[] = {
838         ITEM_IPV6_TC,
839         ITEM_IPV6_FLOW,
840         ITEM_IPV6_PROTO,
841         ITEM_IPV6_HOP,
842         ITEM_IPV6_SRC,
843         ITEM_IPV6_DST,
844         ITEM_NEXT,
845         ZERO,
846 };
847
848 static const enum index item_icmp[] = {
849         ITEM_ICMP_TYPE,
850         ITEM_ICMP_CODE,
851         ITEM_NEXT,
852         ZERO,
853 };
854
855 static const enum index item_udp[] = {
856         ITEM_UDP_SRC,
857         ITEM_UDP_DST,
858         ITEM_NEXT,
859         ZERO,
860 };
861
862 static const enum index item_tcp[] = {
863         ITEM_TCP_SRC,
864         ITEM_TCP_DST,
865         ITEM_TCP_FLAGS,
866         ITEM_NEXT,
867         ZERO,
868 };
869
870 static const enum index item_sctp[] = {
871         ITEM_SCTP_SRC,
872         ITEM_SCTP_DST,
873         ITEM_SCTP_TAG,
874         ITEM_SCTP_CKSUM,
875         ITEM_NEXT,
876         ZERO,
877 };
878
879 static const enum index item_vxlan[] = {
880         ITEM_VXLAN_VNI,
881         ITEM_NEXT,
882         ZERO,
883 };
884
885 static const enum index item_e_tag[] = {
886         ITEM_E_TAG_GRP_ECID_B,
887         ITEM_NEXT,
888         ZERO,
889 };
890
891 static const enum index item_nvgre[] = {
892         ITEM_NVGRE_TNI,
893         ITEM_NEXT,
894         ZERO,
895 };
896
897 static const enum index item_mpls[] = {
898         ITEM_MPLS_LABEL,
899         ITEM_MPLS_TC,
900         ITEM_MPLS_S,
901         ITEM_NEXT,
902         ZERO,
903 };
904
905 static const enum index item_gre[] = {
906         ITEM_GRE_PROTO,
907         ITEM_GRE_C_RSVD0_VER,
908         ITEM_GRE_C_BIT,
909         ITEM_GRE_K_BIT,
910         ITEM_GRE_S_BIT,
911         ITEM_NEXT,
912         ZERO,
913 };
914
915 static const enum index item_gre_key[] = {
916         ITEM_GRE_KEY_VALUE,
917         ITEM_NEXT,
918         ZERO,
919 };
920
921 static const enum index item_gtp[] = {
922         ITEM_GTP_TEID,
923         ITEM_NEXT,
924         ZERO,
925 };
926
927 static const enum index item_geneve[] = {
928         ITEM_GENEVE_VNI,
929         ITEM_GENEVE_PROTO,
930         ITEM_NEXT,
931         ZERO,
932 };
933
934 static const enum index item_vxlan_gpe[] = {
935         ITEM_VXLAN_GPE_VNI,
936         ITEM_NEXT,
937         ZERO,
938 };
939
940 static const enum index item_arp_eth_ipv4[] = {
941         ITEM_ARP_ETH_IPV4_SHA,
942         ITEM_ARP_ETH_IPV4_SPA,
943         ITEM_ARP_ETH_IPV4_THA,
944         ITEM_ARP_ETH_IPV4_TPA,
945         ITEM_NEXT,
946         ZERO,
947 };
948
949 static const enum index item_ipv6_ext[] = {
950         ITEM_IPV6_EXT_NEXT_HDR,
951         ITEM_NEXT,
952         ZERO,
953 };
954
955 static const enum index item_icmp6[] = {
956         ITEM_ICMP6_TYPE,
957         ITEM_ICMP6_CODE,
958         ITEM_NEXT,
959         ZERO,
960 };
961
962 static const enum index item_icmp6_nd_ns[] = {
963         ITEM_ICMP6_ND_NS_TARGET_ADDR,
964         ITEM_NEXT,
965         ZERO,
966 };
967
968 static const enum index item_icmp6_nd_na[] = {
969         ITEM_ICMP6_ND_NA_TARGET_ADDR,
970         ITEM_NEXT,
971         ZERO,
972 };
973
974 static const enum index item_icmp6_nd_opt[] = {
975         ITEM_ICMP6_ND_OPT_TYPE,
976         ITEM_NEXT,
977         ZERO,
978 };
979
980 static const enum index item_icmp6_nd_opt_sla_eth[] = {
981         ITEM_ICMP6_ND_OPT_SLA_ETH_SLA,
982         ITEM_NEXT,
983         ZERO,
984 };
985
986 static const enum index item_icmp6_nd_opt_tla_eth[] = {
987         ITEM_ICMP6_ND_OPT_TLA_ETH_TLA,
988         ITEM_NEXT,
989         ZERO,
990 };
991
992 static const enum index item_meta[] = {
993         ITEM_META_DATA,
994         ITEM_NEXT,
995         ZERO,
996 };
997
998 static const enum index item_gtp_psc[] = {
999         ITEM_GTP_PSC_QFI,
1000         ITEM_GTP_PSC_PDU_T,
1001         ITEM_NEXT,
1002         ZERO,
1003 };
1004
1005 static const enum index item_pppoed[] = {
1006         ITEM_PPPOE_SEID,
1007         ITEM_NEXT,
1008         ZERO,
1009 };
1010
1011 static const enum index item_pppoes[] = {
1012         ITEM_PPPOE_SEID,
1013         ITEM_NEXT,
1014         ZERO,
1015 };
1016
1017 static const enum index item_pppoe_proto_id[] = {
1018         ITEM_PPPOE_PROTO_ID,
1019         ITEM_NEXT,
1020         ZERO,
1021 };
1022
1023 static const enum index item_higig2[] = {
1024         ITEM_HIGIG2_CLASSIFICATION,
1025         ITEM_HIGIG2_VID,
1026         ITEM_NEXT,
1027         ZERO,
1028 };
1029
1030 static const enum index item_esp[] = {
1031         ITEM_ESP_SPI,
1032         ITEM_NEXT,
1033         ZERO,
1034 };
1035
1036 static const enum index next_set_raw[] = {
1037         SET_RAW_INDEX,
1038         ITEM_ETH,
1039         ZERO,
1040 };
1041
1042 static const enum index item_tag[] = {
1043         ITEM_TAG_DATA,
1044         ITEM_TAG_INDEX,
1045         ITEM_NEXT,
1046         ZERO,
1047 };
1048
1049 static const enum index item_l2tpv3oip[] = {
1050         ITEM_L2TPV3OIP_SESSION_ID,
1051         ITEM_NEXT,
1052         ZERO,
1053 };
1054
1055 static const enum index next_action[] = {
1056         ACTION_END,
1057         ACTION_VOID,
1058         ACTION_PASSTHRU,
1059         ACTION_JUMP,
1060         ACTION_MARK,
1061         ACTION_FLAG,
1062         ACTION_QUEUE,
1063         ACTION_DROP,
1064         ACTION_COUNT,
1065         ACTION_RSS,
1066         ACTION_PF,
1067         ACTION_VF,
1068         ACTION_PHY_PORT,
1069         ACTION_PORT_ID,
1070         ACTION_METER,
1071         ACTION_OF_SET_MPLS_TTL,
1072         ACTION_OF_DEC_MPLS_TTL,
1073         ACTION_OF_SET_NW_TTL,
1074         ACTION_OF_DEC_NW_TTL,
1075         ACTION_OF_COPY_TTL_OUT,
1076         ACTION_OF_COPY_TTL_IN,
1077         ACTION_OF_POP_VLAN,
1078         ACTION_OF_PUSH_VLAN,
1079         ACTION_OF_SET_VLAN_VID,
1080         ACTION_OF_SET_VLAN_PCP,
1081         ACTION_OF_POP_MPLS,
1082         ACTION_OF_PUSH_MPLS,
1083         ACTION_VXLAN_ENCAP,
1084         ACTION_VXLAN_DECAP,
1085         ACTION_NVGRE_ENCAP,
1086         ACTION_NVGRE_DECAP,
1087         ACTION_L2_ENCAP,
1088         ACTION_L2_DECAP,
1089         ACTION_MPLSOGRE_ENCAP,
1090         ACTION_MPLSOGRE_DECAP,
1091         ACTION_MPLSOUDP_ENCAP,
1092         ACTION_MPLSOUDP_DECAP,
1093         ACTION_SET_IPV4_SRC,
1094         ACTION_SET_IPV4_DST,
1095         ACTION_SET_IPV6_SRC,
1096         ACTION_SET_IPV6_DST,
1097         ACTION_SET_TP_SRC,
1098         ACTION_SET_TP_DST,
1099         ACTION_MAC_SWAP,
1100         ACTION_DEC_TTL,
1101         ACTION_SET_TTL,
1102         ACTION_SET_MAC_SRC,
1103         ACTION_SET_MAC_DST,
1104         ACTION_INC_TCP_SEQ,
1105         ACTION_DEC_TCP_SEQ,
1106         ACTION_INC_TCP_ACK,
1107         ACTION_DEC_TCP_ACK,
1108         ACTION_RAW_ENCAP,
1109         ACTION_RAW_DECAP,
1110         ACTION_SET_TAG,
1111         ACTION_SET_META,
1112         ACTION_SET_IPV4_DSCP,
1113         ACTION_SET_IPV6_DSCP,
1114         ZERO,
1115 };
1116
1117 static const enum index action_mark[] = {
1118         ACTION_MARK_ID,
1119         ACTION_NEXT,
1120         ZERO,
1121 };
1122
1123 static const enum index action_queue[] = {
1124         ACTION_QUEUE_INDEX,
1125         ACTION_NEXT,
1126         ZERO,
1127 };
1128
1129 static const enum index action_count[] = {
1130         ACTION_COUNT_ID,
1131         ACTION_COUNT_SHARED,
1132         ACTION_NEXT,
1133         ZERO,
1134 };
1135
1136 static const enum index action_rss[] = {
1137         ACTION_RSS_FUNC,
1138         ACTION_RSS_LEVEL,
1139         ACTION_RSS_TYPES,
1140         ACTION_RSS_KEY,
1141         ACTION_RSS_KEY_LEN,
1142         ACTION_RSS_QUEUES,
1143         ACTION_NEXT,
1144         ZERO,
1145 };
1146
1147 static const enum index action_vf[] = {
1148         ACTION_VF_ORIGINAL,
1149         ACTION_VF_ID,
1150         ACTION_NEXT,
1151         ZERO,
1152 };
1153
1154 static const enum index action_phy_port[] = {
1155         ACTION_PHY_PORT_ORIGINAL,
1156         ACTION_PHY_PORT_INDEX,
1157         ACTION_NEXT,
1158         ZERO,
1159 };
1160
1161 static const enum index action_port_id[] = {
1162         ACTION_PORT_ID_ORIGINAL,
1163         ACTION_PORT_ID_ID,
1164         ACTION_NEXT,
1165         ZERO,
1166 };
1167
1168 static const enum index action_meter[] = {
1169         ACTION_METER_ID,
1170         ACTION_NEXT,
1171         ZERO,
1172 };
1173
1174 static const enum index action_of_set_mpls_ttl[] = {
1175         ACTION_OF_SET_MPLS_TTL_MPLS_TTL,
1176         ACTION_NEXT,
1177         ZERO,
1178 };
1179
1180 static const enum index action_of_set_nw_ttl[] = {
1181         ACTION_OF_SET_NW_TTL_NW_TTL,
1182         ACTION_NEXT,
1183         ZERO,
1184 };
1185
1186 static const enum index action_of_push_vlan[] = {
1187         ACTION_OF_PUSH_VLAN_ETHERTYPE,
1188         ACTION_NEXT,
1189         ZERO,
1190 };
1191
1192 static const enum index action_of_set_vlan_vid[] = {
1193         ACTION_OF_SET_VLAN_VID_VLAN_VID,
1194         ACTION_NEXT,
1195         ZERO,
1196 };
1197
1198 static const enum index action_of_set_vlan_pcp[] = {
1199         ACTION_OF_SET_VLAN_PCP_VLAN_PCP,
1200         ACTION_NEXT,
1201         ZERO,
1202 };
1203
1204 static const enum index action_of_pop_mpls[] = {
1205         ACTION_OF_POP_MPLS_ETHERTYPE,
1206         ACTION_NEXT,
1207         ZERO,
1208 };
1209
1210 static const enum index action_of_push_mpls[] = {
1211         ACTION_OF_PUSH_MPLS_ETHERTYPE,
1212         ACTION_NEXT,
1213         ZERO,
1214 };
1215
1216 static const enum index action_set_ipv4_src[] = {
1217         ACTION_SET_IPV4_SRC_IPV4_SRC,
1218         ACTION_NEXT,
1219         ZERO,
1220 };
1221
1222 static const enum index action_set_mac_src[] = {
1223         ACTION_SET_MAC_SRC_MAC_SRC,
1224         ACTION_NEXT,
1225         ZERO,
1226 };
1227
1228 static const enum index action_set_ipv4_dst[] = {
1229         ACTION_SET_IPV4_DST_IPV4_DST,
1230         ACTION_NEXT,
1231         ZERO,
1232 };
1233
1234 static const enum index action_set_ipv6_src[] = {
1235         ACTION_SET_IPV6_SRC_IPV6_SRC,
1236         ACTION_NEXT,
1237         ZERO,
1238 };
1239
1240 static const enum index action_set_ipv6_dst[] = {
1241         ACTION_SET_IPV6_DST_IPV6_DST,
1242         ACTION_NEXT,
1243         ZERO,
1244 };
1245
1246 static const enum index action_set_tp_src[] = {
1247         ACTION_SET_TP_SRC_TP_SRC,
1248         ACTION_NEXT,
1249         ZERO,
1250 };
1251
1252 static const enum index action_set_tp_dst[] = {
1253         ACTION_SET_TP_DST_TP_DST,
1254         ACTION_NEXT,
1255         ZERO,
1256 };
1257
1258 static const enum index action_set_ttl[] = {
1259         ACTION_SET_TTL_TTL,
1260         ACTION_NEXT,
1261         ZERO,
1262 };
1263
1264 static const enum index action_jump[] = {
1265         ACTION_JUMP_GROUP,
1266         ACTION_NEXT,
1267         ZERO,
1268 };
1269
1270 static const enum index action_set_mac_dst[] = {
1271         ACTION_SET_MAC_DST_MAC_DST,
1272         ACTION_NEXT,
1273         ZERO,
1274 };
1275
1276 static const enum index action_inc_tcp_seq[] = {
1277         ACTION_INC_TCP_SEQ_VALUE,
1278         ACTION_NEXT,
1279         ZERO,
1280 };
1281
1282 static const enum index action_dec_tcp_seq[] = {
1283         ACTION_DEC_TCP_SEQ_VALUE,
1284         ACTION_NEXT,
1285         ZERO,
1286 };
1287
1288 static const enum index action_inc_tcp_ack[] = {
1289         ACTION_INC_TCP_ACK_VALUE,
1290         ACTION_NEXT,
1291         ZERO,
1292 };
1293
1294 static const enum index action_dec_tcp_ack[] = {
1295         ACTION_DEC_TCP_ACK_VALUE,
1296         ACTION_NEXT,
1297         ZERO,
1298 };
1299
1300 static const enum index action_raw_encap[] = {
1301         ACTION_RAW_ENCAP_INDEX,
1302         ACTION_NEXT,
1303         ZERO,
1304 };
1305
1306 static const enum index action_raw_decap[] = {
1307         ACTION_RAW_DECAP_INDEX,
1308         ACTION_NEXT,
1309         ZERO,
1310 };
1311
1312 static const enum index action_set_tag[] = {
1313         ACTION_SET_TAG_DATA,
1314         ACTION_SET_TAG_INDEX,
1315         ACTION_SET_TAG_MASK,
1316         ACTION_NEXT,
1317         ZERO,
1318 };
1319
1320 static const enum index action_set_meta[] = {
1321         ACTION_SET_META_DATA,
1322         ACTION_SET_META_MASK,
1323         ACTION_NEXT,
1324         ZERO,
1325 };
1326
1327 static const enum index action_set_ipv4_dscp[] = {
1328         ACTION_SET_IPV4_DSCP_VALUE,
1329         ACTION_NEXT,
1330         ZERO,
1331 };
1332
1333 static const enum index action_set_ipv6_dscp[] = {
1334         ACTION_SET_IPV6_DSCP_VALUE,
1335         ACTION_NEXT,
1336         ZERO,
1337 };
1338
1339 static int parse_set_raw_encap_decap(struct context *, const struct token *,
1340                                      const char *, unsigned int,
1341                                      void *, unsigned int);
1342 static int parse_set_init(struct context *, const struct token *,
1343                           const char *, unsigned int,
1344                           void *, unsigned int);
1345 static int parse_init(struct context *, const struct token *,
1346                       const char *, unsigned int,
1347                       void *, unsigned int);
1348 static int parse_vc(struct context *, const struct token *,
1349                     const char *, unsigned int,
1350                     void *, unsigned int);
1351 static int parse_vc_spec(struct context *, const struct token *,
1352                          const char *, unsigned int, void *, unsigned int);
1353 static int parse_vc_conf(struct context *, const struct token *,
1354                          const char *, unsigned int, void *, unsigned int);
1355 static int parse_vc_action_rss(struct context *, const struct token *,
1356                                const char *, unsigned int, void *,
1357                                unsigned int);
1358 static int parse_vc_action_rss_func(struct context *, const struct token *,
1359                                     const char *, unsigned int, void *,
1360                                     unsigned int);
1361 static int parse_vc_action_rss_type(struct context *, const struct token *,
1362                                     const char *, unsigned int, void *,
1363                                     unsigned int);
1364 static int parse_vc_action_rss_queue(struct context *, const struct token *,
1365                                      const char *, unsigned int, void *,
1366                                      unsigned int);
1367 static int parse_vc_action_vxlan_encap(struct context *, const struct token *,
1368                                        const char *, unsigned int, void *,
1369                                        unsigned int);
1370 static int parse_vc_action_nvgre_encap(struct context *, const struct token *,
1371                                        const char *, unsigned int, void *,
1372                                        unsigned int);
1373 static int parse_vc_action_l2_encap(struct context *, const struct token *,
1374                                     const char *, unsigned int, void *,
1375                                     unsigned int);
1376 static int parse_vc_action_l2_decap(struct context *, const struct token *,
1377                                     const char *, unsigned int, void *,
1378                                     unsigned int);
1379 static int parse_vc_action_mplsogre_encap(struct context *,
1380                                           const struct token *, const char *,
1381                                           unsigned int, void *, unsigned int);
1382 static int parse_vc_action_mplsogre_decap(struct context *,
1383                                           const struct token *, const char *,
1384                                           unsigned int, void *, unsigned int);
1385 static int parse_vc_action_mplsoudp_encap(struct context *,
1386                                           const struct token *, const char *,
1387                                           unsigned int, void *, unsigned int);
1388 static int parse_vc_action_mplsoudp_decap(struct context *,
1389                                           const struct token *, const char *,
1390                                           unsigned int, void *, unsigned int);
1391 static int parse_vc_action_raw_encap(struct context *,
1392                                      const struct token *, const char *,
1393                                      unsigned int, void *, unsigned int);
1394 static int parse_vc_action_raw_decap(struct context *,
1395                                      const struct token *, const char *,
1396                                      unsigned int, void *, unsigned int);
1397 static int parse_vc_action_raw_encap_index(struct context *,
1398                                            const struct token *, const char *,
1399                                            unsigned int, void *, unsigned int);
1400 static int parse_vc_action_raw_decap_index(struct context *,
1401                                            const struct token *, const char *,
1402                                            unsigned int, void *, unsigned int);
1403 static int parse_vc_action_set_meta(struct context *ctx,
1404                                     const struct token *token, const char *str,
1405                                     unsigned int len, void *buf,
1406                                     unsigned int size);
1407 static int parse_destroy(struct context *, const struct token *,
1408                          const char *, unsigned int,
1409                          void *, unsigned int);
1410 static int parse_flush(struct context *, const struct token *,
1411                        const char *, unsigned int,
1412                        void *, unsigned int);
1413 static int parse_query(struct context *, const struct token *,
1414                        const char *, unsigned int,
1415                        void *, unsigned int);
1416 static int parse_action(struct context *, const struct token *,
1417                         const char *, unsigned int,
1418                         void *, unsigned int);
1419 static int parse_list(struct context *, const struct token *,
1420                       const char *, unsigned int,
1421                       void *, unsigned int);
1422 static int parse_isolate(struct context *, const struct token *,
1423                          const char *, unsigned int,
1424                          void *, unsigned int);
1425 static int parse_int(struct context *, const struct token *,
1426                      const char *, unsigned int,
1427                      void *, unsigned int);
1428 static int parse_prefix(struct context *, const struct token *,
1429                         const char *, unsigned int,
1430                         void *, unsigned int);
1431 static int parse_boolean(struct context *, const struct token *,
1432                          const char *, unsigned int,
1433                          void *, unsigned int);
1434 static int parse_string(struct context *, const struct token *,
1435                         const char *, unsigned int,
1436                         void *, unsigned int);
1437 static int parse_hex(struct context *ctx, const struct token *token,
1438                         const char *str, unsigned int len,
1439                         void *buf, unsigned int size);
1440 static int parse_mac_addr(struct context *, const struct token *,
1441                           const char *, unsigned int,
1442                           void *, unsigned int);
1443 static int parse_ipv4_addr(struct context *, const struct token *,
1444                            const char *, unsigned int,
1445                            void *, unsigned int);
1446 static int parse_ipv6_addr(struct context *, const struct token *,
1447                            const char *, unsigned int,
1448                            void *, unsigned int);
1449 static int parse_port(struct context *, const struct token *,
1450                       const char *, unsigned int,
1451                       void *, unsigned int);
1452 static int comp_none(struct context *, const struct token *,
1453                      unsigned int, char *, unsigned int);
1454 static int comp_boolean(struct context *, const struct token *,
1455                         unsigned int, char *, unsigned int);
1456 static int comp_action(struct context *, const struct token *,
1457                        unsigned int, char *, unsigned int);
1458 static int comp_port(struct context *, const struct token *,
1459                      unsigned int, char *, unsigned int);
1460 static int comp_rule_id(struct context *, const struct token *,
1461                         unsigned int, char *, unsigned int);
1462 static int comp_vc_action_rss_type(struct context *, const struct token *,
1463                                    unsigned int, char *, unsigned int);
1464 static int comp_vc_action_rss_queue(struct context *, const struct token *,
1465                                     unsigned int, char *, unsigned int);
1466 static int comp_set_raw_index(struct context *, const struct token *,
1467                               unsigned int, char *, unsigned int);
1468
1469 /** Token definitions. */
1470 static const struct token token_list[] = {
1471         /* Special tokens. */
1472         [ZERO] = {
1473                 .name = "ZERO",
1474                 .help = "null entry, abused as the entry point",
1475                 .next = NEXT(NEXT_ENTRY(FLOW)),
1476         },
1477         [END] = {
1478                 .name = "",
1479                 .type = "RETURN",
1480                 .help = "command may end here",
1481         },
1482         [START_SET] = {
1483                 .name = "START_SET",
1484                 .help = "null entry, abused as the entry point for set",
1485                 .next = NEXT(NEXT_ENTRY(SET)),
1486         },
1487         [END_SET] = {
1488                 .name = "end_set",
1489                 .type = "RETURN",
1490                 .help = "set command may end here",
1491         },
1492         /* Common tokens. */
1493         [INTEGER] = {
1494                 .name = "{int}",
1495                 .type = "INTEGER",
1496                 .help = "integer value",
1497                 .call = parse_int,
1498                 .comp = comp_none,
1499         },
1500         [UNSIGNED] = {
1501                 .name = "{unsigned}",
1502                 .type = "UNSIGNED",
1503                 .help = "unsigned integer value",
1504                 .call = parse_int,
1505                 .comp = comp_none,
1506         },
1507         [PREFIX] = {
1508                 .name = "{prefix}",
1509                 .type = "PREFIX",
1510                 .help = "prefix length for bit-mask",
1511                 .call = parse_prefix,
1512                 .comp = comp_none,
1513         },
1514         [BOOLEAN] = {
1515                 .name = "{boolean}",
1516                 .type = "BOOLEAN",
1517                 .help = "any boolean value",
1518                 .call = parse_boolean,
1519                 .comp = comp_boolean,
1520         },
1521         [STRING] = {
1522                 .name = "{string}",
1523                 .type = "STRING",
1524                 .help = "fixed string",
1525                 .call = parse_string,
1526                 .comp = comp_none,
1527         },
1528         [HEX] = {
1529                 .name = "{hex}",
1530                 .type = "HEX",
1531                 .help = "fixed string",
1532                 .call = parse_hex,
1533                 .comp = comp_none,
1534         },
1535         [MAC_ADDR] = {
1536                 .name = "{MAC address}",
1537                 .type = "MAC-48",
1538                 .help = "standard MAC address notation",
1539                 .call = parse_mac_addr,
1540                 .comp = comp_none,
1541         },
1542         [IPV4_ADDR] = {
1543                 .name = "{IPv4 address}",
1544                 .type = "IPV4 ADDRESS",
1545                 .help = "standard IPv4 address notation",
1546                 .call = parse_ipv4_addr,
1547                 .comp = comp_none,
1548         },
1549         [IPV6_ADDR] = {
1550                 .name = "{IPv6 address}",
1551                 .type = "IPV6 ADDRESS",
1552                 .help = "standard IPv6 address notation",
1553                 .call = parse_ipv6_addr,
1554                 .comp = comp_none,
1555         },
1556         [RULE_ID] = {
1557                 .name = "{rule id}",
1558                 .type = "RULE ID",
1559                 .help = "rule identifier",
1560                 .call = parse_int,
1561                 .comp = comp_rule_id,
1562         },
1563         [PORT_ID] = {
1564                 .name = "{port_id}",
1565                 .type = "PORT ID",
1566                 .help = "port identifier",
1567                 .call = parse_port,
1568                 .comp = comp_port,
1569         },
1570         [GROUP_ID] = {
1571                 .name = "{group_id}",
1572                 .type = "GROUP ID",
1573                 .help = "group identifier",
1574                 .call = parse_int,
1575                 .comp = comp_none,
1576         },
1577         [PRIORITY_LEVEL] = {
1578                 .name = "{level}",
1579                 .type = "PRIORITY",
1580                 .help = "priority level",
1581                 .call = parse_int,
1582                 .comp = comp_none,
1583         },
1584         /* Top-level command. */
1585         [FLOW] = {
1586                 .name = "flow",
1587                 .type = "{command} {port_id} [{arg} [...]]",
1588                 .help = "manage ingress/egress flow rules",
1589                 .next = NEXT(NEXT_ENTRY
1590                              (VALIDATE,
1591                               CREATE,
1592                               DESTROY,
1593                               FLUSH,
1594                               LIST,
1595                               QUERY,
1596                               ISOLATE)),
1597                 .call = parse_init,
1598         },
1599         /* Sub-level commands. */
1600         [VALIDATE] = {
1601                 .name = "validate",
1602                 .help = "check whether a flow rule can be created",
1603                 .next = NEXT(next_vc_attr, NEXT_ENTRY(PORT_ID)),
1604                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
1605                 .call = parse_vc,
1606         },
1607         [CREATE] = {
1608                 .name = "create",
1609                 .help = "create a flow rule",
1610                 .next = NEXT(next_vc_attr, NEXT_ENTRY(PORT_ID)),
1611                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
1612                 .call = parse_vc,
1613         },
1614         [DESTROY] = {
1615                 .name = "destroy",
1616                 .help = "destroy specific flow rules",
1617                 .next = NEXT(NEXT_ENTRY(DESTROY_RULE), NEXT_ENTRY(PORT_ID)),
1618                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
1619                 .call = parse_destroy,
1620         },
1621         [FLUSH] = {
1622                 .name = "flush",
1623                 .help = "destroy all flow rules",
1624                 .next = NEXT(NEXT_ENTRY(PORT_ID)),
1625                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
1626                 .call = parse_flush,
1627         },
1628         [QUERY] = {
1629                 .name = "query",
1630                 .help = "query an existing flow rule",
1631                 .next = NEXT(NEXT_ENTRY(QUERY_ACTION),
1632                              NEXT_ENTRY(RULE_ID),
1633                              NEXT_ENTRY(PORT_ID)),
1634                 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type),
1635                              ARGS_ENTRY(struct buffer, args.query.rule),
1636                              ARGS_ENTRY(struct buffer, port)),
1637                 .call = parse_query,
1638         },
1639         [LIST] = {
1640                 .name = "list",
1641                 .help = "list existing flow rules",
1642                 .next = NEXT(next_list_attr, NEXT_ENTRY(PORT_ID)),
1643                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
1644                 .call = parse_list,
1645         },
1646         [ISOLATE] = {
1647                 .name = "isolate",
1648                 .help = "restrict ingress traffic to the defined flow rules",
1649                 .next = NEXT(NEXT_ENTRY(BOOLEAN),
1650                              NEXT_ENTRY(PORT_ID)),
1651                 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set),
1652                              ARGS_ENTRY(struct buffer, port)),
1653                 .call = parse_isolate,
1654         },
1655         /* Destroy arguments. */
1656         [DESTROY_RULE] = {
1657                 .name = "rule",
1658                 .help = "specify a rule identifier",
1659                 .next = NEXT(next_destroy_attr, NEXT_ENTRY(RULE_ID)),
1660                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)),
1661                 .call = parse_destroy,
1662         },
1663         /* Query arguments. */
1664         [QUERY_ACTION] = {
1665                 .name = "{action}",
1666                 .type = "ACTION",
1667                 .help = "action to query, must be part of the rule",
1668                 .call = parse_action,
1669                 .comp = comp_action,
1670         },
1671         /* List arguments. */
1672         [LIST_GROUP] = {
1673                 .name = "group",
1674                 .help = "specify a group",
1675                 .next = NEXT(next_list_attr, NEXT_ENTRY(GROUP_ID)),
1676                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)),
1677                 .call = parse_list,
1678         },
1679         /* Validate/create attributes. */
1680         [GROUP] = {
1681                 .name = "group",
1682                 .help = "specify a group",
1683                 .next = NEXT(next_vc_attr, NEXT_ENTRY(GROUP_ID)),
1684                 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)),
1685                 .call = parse_vc,
1686         },
1687         [PRIORITY] = {
1688                 .name = "priority",
1689                 .help = "specify a priority level",
1690                 .next = NEXT(next_vc_attr, NEXT_ENTRY(PRIORITY_LEVEL)),
1691                 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)),
1692                 .call = parse_vc,
1693         },
1694         [INGRESS] = {
1695                 .name = "ingress",
1696                 .help = "affect rule to ingress",
1697                 .next = NEXT(next_vc_attr),
1698                 .call = parse_vc,
1699         },
1700         [EGRESS] = {
1701                 .name = "egress",
1702                 .help = "affect rule to egress",
1703                 .next = NEXT(next_vc_attr),
1704                 .call = parse_vc,
1705         },
1706         [TRANSFER] = {
1707                 .name = "transfer",
1708                 .help = "apply rule directly to endpoints found in pattern",
1709                 .next = NEXT(next_vc_attr),
1710                 .call = parse_vc,
1711         },
1712         /* Validate/create pattern. */
1713         [PATTERN] = {
1714                 .name = "pattern",
1715                 .help = "submit a list of pattern items",
1716                 .next = NEXT(next_item),
1717                 .call = parse_vc,
1718         },
1719         [ITEM_PARAM_IS] = {
1720                 .name = "is",
1721                 .help = "match value perfectly (with full bit-mask)",
1722                 .call = parse_vc_spec,
1723         },
1724         [ITEM_PARAM_SPEC] = {
1725                 .name = "spec",
1726                 .help = "match value according to configured bit-mask",
1727                 .call = parse_vc_spec,
1728         },
1729         [ITEM_PARAM_LAST] = {
1730                 .name = "last",
1731                 .help = "specify upper bound to establish a range",
1732                 .call = parse_vc_spec,
1733         },
1734         [ITEM_PARAM_MASK] = {
1735                 .name = "mask",
1736                 .help = "specify bit-mask with relevant bits set to one",
1737                 .call = parse_vc_spec,
1738         },
1739         [ITEM_PARAM_PREFIX] = {
1740                 .name = "prefix",
1741                 .help = "generate bit-mask from a prefix length",
1742                 .call = parse_vc_spec,
1743         },
1744         [ITEM_NEXT] = {
1745                 .name = "/",
1746                 .help = "specify next pattern item",
1747                 .next = NEXT(next_item),
1748         },
1749         [ITEM_END] = {
1750                 .name = "end",
1751                 .help = "end list of pattern items",
1752                 .priv = PRIV_ITEM(END, 0),
1753                 .next = NEXT(NEXT_ENTRY(ACTIONS)),
1754                 .call = parse_vc,
1755         },
1756         [ITEM_VOID] = {
1757                 .name = "void",
1758                 .help = "no-op pattern item",
1759                 .priv = PRIV_ITEM(VOID, 0),
1760                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
1761                 .call = parse_vc,
1762         },
1763         [ITEM_INVERT] = {
1764                 .name = "invert",
1765                 .help = "perform actions when pattern does not match",
1766                 .priv = PRIV_ITEM(INVERT, 0),
1767                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
1768                 .call = parse_vc,
1769         },
1770         [ITEM_ANY] = {
1771                 .name = "any",
1772                 .help = "match any protocol for the current layer",
1773                 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)),
1774                 .next = NEXT(item_any),
1775                 .call = parse_vc,
1776         },
1777         [ITEM_ANY_NUM] = {
1778                 .name = "num",
1779                 .help = "number of layers covered",
1780                 .next = NEXT(item_any, NEXT_ENTRY(UNSIGNED), item_param),
1781                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)),
1782         },
1783         [ITEM_PF] = {
1784                 .name = "pf",
1785                 .help = "match traffic from/to the physical function",
1786                 .priv = PRIV_ITEM(PF, 0),
1787                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
1788                 .call = parse_vc,
1789         },
1790         [ITEM_VF] = {
1791                 .name = "vf",
1792                 .help = "match traffic from/to a virtual function ID",
1793                 .priv = PRIV_ITEM(VF, sizeof(struct rte_flow_item_vf)),
1794                 .next = NEXT(item_vf),
1795                 .call = parse_vc,
1796         },
1797         [ITEM_VF_ID] = {
1798                 .name = "id",
1799                 .help = "VF ID",
1800                 .next = NEXT(item_vf, NEXT_ENTRY(UNSIGNED), item_param),
1801                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_vf, id)),
1802         },
1803         [ITEM_PHY_PORT] = {
1804                 .name = "phy_port",
1805                 .help = "match traffic from/to a specific physical port",
1806                 .priv = PRIV_ITEM(PHY_PORT,
1807                                   sizeof(struct rte_flow_item_phy_port)),
1808                 .next = NEXT(item_phy_port),
1809                 .call = parse_vc,
1810         },
1811         [ITEM_PHY_PORT_INDEX] = {
1812                 .name = "index",
1813                 .help = "physical port index",
1814                 .next = NEXT(item_phy_port, NEXT_ENTRY(UNSIGNED), item_param),
1815                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_phy_port, index)),
1816         },
1817         [ITEM_PORT_ID] = {
1818                 .name = "port_id",
1819                 .help = "match traffic from/to a given DPDK port ID",
1820                 .priv = PRIV_ITEM(PORT_ID,
1821                                   sizeof(struct rte_flow_item_port_id)),
1822                 .next = NEXT(item_port_id),
1823                 .call = parse_vc,
1824         },
1825         [ITEM_PORT_ID_ID] = {
1826                 .name = "id",
1827                 .help = "DPDK port ID",
1828                 .next = NEXT(item_port_id, NEXT_ENTRY(UNSIGNED), item_param),
1829                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)),
1830         },
1831         [ITEM_MARK] = {
1832                 .name = "mark",
1833                 .help = "match traffic against value set in previously matched rule",
1834                 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)),
1835                 .next = NEXT(item_mark),
1836                 .call = parse_vc,
1837         },
1838         [ITEM_MARK_ID] = {
1839                 .name = "id",
1840                 .help = "Integer value to match against",
1841                 .next = NEXT(item_mark, NEXT_ENTRY(UNSIGNED), item_param),
1842                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)),
1843         },
1844         [ITEM_RAW] = {
1845                 .name = "raw",
1846                 .help = "match an arbitrary byte string",
1847                 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE),
1848                 .next = NEXT(item_raw),
1849                 .call = parse_vc,
1850         },
1851         [ITEM_RAW_RELATIVE] = {
1852                 .name = "relative",
1853                 .help = "look for pattern after the previous item",
1854                 .next = NEXT(item_raw, NEXT_ENTRY(BOOLEAN), item_param),
1855                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
1856                                            relative, 1)),
1857         },
1858         [ITEM_RAW_SEARCH] = {
1859                 .name = "search",
1860                 .help = "search pattern from offset (see also limit)",
1861                 .next = NEXT(item_raw, NEXT_ENTRY(BOOLEAN), item_param),
1862                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
1863                                            search, 1)),
1864         },
1865         [ITEM_RAW_OFFSET] = {
1866                 .name = "offset",
1867                 .help = "absolute or relative offset for pattern",
1868                 .next = NEXT(item_raw, NEXT_ENTRY(INTEGER), item_param),
1869                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)),
1870         },
1871         [ITEM_RAW_LIMIT] = {
1872                 .name = "limit",
1873                 .help = "search area limit for start of pattern",
1874                 .next = NEXT(item_raw, NEXT_ENTRY(UNSIGNED), item_param),
1875                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)),
1876         },
1877         [ITEM_RAW_PATTERN] = {
1878                 .name = "pattern",
1879                 .help = "byte string to look for",
1880                 .next = NEXT(item_raw,
1881                              NEXT_ENTRY(STRING),
1882                              NEXT_ENTRY(ITEM_PARAM_IS,
1883                                         ITEM_PARAM_SPEC,
1884                                         ITEM_PARAM_MASK)),
1885                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern),
1886                              ARGS_ENTRY(struct rte_flow_item_raw, length),
1887                              ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw),
1888                                             ITEM_RAW_PATTERN_SIZE)),
1889         },
1890         [ITEM_ETH] = {
1891                 .name = "eth",
1892                 .help = "match Ethernet header",
1893                 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
1894                 .next = NEXT(item_eth),
1895                 .call = parse_vc,
1896         },
1897         [ITEM_ETH_DST] = {
1898                 .name = "dst",
1899                 .help = "destination MAC",
1900                 .next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param),
1901                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, dst)),
1902         },
1903         [ITEM_ETH_SRC] = {
1904                 .name = "src",
1905                 .help = "source MAC",
1906                 .next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param),
1907                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, src)),
1908         },
1909         [ITEM_ETH_TYPE] = {
1910                 .name = "type",
1911                 .help = "EtherType",
1912                 .next = NEXT(item_eth, NEXT_ENTRY(UNSIGNED), item_param),
1913                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, type)),
1914         },
1915         [ITEM_VLAN] = {
1916                 .name = "vlan",
1917                 .help = "match 802.1Q/ad VLAN tag",
1918                 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
1919                 .next = NEXT(item_vlan),
1920                 .call = parse_vc,
1921         },
1922         [ITEM_VLAN_TCI] = {
1923                 .name = "tci",
1924                 .help = "tag control information",
1925                 .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1926                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)),
1927         },
1928         [ITEM_VLAN_PCP] = {
1929                 .name = "pcp",
1930                 .help = "priority code point",
1931                 .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1932                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
1933                                                   tci, "\xe0\x00")),
1934         },
1935         [ITEM_VLAN_DEI] = {
1936                 .name = "dei",
1937                 .help = "drop eligible indicator",
1938                 .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1939                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
1940                                                   tci, "\x10\x00")),
1941         },
1942         [ITEM_VLAN_VID] = {
1943                 .name = "vid",
1944                 .help = "VLAN identifier",
1945                 .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1946                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
1947                                                   tci, "\x0f\xff")),
1948         },
1949         [ITEM_VLAN_INNER_TYPE] = {
1950                 .name = "inner_type",
1951                 .help = "inner EtherType",
1952                 .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1953                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan,
1954                                              inner_type)),
1955         },
1956         [ITEM_IPV4] = {
1957                 .name = "ipv4",
1958                 .help = "match IPv4 header",
1959                 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
1960                 .next = NEXT(item_ipv4),
1961                 .call = parse_vc,
1962         },
1963         [ITEM_IPV4_TOS] = {
1964                 .name = "tos",
1965                 .help = "type of service",
1966                 .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
1967                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
1968                                              hdr.type_of_service)),
1969         },
1970         [ITEM_IPV4_TTL] = {
1971                 .name = "ttl",
1972                 .help = "time to live",
1973                 .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
1974                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
1975                                              hdr.time_to_live)),
1976         },
1977         [ITEM_IPV4_PROTO] = {
1978                 .name = "proto",
1979                 .help = "next protocol ID",
1980                 .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
1981                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
1982                                              hdr.next_proto_id)),
1983         },
1984         [ITEM_IPV4_SRC] = {
1985                 .name = "src",
1986                 .help = "source address",
1987                 .next = NEXT(item_ipv4, NEXT_ENTRY(IPV4_ADDR), item_param),
1988                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
1989                                              hdr.src_addr)),
1990         },
1991         [ITEM_IPV4_DST] = {
1992                 .name = "dst",
1993                 .help = "destination address",
1994                 .next = NEXT(item_ipv4, NEXT_ENTRY(IPV4_ADDR), item_param),
1995                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
1996                                              hdr.dst_addr)),
1997         },
1998         [ITEM_IPV6] = {
1999                 .name = "ipv6",
2000                 .help = "match IPv6 header",
2001                 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
2002                 .next = NEXT(item_ipv6),
2003                 .call = parse_vc,
2004         },
2005         [ITEM_IPV6_TC] = {
2006                 .name = "tc",
2007                 .help = "traffic class",
2008                 .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
2009                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
2010                                                   hdr.vtc_flow,
2011                                                   "\x0f\xf0\x00\x00")),
2012         },
2013         [ITEM_IPV6_FLOW] = {
2014                 .name = "flow",
2015                 .help = "flow label",
2016                 .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
2017                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
2018                                                   hdr.vtc_flow,
2019                                                   "\x00\x0f\xff\xff")),
2020         },
2021         [ITEM_IPV6_PROTO] = {
2022                 .name = "proto",
2023                 .help = "protocol (next header)",
2024                 .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
2025                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2026                                              hdr.proto)),
2027         },
2028         [ITEM_IPV6_HOP] = {
2029                 .name = "hop",
2030                 .help = "hop limit",
2031                 .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
2032                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2033                                              hdr.hop_limits)),
2034         },
2035         [ITEM_IPV6_SRC] = {
2036                 .name = "src",
2037                 .help = "source address",
2038                 .next = NEXT(item_ipv6, NEXT_ENTRY(IPV6_ADDR), item_param),
2039                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2040                                              hdr.src_addr)),
2041         },
2042         [ITEM_IPV6_DST] = {
2043                 .name = "dst",
2044                 .help = "destination address",
2045                 .next = NEXT(item_ipv6, NEXT_ENTRY(IPV6_ADDR), item_param),
2046                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2047                                              hdr.dst_addr)),
2048         },
2049         [ITEM_ICMP] = {
2050                 .name = "icmp",
2051                 .help = "match ICMP header",
2052                 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
2053                 .next = NEXT(item_icmp),
2054                 .call = parse_vc,
2055         },
2056         [ITEM_ICMP_TYPE] = {
2057                 .name = "type",
2058                 .help = "ICMP packet type",
2059                 .next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
2060                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
2061                                              hdr.icmp_type)),
2062         },
2063         [ITEM_ICMP_CODE] = {
2064                 .name = "code",
2065                 .help = "ICMP packet code",
2066                 .next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
2067                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
2068                                              hdr.icmp_code)),
2069         },
2070         [ITEM_UDP] = {
2071                 .name = "udp",
2072                 .help = "match UDP header",
2073                 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
2074                 .next = NEXT(item_udp),
2075                 .call = parse_vc,
2076         },
2077         [ITEM_UDP_SRC] = {
2078                 .name = "src",
2079                 .help = "UDP source port",
2080                 .next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
2081                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
2082                                              hdr.src_port)),
2083         },
2084         [ITEM_UDP_DST] = {
2085                 .name = "dst",
2086                 .help = "UDP destination port",
2087                 .next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
2088                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
2089                                              hdr.dst_port)),
2090         },
2091         [ITEM_TCP] = {
2092                 .name = "tcp",
2093                 .help = "match TCP header",
2094                 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
2095                 .next = NEXT(item_tcp),
2096                 .call = parse_vc,
2097         },
2098         [ITEM_TCP_SRC] = {
2099                 .name = "src",
2100                 .help = "TCP source port",
2101                 .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
2102                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
2103                                              hdr.src_port)),
2104         },
2105         [ITEM_TCP_DST] = {
2106                 .name = "dst",
2107                 .help = "TCP destination port",
2108                 .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
2109                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
2110                                              hdr.dst_port)),
2111         },
2112         [ITEM_TCP_FLAGS] = {
2113                 .name = "flags",
2114                 .help = "TCP flags",
2115                 .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
2116                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
2117                                              hdr.tcp_flags)),
2118         },
2119         [ITEM_SCTP] = {
2120                 .name = "sctp",
2121                 .help = "match SCTP header",
2122                 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
2123                 .next = NEXT(item_sctp),
2124                 .call = parse_vc,
2125         },
2126         [ITEM_SCTP_SRC] = {
2127                 .name = "src",
2128                 .help = "SCTP source port",
2129                 .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
2130                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2131                                              hdr.src_port)),
2132         },
2133         [ITEM_SCTP_DST] = {
2134                 .name = "dst",
2135                 .help = "SCTP destination port",
2136                 .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
2137                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2138                                              hdr.dst_port)),
2139         },
2140         [ITEM_SCTP_TAG] = {
2141                 .name = "tag",
2142                 .help = "validation tag",
2143                 .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
2144                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2145                                              hdr.tag)),
2146         },
2147         [ITEM_SCTP_CKSUM] = {
2148                 .name = "cksum",
2149                 .help = "checksum",
2150                 .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
2151                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2152                                              hdr.cksum)),
2153         },
2154         [ITEM_VXLAN] = {
2155                 .name = "vxlan",
2156                 .help = "match VXLAN header",
2157                 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
2158                 .next = NEXT(item_vxlan),
2159                 .call = parse_vc,
2160         },
2161         [ITEM_VXLAN_VNI] = {
2162                 .name = "vni",
2163                 .help = "VXLAN identifier",
2164                 .next = NEXT(item_vxlan, NEXT_ENTRY(UNSIGNED), item_param),
2165                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)),
2166         },
2167         [ITEM_E_TAG] = {
2168                 .name = "e_tag",
2169                 .help = "match E-Tag header",
2170                 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
2171                 .next = NEXT(item_e_tag),
2172                 .call = parse_vc,
2173         },
2174         [ITEM_E_TAG_GRP_ECID_B] = {
2175                 .name = "grp_ecid_b",
2176                 .help = "GRP and E-CID base",
2177                 .next = NEXT(item_e_tag, NEXT_ENTRY(UNSIGNED), item_param),
2178                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag,
2179                                                   rsvd_grp_ecid_b,
2180                                                   "\x3f\xff")),
2181         },
2182         [ITEM_NVGRE] = {
2183                 .name = "nvgre",
2184                 .help = "match NVGRE header",
2185                 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
2186                 .next = NEXT(item_nvgre),
2187                 .call = parse_vc,
2188         },
2189         [ITEM_NVGRE_TNI] = {
2190                 .name = "tni",
2191                 .help = "virtual subnet ID",
2192                 .next = NEXT(item_nvgre, NEXT_ENTRY(UNSIGNED), item_param),
2193                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)),
2194         },
2195         [ITEM_MPLS] = {
2196                 .name = "mpls",
2197                 .help = "match MPLS header",
2198                 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
2199                 .next = NEXT(item_mpls),
2200                 .call = parse_vc,
2201         },
2202         [ITEM_MPLS_LABEL] = {
2203                 .name = "label",
2204                 .help = "MPLS label",
2205                 .next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param),
2206                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
2207                                                   label_tc_s,
2208                                                   "\xff\xff\xf0")),
2209         },
2210         [ITEM_MPLS_TC] = {
2211                 .name = "tc",
2212                 .help = "MPLS Traffic Class",
2213                 .next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param),
2214                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
2215                                                   label_tc_s,
2216                                                   "\x00\x00\x0e")),
2217         },
2218         [ITEM_MPLS_S] = {
2219                 .name = "s",
2220                 .help = "MPLS Bottom-of-Stack",
2221                 .next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param),
2222                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
2223                                                   label_tc_s,
2224                                                   "\x00\x00\x01")),
2225         },
2226         [ITEM_GRE] = {
2227                 .name = "gre",
2228                 .help = "match GRE header",
2229                 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
2230                 .next = NEXT(item_gre),
2231                 .call = parse_vc,
2232         },
2233         [ITEM_GRE_PROTO] = {
2234                 .name = "protocol",
2235                 .help = "GRE protocol type",
2236                 .next = NEXT(item_gre, NEXT_ENTRY(UNSIGNED), item_param),
2237                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
2238                                              protocol)),
2239         },
2240         [ITEM_GRE_C_RSVD0_VER] = {
2241                 .name = "c_rsvd0_ver",
2242                 .help =
2243                         "checksum (1b), undefined (1b), key bit (1b),"
2244                         " sequence number (1b), reserved 0 (9b),"
2245                         " version (3b)",
2246                 .next = NEXT(item_gre, NEXT_ENTRY(UNSIGNED), item_param),
2247                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
2248                                              c_rsvd0_ver)),
2249         },
2250         [ITEM_GRE_C_BIT] = {
2251                 .name = "c_bit",
2252                 .help = "checksum bit (C)",
2253                 .next = NEXT(item_gre, NEXT_ENTRY(BOOLEAN), item_param),
2254                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
2255                                                   c_rsvd0_ver,
2256                                                   "\x80\x00\x00\x00")),
2257         },
2258         [ITEM_GRE_S_BIT] = {
2259                 .name = "s_bit",
2260                 .help = "sequence number bit (S)",
2261                 .next = NEXT(item_gre, NEXT_ENTRY(BOOLEAN), item_param),
2262                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
2263                                                   c_rsvd0_ver,
2264                                                   "\x10\x00\x00\x00")),
2265         },
2266         [ITEM_GRE_K_BIT] = {
2267                 .name = "k_bit",
2268                 .help = "key bit (K)",
2269                 .next = NEXT(item_gre, NEXT_ENTRY(BOOLEAN), item_param),
2270                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
2271                                                   c_rsvd0_ver,
2272                                                   "\x20\x00\x00\x00")),
2273         },
2274         [ITEM_FUZZY] = {
2275                 .name = "fuzzy",
2276                 .help = "fuzzy pattern match, expect faster than default",
2277                 .priv = PRIV_ITEM(FUZZY,
2278                                 sizeof(struct rte_flow_item_fuzzy)),
2279                 .next = NEXT(item_fuzzy),
2280                 .call = parse_vc,
2281         },
2282         [ITEM_FUZZY_THRESH] = {
2283                 .name = "thresh",
2284                 .help = "match accuracy threshold",
2285                 .next = NEXT(item_fuzzy, NEXT_ENTRY(UNSIGNED), item_param),
2286                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy,
2287                                         thresh)),
2288         },
2289         [ITEM_GTP] = {
2290                 .name = "gtp",
2291                 .help = "match GTP header",
2292                 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)),
2293                 .next = NEXT(item_gtp),
2294                 .call = parse_vc,
2295         },
2296         [ITEM_GTP_TEID] = {
2297                 .name = "teid",
2298                 .help = "tunnel endpoint identifier",
2299                 .next = NEXT(item_gtp, NEXT_ENTRY(UNSIGNED), item_param),
2300                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, teid)),
2301         },
2302         [ITEM_GTPC] = {
2303                 .name = "gtpc",
2304                 .help = "match GTP header",
2305                 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
2306                 .next = NEXT(item_gtp),
2307                 .call = parse_vc,
2308         },
2309         [ITEM_GTPU] = {
2310                 .name = "gtpu",
2311                 .help = "match GTP header",
2312                 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)),
2313                 .next = NEXT(item_gtp),
2314                 .call = parse_vc,
2315         },
2316         [ITEM_GENEVE] = {
2317                 .name = "geneve",
2318                 .help = "match GENEVE header",
2319                 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
2320                 .next = NEXT(item_geneve),
2321                 .call = parse_vc,
2322         },
2323         [ITEM_GENEVE_VNI] = {
2324                 .name = "vni",
2325                 .help = "virtual network identifier",
2326                 .next = NEXT(item_geneve, NEXT_ENTRY(UNSIGNED), item_param),
2327                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)),
2328         },
2329         [ITEM_GENEVE_PROTO] = {
2330                 .name = "protocol",
2331                 .help = "GENEVE protocol type",
2332                 .next = NEXT(item_geneve, NEXT_ENTRY(UNSIGNED), item_param),
2333                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve,
2334                                              protocol)),
2335         },
2336         [ITEM_VXLAN_GPE] = {
2337                 .name = "vxlan-gpe",
2338                 .help = "match VXLAN-GPE header",
2339                 .priv = PRIV_ITEM(VXLAN_GPE,
2340                                   sizeof(struct rte_flow_item_vxlan_gpe)),
2341                 .next = NEXT(item_vxlan_gpe),
2342                 .call = parse_vc,
2343         },
2344         [ITEM_VXLAN_GPE_VNI] = {
2345                 .name = "vni",
2346                 .help = "VXLAN-GPE identifier",
2347                 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(UNSIGNED), item_param),
2348                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe,
2349                                              vni)),
2350         },
2351         [ITEM_ARP_ETH_IPV4] = {
2352                 .name = "arp_eth_ipv4",
2353                 .help = "match ARP header for Ethernet/IPv4",
2354                 .priv = PRIV_ITEM(ARP_ETH_IPV4,
2355                                   sizeof(struct rte_flow_item_arp_eth_ipv4)),
2356                 .next = NEXT(item_arp_eth_ipv4),
2357                 .call = parse_vc,
2358         },
2359         [ITEM_ARP_ETH_IPV4_SHA] = {
2360                 .name = "sha",
2361                 .help = "sender hardware address",
2362                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(MAC_ADDR),
2363                              item_param),
2364                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
2365                                              sha)),
2366         },
2367         [ITEM_ARP_ETH_IPV4_SPA] = {
2368                 .name = "spa",
2369                 .help = "sender IPv4 address",
2370                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(IPV4_ADDR),
2371                              item_param),
2372                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
2373                                              spa)),
2374         },
2375         [ITEM_ARP_ETH_IPV4_THA] = {
2376                 .name = "tha",
2377                 .help = "target hardware address",
2378                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(MAC_ADDR),
2379                              item_param),
2380                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
2381                                              tha)),
2382         },
2383         [ITEM_ARP_ETH_IPV4_TPA] = {
2384                 .name = "tpa",
2385                 .help = "target IPv4 address",
2386                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(IPV4_ADDR),
2387                              item_param),
2388                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
2389                                              tpa)),
2390         },
2391         [ITEM_IPV6_EXT] = {
2392                 .name = "ipv6_ext",
2393                 .help = "match presence of any IPv6 extension header",
2394                 .priv = PRIV_ITEM(IPV6_EXT,
2395                                   sizeof(struct rte_flow_item_ipv6_ext)),
2396                 .next = NEXT(item_ipv6_ext),
2397                 .call = parse_vc,
2398         },
2399         [ITEM_IPV6_EXT_NEXT_HDR] = {
2400                 .name = "next_hdr",
2401                 .help = "next header",
2402                 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(UNSIGNED), item_param),
2403                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext,
2404                                              next_hdr)),
2405         },
2406         [ITEM_ICMP6] = {
2407                 .name = "icmp6",
2408                 .help = "match any ICMPv6 header",
2409                 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)),
2410                 .next = NEXT(item_icmp6),
2411                 .call = parse_vc,
2412         },
2413         [ITEM_ICMP6_TYPE] = {
2414                 .name = "type",
2415                 .help = "ICMPv6 type",
2416                 .next = NEXT(item_icmp6, NEXT_ENTRY(UNSIGNED), item_param),
2417                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6,
2418                                              type)),
2419         },
2420         [ITEM_ICMP6_CODE] = {
2421                 .name = "code",
2422                 .help = "ICMPv6 code",
2423                 .next = NEXT(item_icmp6, NEXT_ENTRY(UNSIGNED), item_param),
2424                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6,
2425                                              code)),
2426         },
2427         [ITEM_ICMP6_ND_NS] = {
2428                 .name = "icmp6_nd_ns",
2429                 .help = "match ICMPv6 neighbor discovery solicitation",
2430                 .priv = PRIV_ITEM(ICMP6_ND_NS,
2431                                   sizeof(struct rte_flow_item_icmp6_nd_ns)),
2432                 .next = NEXT(item_icmp6_nd_ns),
2433                 .call = parse_vc,
2434         },
2435         [ITEM_ICMP6_ND_NS_TARGET_ADDR] = {
2436                 .name = "target_addr",
2437                 .help = "target address",
2438                 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(IPV6_ADDR),
2439                              item_param),
2440                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns,
2441                                              target_addr)),
2442         },
2443         [ITEM_ICMP6_ND_NA] = {
2444                 .name = "icmp6_nd_na",
2445                 .help = "match ICMPv6 neighbor discovery advertisement",
2446                 .priv = PRIV_ITEM(ICMP6_ND_NA,
2447                                   sizeof(struct rte_flow_item_icmp6_nd_na)),
2448                 .next = NEXT(item_icmp6_nd_na),
2449                 .call = parse_vc,
2450         },
2451         [ITEM_ICMP6_ND_NA_TARGET_ADDR] = {
2452                 .name = "target_addr",
2453                 .help = "target address",
2454                 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(IPV6_ADDR),
2455                              item_param),
2456                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na,
2457                                              target_addr)),
2458         },
2459         [ITEM_ICMP6_ND_OPT] = {
2460                 .name = "icmp6_nd_opt",
2461                 .help = "match presence of any ICMPv6 neighbor discovery"
2462                         " option",
2463                 .priv = PRIV_ITEM(ICMP6_ND_OPT,
2464                                   sizeof(struct rte_flow_item_icmp6_nd_opt)),
2465                 .next = NEXT(item_icmp6_nd_opt),
2466                 .call = parse_vc,
2467         },
2468         [ITEM_ICMP6_ND_OPT_TYPE] = {
2469                 .name = "type",
2470                 .help = "ND option type",
2471                 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(UNSIGNED),
2472                              item_param),
2473                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt,
2474                                              type)),
2475         },
2476         [ITEM_ICMP6_ND_OPT_SLA_ETH] = {
2477                 .name = "icmp6_nd_opt_sla_eth",
2478                 .help = "match ICMPv6 neighbor discovery source Ethernet"
2479                         " link-layer address option",
2480                 .priv = PRIV_ITEM
2481                         (ICMP6_ND_OPT_SLA_ETH,
2482                          sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)),
2483                 .next = NEXT(item_icmp6_nd_opt_sla_eth),
2484                 .call = parse_vc,
2485         },
2486         [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = {
2487                 .name = "sla",
2488                 .help = "source Ethernet LLA",
2489                 .next = NEXT(item_icmp6_nd_opt_sla_eth, NEXT_ENTRY(MAC_ADDR),
2490                              item_param),
2491                 .args = ARGS(ARGS_ENTRY_HTON
2492                              (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)),
2493         },
2494         [ITEM_ICMP6_ND_OPT_TLA_ETH] = {
2495                 .name = "icmp6_nd_opt_tla_eth",
2496                 .help = "match ICMPv6 neighbor discovery target Ethernet"
2497                         " link-layer address option",
2498                 .priv = PRIV_ITEM
2499                         (ICMP6_ND_OPT_TLA_ETH,
2500                          sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)),
2501                 .next = NEXT(item_icmp6_nd_opt_tla_eth),
2502                 .call = parse_vc,
2503         },
2504         [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = {
2505                 .name = "tla",
2506                 .help = "target Ethernet LLA",
2507                 .next = NEXT(item_icmp6_nd_opt_tla_eth, NEXT_ENTRY(MAC_ADDR),
2508                              item_param),
2509                 .args = ARGS(ARGS_ENTRY_HTON
2510                              (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)),
2511         },
2512         [ITEM_META] = {
2513                 .name = "meta",
2514                 .help = "match metadata header",
2515                 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)),
2516                 .next = NEXT(item_meta),
2517                 .call = parse_vc,
2518         },
2519         [ITEM_META_DATA] = {
2520                 .name = "data",
2521                 .help = "metadata value",
2522                 .next = NEXT(item_meta, NEXT_ENTRY(UNSIGNED), item_param),
2523                 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta,
2524                                              data, "\xff\xff\xff\xff")),
2525         },
2526         [ITEM_GRE_KEY] = {
2527                 .name = "gre_key",
2528                 .help = "match GRE key",
2529                 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)),
2530                 .next = NEXT(item_gre_key),
2531                 .call = parse_vc,
2532         },
2533         [ITEM_GRE_KEY_VALUE] = {
2534                 .name = "value",
2535                 .help = "key value",
2536                 .next = NEXT(item_gre_key, NEXT_ENTRY(UNSIGNED), item_param),
2537                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
2538         },
2539         [ITEM_GTP_PSC] = {
2540                 .name = "gtp_psc",
2541                 .help = "match GTP extension header with type 0x85",
2542                 .priv = PRIV_ITEM(GTP_PSC,
2543                                 sizeof(struct rte_flow_item_gtp_psc)),
2544                 .next = NEXT(item_gtp_psc),
2545                 .call = parse_vc,
2546         },
2547         [ITEM_GTP_PSC_QFI] = {
2548                 .name = "qfi",
2549                 .help = "QoS flow identifier",
2550                 .next = NEXT(item_gtp_psc, NEXT_ENTRY(UNSIGNED), item_param),
2551                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp_psc,
2552                                         qfi)),
2553         },
2554         [ITEM_GTP_PSC_PDU_T] = {
2555                 .name = "pdu_t",
2556                 .help = "PDU type",
2557                 .next = NEXT(item_gtp_psc, NEXT_ENTRY(UNSIGNED), item_param),
2558                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp_psc,
2559                                         pdu_type)),
2560         },
2561         [ITEM_PPPOES] = {
2562                 .name = "pppoes",
2563                 .help = "match PPPoE session header",
2564                 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)),
2565                 .next = NEXT(item_pppoes),
2566                 .call = parse_vc,
2567         },
2568         [ITEM_PPPOED] = {
2569                 .name = "pppoed",
2570                 .help = "match PPPoE discovery header",
2571                 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)),
2572                 .next = NEXT(item_pppoed),
2573                 .call = parse_vc,
2574         },
2575         [ITEM_PPPOE_SEID] = {
2576                 .name = "seid",
2577                 .help = "session identifier",
2578                 .next = NEXT(item_pppoes, NEXT_ENTRY(UNSIGNED), item_param),
2579                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe,
2580                                         session_id)),
2581         },
2582         [ITEM_PPPOE_PROTO_ID] = {
2583                 .name = "proto_id",
2584                 .help = "match PPPoE session protocol identifier",
2585                 .priv = PRIV_ITEM(PPPOE_PROTO_ID,
2586                                 sizeof(struct rte_flow_item_pppoe_proto_id)),
2587                 .next = NEXT(item_pppoe_proto_id),
2588                 .call = parse_vc,
2589         },
2590         [ITEM_HIGIG2] = {
2591                 .name = "higig2",
2592                 .help = "matches higig2 header",
2593                 .priv = PRIV_ITEM(HIGIG2,
2594                                 sizeof(struct rte_flow_item_higig2_hdr)),
2595                 .next = NEXT(item_higig2),
2596                 .call = parse_vc,
2597         },
2598         [ITEM_HIGIG2_CLASSIFICATION] = {
2599                 .name = "classification",
2600                 .help = "matches classification of higig2 header",
2601                 .next = NEXT(item_higig2, NEXT_ENTRY(UNSIGNED), item_param),
2602                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr,
2603                                         hdr.ppt1.classification)),
2604         },
2605         [ITEM_HIGIG2_VID] = {
2606                 .name = "vid",
2607                 .help = "matches vid of higig2 header",
2608                 .next = NEXT(item_higig2, NEXT_ENTRY(UNSIGNED), item_param),
2609                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr,
2610                                         hdr.ppt1.vid)),
2611         },
2612         [ITEM_TAG] = {
2613                 .name = "tag",
2614                 .help = "match tag value",
2615                 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)),
2616                 .next = NEXT(item_tag),
2617                 .call = parse_vc,
2618         },
2619         [ITEM_TAG_DATA] = {
2620                 .name = "data",
2621                 .help = "tag value to match",
2622                 .next = NEXT(item_tag, NEXT_ENTRY(UNSIGNED), item_param),
2623                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)),
2624         },
2625         [ITEM_TAG_INDEX] = {
2626                 .name = "index",
2627                 .help = "index of tag array to match",
2628                 .next = NEXT(item_tag, NEXT_ENTRY(UNSIGNED),
2629                              NEXT_ENTRY(ITEM_PARAM_IS)),
2630                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)),
2631         },
2632         [ITEM_L2TPV3OIP] = {
2633                 .name = "l2tpv3oip",
2634                 .help = "match L2TPv3 over IP header",
2635                 .priv = PRIV_ITEM(L2TPV3OIP,
2636                                   sizeof(struct rte_flow_item_l2tpv3oip)),
2637                 .next = NEXT(item_l2tpv3oip),
2638                 .call = parse_vc,
2639         },
2640         [ITEM_L2TPV3OIP_SESSION_ID] = {
2641                 .name = "session_id",
2642                 .help = "session identifier",
2643                 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(UNSIGNED), item_param),
2644                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip,
2645                                              session_id)),
2646         },
2647         [ITEM_ESP] = {
2648                 .name = "esp",
2649                 .help = "match ESP header",
2650                 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)),
2651                 .next = NEXT(item_esp),
2652                 .call = parse_vc,
2653         },
2654         [ITEM_ESP_SPI] = {
2655                 .name = "spi",
2656                 .help = "security policy index",
2657                 .next = NEXT(item_esp, NEXT_ENTRY(UNSIGNED), item_param),
2658                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp,
2659                                 hdr.spi)),
2660         },
2661         /* Validate/create actions. */
2662         [ACTIONS] = {
2663                 .name = "actions",
2664                 .help = "submit a list of associated actions",
2665                 .next = NEXT(next_action),
2666                 .call = parse_vc,
2667         },
2668         [ACTION_NEXT] = {
2669                 .name = "/",
2670                 .help = "specify next action",
2671                 .next = NEXT(next_action),
2672         },
2673         [ACTION_END] = {
2674                 .name = "end",
2675                 .help = "end list of actions",
2676                 .priv = PRIV_ACTION(END, 0),
2677                 .call = parse_vc,
2678         },
2679         [ACTION_VOID] = {
2680                 .name = "void",
2681                 .help = "no-op action",
2682                 .priv = PRIV_ACTION(VOID, 0),
2683                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
2684                 .call = parse_vc,
2685         },
2686         [ACTION_PASSTHRU] = {
2687                 .name = "passthru",
2688                 .help = "let subsequent rule process matched packets",
2689                 .priv = PRIV_ACTION(PASSTHRU, 0),
2690                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
2691                 .call = parse_vc,
2692         },
2693         [ACTION_JUMP] = {
2694                 .name = "jump",
2695                 .help = "redirect traffic to a given group",
2696                 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)),
2697                 .next = NEXT(action_jump),
2698                 .call = parse_vc,
2699         },
2700         [ACTION_JUMP_GROUP] = {
2701                 .name = "group",
2702                 .help = "group to redirect traffic to",
2703                 .next = NEXT(action_jump, NEXT_ENTRY(UNSIGNED)),
2704                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)),
2705                 .call = parse_vc_conf,
2706         },
2707         [ACTION_MARK] = {
2708                 .name = "mark",
2709                 .help = "attach 32 bit value to packets",
2710                 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
2711                 .next = NEXT(action_mark),
2712                 .call = parse_vc,
2713         },
2714         [ACTION_MARK_ID] = {
2715                 .name = "id",
2716                 .help = "32 bit value to return with packets",
2717                 .next = NEXT(action_mark, NEXT_ENTRY(UNSIGNED)),
2718                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)),
2719                 .call = parse_vc_conf,
2720         },
2721         [ACTION_FLAG] = {
2722                 .name = "flag",
2723                 .help = "flag packets",
2724                 .priv = PRIV_ACTION(FLAG, 0),
2725                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
2726                 .call = parse_vc,
2727         },
2728         [ACTION_QUEUE] = {
2729                 .name = "queue",
2730                 .help = "assign packets to a given queue index",
2731                 .priv = PRIV_ACTION(QUEUE,
2732                                     sizeof(struct rte_flow_action_queue)),
2733                 .next = NEXT(action_queue),
2734                 .call = parse_vc,
2735         },
2736         [ACTION_QUEUE_INDEX] = {
2737                 .name = "index",
2738                 .help = "queue index to use",
2739                 .next = NEXT(action_queue, NEXT_ENTRY(UNSIGNED)),
2740                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
2741                 .call = parse_vc_conf,
2742         },
2743         [ACTION_DROP] = {
2744                 .name = "drop",
2745                 .help = "drop packets (note: passthru has priority)",
2746                 .priv = PRIV_ACTION(DROP, 0),
2747                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
2748                 .call = parse_vc,
2749         },
2750         [ACTION_COUNT] = {
2751                 .name = "count",
2752                 .help = "enable counters for this rule",
2753                 .priv = PRIV_ACTION(COUNT,
2754                                     sizeof(struct rte_flow_action_count)),
2755                 .next = NEXT(action_count),
2756                 .call = parse_vc,
2757         },
2758         [ACTION_COUNT_ID] = {
2759                 .name = "identifier",
2760                 .help = "counter identifier to use",
2761                 .next = NEXT(action_count, NEXT_ENTRY(UNSIGNED)),
2762                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)),
2763                 .call = parse_vc_conf,
2764         },
2765         [ACTION_COUNT_SHARED] = {
2766                 .name = "shared",
2767                 .help = "shared counter",
2768                 .next = NEXT(action_count, NEXT_ENTRY(BOOLEAN)),
2769                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_count,
2770                                            shared, 1)),
2771                 .call = parse_vc_conf,
2772         },
2773         [ACTION_RSS] = {
2774                 .name = "rss",
2775                 .help = "spread packets among several queues",
2776                 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)),
2777                 .next = NEXT(action_rss),
2778                 .call = parse_vc_action_rss,
2779         },
2780         [ACTION_RSS_FUNC] = {
2781                 .name = "func",
2782                 .help = "RSS hash function to apply",
2783                 .next = NEXT(action_rss,
2784                              NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT,
2785                                         ACTION_RSS_FUNC_TOEPLITZ,
2786                                         ACTION_RSS_FUNC_SIMPLE_XOR,
2787                                         ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)),
2788         },
2789         [ACTION_RSS_FUNC_DEFAULT] = {
2790                 .name = "default",
2791                 .help = "default hash function",
2792                 .call = parse_vc_action_rss_func,
2793         },
2794         [ACTION_RSS_FUNC_TOEPLITZ] = {
2795                 .name = "toeplitz",
2796                 .help = "Toeplitz hash function",
2797                 .call = parse_vc_action_rss_func,
2798         },
2799         [ACTION_RSS_FUNC_SIMPLE_XOR] = {
2800                 .name = "simple_xor",
2801                 .help = "simple XOR hash function",
2802                 .call = parse_vc_action_rss_func,
2803         },
2804         [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = {
2805                 .name = "symmetric_toeplitz",
2806                 .help = "Symmetric Toeplitz hash function",
2807                 .call = parse_vc_action_rss_func,
2808         },
2809         [ACTION_RSS_LEVEL] = {
2810                 .name = "level",
2811                 .help = "encapsulation level for \"types\"",
2812                 .next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
2813                 .args = ARGS(ARGS_ENTRY_ARB
2814                              (offsetof(struct action_rss_data, conf) +
2815                               offsetof(struct rte_flow_action_rss, level),
2816                               sizeof(((struct rte_flow_action_rss *)0)->
2817                                      level))),
2818         },
2819         [ACTION_RSS_TYPES] = {
2820                 .name = "types",
2821                 .help = "specific RSS hash types",
2822                 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)),
2823         },
2824         [ACTION_RSS_TYPE] = {
2825                 .name = "{type}",
2826                 .help = "RSS hash type",
2827                 .call = parse_vc_action_rss_type,
2828                 .comp = comp_vc_action_rss_type,
2829         },
2830         [ACTION_RSS_KEY] = {
2831                 .name = "key",
2832                 .help = "RSS hash key",
2833                 .next = NEXT(action_rss, NEXT_ENTRY(HEX)),
2834                 .args = ARGS(ARGS_ENTRY_ARB(0, 0),
2835                              ARGS_ENTRY_ARB
2836                              (offsetof(struct action_rss_data, conf) +
2837                               offsetof(struct rte_flow_action_rss, key_len),
2838                               sizeof(((struct rte_flow_action_rss *)0)->
2839                                      key_len)),
2840                              ARGS_ENTRY(struct action_rss_data, key)),
2841         },
2842         [ACTION_RSS_KEY_LEN] = {
2843                 .name = "key_len",
2844                 .help = "RSS hash key length in bytes",
2845                 .next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
2846                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
2847                              (offsetof(struct action_rss_data, conf) +
2848                               offsetof(struct rte_flow_action_rss, key_len),
2849                               sizeof(((struct rte_flow_action_rss *)0)->
2850                                      key_len),
2851                               0,
2852                               RSS_HASH_KEY_LENGTH)),
2853         },
2854         [ACTION_RSS_QUEUES] = {
2855                 .name = "queues",
2856                 .help = "queue indices to use",
2857                 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)),
2858                 .call = parse_vc_conf,
2859         },
2860         [ACTION_RSS_QUEUE] = {
2861                 .name = "{queue}",
2862                 .help = "queue index",
2863                 .call = parse_vc_action_rss_queue,
2864                 .comp = comp_vc_action_rss_queue,
2865         },
2866         [ACTION_PF] = {
2867                 .name = "pf",
2868                 .help = "direct traffic to physical function",
2869                 .priv = PRIV_ACTION(PF, 0),
2870                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
2871                 .call = parse_vc,
2872         },
2873         [ACTION_VF] = {
2874                 .name = "vf",
2875                 .help = "direct traffic to a virtual function ID",
2876                 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)),
2877                 .next = NEXT(action_vf),
2878                 .call = parse_vc,
2879         },
2880         [ACTION_VF_ORIGINAL] = {
2881                 .name = "original",
2882                 .help = "use original VF ID if possible",
2883                 .next = NEXT(action_vf, NEXT_ENTRY(BOOLEAN)),
2884                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf,
2885                                            original, 1)),
2886                 .call = parse_vc_conf,
2887         },
2888         [ACTION_VF_ID] = {
2889                 .name = "id",
2890                 .help = "VF ID",
2891                 .next = NEXT(action_vf, NEXT_ENTRY(UNSIGNED)),
2892                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)),
2893                 .call = parse_vc_conf,
2894         },
2895         [ACTION_PHY_PORT] = {
2896                 .name = "phy_port",
2897                 .help = "direct packets to physical port index",
2898                 .priv = PRIV_ACTION(PHY_PORT,
2899                                     sizeof(struct rte_flow_action_phy_port)),
2900                 .next = NEXT(action_phy_port),
2901                 .call = parse_vc,
2902         },
2903         [ACTION_PHY_PORT_ORIGINAL] = {
2904                 .name = "original",
2905                 .help = "use original port index if possible",
2906                 .next = NEXT(action_phy_port, NEXT_ENTRY(BOOLEAN)),
2907                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_phy_port,
2908                                            original, 1)),
2909                 .call = parse_vc_conf,
2910         },
2911         [ACTION_PHY_PORT_INDEX] = {
2912                 .name = "index",
2913                 .help = "physical port index",
2914                 .next = NEXT(action_phy_port, NEXT_ENTRY(UNSIGNED)),
2915                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_phy_port,
2916                                         index)),
2917                 .call = parse_vc_conf,
2918         },
2919         [ACTION_PORT_ID] = {
2920                 .name = "port_id",
2921                 .help = "direct matching traffic to a given DPDK port ID",
2922                 .priv = PRIV_ACTION(PORT_ID,
2923                                     sizeof(struct rte_flow_action_port_id)),
2924                 .next = NEXT(action_port_id),
2925                 .call = parse_vc,
2926         },
2927         [ACTION_PORT_ID_ORIGINAL] = {
2928                 .name = "original",
2929                 .help = "use original DPDK port ID if possible",
2930                 .next = NEXT(action_port_id, NEXT_ENTRY(BOOLEAN)),
2931                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id,
2932                                            original, 1)),
2933                 .call = parse_vc_conf,
2934         },
2935         [ACTION_PORT_ID_ID] = {
2936                 .name = "id",
2937                 .help = "DPDK port ID",
2938                 .next = NEXT(action_port_id, NEXT_ENTRY(UNSIGNED)),
2939                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)),
2940                 .call = parse_vc_conf,
2941         },
2942         [ACTION_METER] = {
2943                 .name = "meter",
2944                 .help = "meter the directed packets at given id",
2945                 .priv = PRIV_ACTION(METER,
2946                                     sizeof(struct rte_flow_action_meter)),
2947                 .next = NEXT(action_meter),
2948                 .call = parse_vc,
2949         },
2950         [ACTION_METER_ID] = {
2951                 .name = "mtr_id",
2952                 .help = "meter id to use",
2953                 .next = NEXT(action_meter, NEXT_ENTRY(UNSIGNED)),
2954                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)),
2955                 .call = parse_vc_conf,
2956         },
2957         [ACTION_OF_SET_MPLS_TTL] = {
2958                 .name = "of_set_mpls_ttl",
2959                 .help = "OpenFlow's OFPAT_SET_MPLS_TTL",
2960                 .priv = PRIV_ACTION
2961                         (OF_SET_MPLS_TTL,
2962                          sizeof(struct rte_flow_action_of_set_mpls_ttl)),
2963                 .next = NEXT(action_of_set_mpls_ttl),
2964                 .call = parse_vc,
2965         },
2966         [ACTION_OF_SET_MPLS_TTL_MPLS_TTL] = {
2967                 .name = "mpls_ttl",
2968                 .help = "MPLS TTL",
2969                 .next = NEXT(action_of_set_mpls_ttl, NEXT_ENTRY(UNSIGNED)),
2970                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_set_mpls_ttl,
2971                                         mpls_ttl)),
2972                 .call = parse_vc_conf,
2973         },
2974         [ACTION_OF_DEC_MPLS_TTL] = {
2975                 .name = "of_dec_mpls_ttl",
2976                 .help = "OpenFlow's OFPAT_DEC_MPLS_TTL",
2977                 .priv = PRIV_ACTION(OF_DEC_MPLS_TTL, 0),
2978                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
2979                 .call = parse_vc,
2980         },
2981         [ACTION_OF_SET_NW_TTL] = {
2982                 .name = "of_set_nw_ttl",
2983                 .help = "OpenFlow's OFPAT_SET_NW_TTL",
2984                 .priv = PRIV_ACTION
2985                         (OF_SET_NW_TTL,
2986                          sizeof(struct rte_flow_action_of_set_nw_ttl)),
2987                 .next = NEXT(action_of_set_nw_ttl),
2988                 .call = parse_vc,
2989         },
2990         [ACTION_OF_SET_NW_TTL_NW_TTL] = {
2991                 .name = "nw_ttl",
2992                 .help = "IP TTL",
2993                 .next = NEXT(action_of_set_nw_ttl, NEXT_ENTRY(UNSIGNED)),
2994                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_set_nw_ttl,
2995                                         nw_ttl)),
2996                 .call = parse_vc_conf,
2997         },
2998         [ACTION_OF_DEC_NW_TTL] = {
2999                 .name = "of_dec_nw_ttl",
3000                 .help = "OpenFlow's OFPAT_DEC_NW_TTL",
3001                 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0),
3002                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3003                 .call = parse_vc,
3004         },
3005         [ACTION_OF_COPY_TTL_OUT] = {
3006                 .name = "of_copy_ttl_out",
3007                 .help = "OpenFlow's OFPAT_COPY_TTL_OUT",
3008                 .priv = PRIV_ACTION(OF_COPY_TTL_OUT, 0),
3009                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3010                 .call = parse_vc,
3011         },
3012         [ACTION_OF_COPY_TTL_IN] = {
3013                 .name = "of_copy_ttl_in",
3014                 .help = "OpenFlow's OFPAT_COPY_TTL_IN",
3015                 .priv = PRIV_ACTION(OF_COPY_TTL_IN, 0),
3016                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3017                 .call = parse_vc,
3018         },
3019         [ACTION_OF_POP_VLAN] = {
3020                 .name = "of_pop_vlan",
3021                 .help = "OpenFlow's OFPAT_POP_VLAN",
3022                 .priv = PRIV_ACTION(OF_POP_VLAN, 0),
3023                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3024                 .call = parse_vc,
3025         },
3026         [ACTION_OF_PUSH_VLAN] = {
3027                 .name = "of_push_vlan",
3028                 .help = "OpenFlow's OFPAT_PUSH_VLAN",
3029                 .priv = PRIV_ACTION
3030                         (OF_PUSH_VLAN,
3031                          sizeof(struct rte_flow_action_of_push_vlan)),
3032                 .next = NEXT(action_of_push_vlan),
3033                 .call = parse_vc,
3034         },
3035         [ACTION_OF_PUSH_VLAN_ETHERTYPE] = {
3036                 .name = "ethertype",
3037                 .help = "EtherType",
3038                 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(UNSIGNED)),
3039                 .args = ARGS(ARGS_ENTRY_HTON
3040                              (struct rte_flow_action_of_push_vlan,
3041                               ethertype)),
3042                 .call = parse_vc_conf,
3043         },
3044         [ACTION_OF_SET_VLAN_VID] = {
3045                 .name = "of_set_vlan_vid",
3046                 .help = "OpenFlow's OFPAT_SET_VLAN_VID",
3047                 .priv = PRIV_ACTION
3048                         (OF_SET_VLAN_VID,
3049                          sizeof(struct rte_flow_action_of_set_vlan_vid)),
3050                 .next = NEXT(action_of_set_vlan_vid),
3051                 .call = parse_vc,
3052         },
3053         [ACTION_OF_SET_VLAN_VID_VLAN_VID] = {
3054                 .name = "vlan_vid",
3055                 .help = "VLAN id",
3056                 .next = NEXT(action_of_set_vlan_vid, NEXT_ENTRY(UNSIGNED)),
3057                 .args = ARGS(ARGS_ENTRY_HTON
3058                              (struct rte_flow_action_of_set_vlan_vid,
3059                               vlan_vid)),
3060                 .call = parse_vc_conf,
3061         },
3062         [ACTION_OF_SET_VLAN_PCP] = {
3063                 .name = "of_set_vlan_pcp",
3064                 .help = "OpenFlow's OFPAT_SET_VLAN_PCP",
3065                 .priv = PRIV_ACTION
3066                         (OF_SET_VLAN_PCP,
3067                          sizeof(struct rte_flow_action_of_set_vlan_pcp)),
3068                 .next = NEXT(action_of_set_vlan_pcp),
3069                 .call = parse_vc,
3070         },
3071         [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = {
3072                 .name = "vlan_pcp",
3073                 .help = "VLAN priority",
3074                 .next = NEXT(action_of_set_vlan_pcp, NEXT_ENTRY(UNSIGNED)),
3075                 .args = ARGS(ARGS_ENTRY_HTON
3076                              (struct rte_flow_action_of_set_vlan_pcp,
3077                               vlan_pcp)),
3078                 .call = parse_vc_conf,
3079         },
3080         [ACTION_OF_POP_MPLS] = {
3081                 .name = "of_pop_mpls",
3082                 .help = "OpenFlow's OFPAT_POP_MPLS",
3083                 .priv = PRIV_ACTION(OF_POP_MPLS,
3084                                     sizeof(struct rte_flow_action_of_pop_mpls)),
3085                 .next = NEXT(action_of_pop_mpls),
3086                 .call = parse_vc,
3087         },
3088         [ACTION_OF_POP_MPLS_ETHERTYPE] = {
3089                 .name = "ethertype",
3090                 .help = "EtherType",
3091                 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(UNSIGNED)),
3092                 .args = ARGS(ARGS_ENTRY_HTON
3093                              (struct rte_flow_action_of_pop_mpls,
3094                               ethertype)),
3095                 .call = parse_vc_conf,
3096         },
3097         [ACTION_OF_PUSH_MPLS] = {
3098                 .name = "of_push_mpls",
3099                 .help = "OpenFlow's OFPAT_PUSH_MPLS",
3100                 .priv = PRIV_ACTION
3101                         (OF_PUSH_MPLS,
3102                          sizeof(struct rte_flow_action_of_push_mpls)),
3103                 .next = NEXT(action_of_push_mpls),
3104                 .call = parse_vc,
3105         },
3106         [ACTION_OF_PUSH_MPLS_ETHERTYPE] = {
3107                 .name = "ethertype",
3108                 .help = "EtherType",
3109                 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(UNSIGNED)),
3110                 .args = ARGS(ARGS_ENTRY_HTON
3111                              (struct rte_flow_action_of_push_mpls,
3112                               ethertype)),
3113                 .call = parse_vc_conf,
3114         },
3115         [ACTION_VXLAN_ENCAP] = {
3116                 .name = "vxlan_encap",
3117                 .help = "VXLAN encapsulation, uses configuration set by \"set"
3118                         " vxlan\"",
3119                 .priv = PRIV_ACTION(VXLAN_ENCAP,
3120                                     sizeof(struct action_vxlan_encap_data)),
3121                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3122                 .call = parse_vc_action_vxlan_encap,
3123         },
3124         [ACTION_VXLAN_DECAP] = {
3125                 .name = "vxlan_decap",
3126                 .help = "Performs a decapsulation action by stripping all"
3127                         " headers of the VXLAN tunnel network overlay from the"
3128                         " matched flow.",
3129                 .priv = PRIV_ACTION(VXLAN_DECAP, 0),
3130                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3131                 .call = parse_vc,
3132         },
3133         [ACTION_NVGRE_ENCAP] = {
3134                 .name = "nvgre_encap",
3135                 .help = "NVGRE encapsulation, uses configuration set by \"set"
3136                         " nvgre\"",
3137                 .priv = PRIV_ACTION(NVGRE_ENCAP,
3138                                     sizeof(struct action_nvgre_encap_data)),
3139                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3140                 .call = parse_vc_action_nvgre_encap,
3141         },
3142         [ACTION_NVGRE_DECAP] = {
3143                 .name = "nvgre_decap",
3144                 .help = "Performs a decapsulation action by stripping all"
3145                         " headers of the NVGRE tunnel network overlay from the"
3146                         " matched flow.",
3147                 .priv = PRIV_ACTION(NVGRE_DECAP, 0),
3148                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3149                 .call = parse_vc,
3150         },
3151         [ACTION_L2_ENCAP] = {
3152                 .name = "l2_encap",
3153                 .help = "l2 encap, uses configuration set by"
3154                         " \"set l2_encap\"",
3155                 .priv = PRIV_ACTION(RAW_ENCAP,
3156                                     sizeof(struct action_raw_encap_data)),
3157                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3158                 .call = parse_vc_action_l2_encap,
3159         },
3160         [ACTION_L2_DECAP] = {
3161                 .name = "l2_decap",
3162                 .help = "l2 decap, uses configuration set by"
3163                         " \"set l2_decap\"",
3164                 .priv = PRIV_ACTION(RAW_DECAP,
3165                                     sizeof(struct action_raw_decap_data)),
3166                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3167                 .call = parse_vc_action_l2_decap,
3168         },
3169         [ACTION_MPLSOGRE_ENCAP] = {
3170                 .name = "mplsogre_encap",
3171                 .help = "mplsogre encapsulation, uses configuration set by"
3172                         " \"set mplsogre_encap\"",
3173                 .priv = PRIV_ACTION(RAW_ENCAP,
3174                                     sizeof(struct action_raw_encap_data)),
3175                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3176                 .call = parse_vc_action_mplsogre_encap,
3177         },
3178         [ACTION_MPLSOGRE_DECAP] = {
3179                 .name = "mplsogre_decap",
3180                 .help = "mplsogre decapsulation, uses configuration set by"
3181                         " \"set mplsogre_decap\"",
3182                 .priv = PRIV_ACTION(RAW_DECAP,
3183                                     sizeof(struct action_raw_decap_data)),
3184                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3185                 .call = parse_vc_action_mplsogre_decap,
3186         },
3187         [ACTION_MPLSOUDP_ENCAP] = {
3188                 .name = "mplsoudp_encap",
3189                 .help = "mplsoudp encapsulation, uses configuration set by"
3190                         " \"set mplsoudp_encap\"",
3191                 .priv = PRIV_ACTION(RAW_ENCAP,
3192                                     sizeof(struct action_raw_encap_data)),
3193                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3194                 .call = parse_vc_action_mplsoudp_encap,
3195         },
3196         [ACTION_MPLSOUDP_DECAP] = {
3197                 .name = "mplsoudp_decap",
3198                 .help = "mplsoudp decapsulation, uses configuration set by"
3199                         " \"set mplsoudp_decap\"",
3200                 .priv = PRIV_ACTION(RAW_DECAP,
3201                                     sizeof(struct action_raw_decap_data)),
3202                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3203                 .call = parse_vc_action_mplsoudp_decap,
3204         },
3205         [ACTION_SET_IPV4_SRC] = {
3206                 .name = "set_ipv4_src",
3207                 .help = "Set a new IPv4 source address in the outermost"
3208                         " IPv4 header",
3209                 .priv = PRIV_ACTION(SET_IPV4_SRC,
3210                         sizeof(struct rte_flow_action_set_ipv4)),
3211                 .next = NEXT(action_set_ipv4_src),
3212                 .call = parse_vc,
3213         },
3214         [ACTION_SET_IPV4_SRC_IPV4_SRC] = {
3215                 .name = "ipv4_addr",
3216                 .help = "new IPv4 source address to set",
3217                 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(IPV4_ADDR)),
3218                 .args = ARGS(ARGS_ENTRY_HTON
3219                         (struct rte_flow_action_set_ipv4, ipv4_addr)),
3220                 .call = parse_vc_conf,
3221         },
3222         [ACTION_SET_IPV4_DST] = {
3223                 .name = "set_ipv4_dst",
3224                 .help = "Set a new IPv4 destination address in the outermost"
3225                         " IPv4 header",
3226                 .priv = PRIV_ACTION(SET_IPV4_DST,
3227                         sizeof(struct rte_flow_action_set_ipv4)),
3228                 .next = NEXT(action_set_ipv4_dst),
3229                 .call = parse_vc,
3230         },
3231         [ACTION_SET_IPV4_DST_IPV4_DST] = {
3232                 .name = "ipv4_addr",
3233                 .help = "new IPv4 destination address to set",
3234                 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(IPV4_ADDR)),
3235                 .args = ARGS(ARGS_ENTRY_HTON
3236                         (struct rte_flow_action_set_ipv4, ipv4_addr)),
3237                 .call = parse_vc_conf,
3238         },
3239         [ACTION_SET_IPV6_SRC] = {
3240                 .name = "set_ipv6_src",
3241                 .help = "Set a new IPv6 source address in the outermost"
3242                         " IPv6 header",
3243                 .priv = PRIV_ACTION(SET_IPV6_SRC,
3244                         sizeof(struct rte_flow_action_set_ipv6)),
3245                 .next = NEXT(action_set_ipv6_src),
3246                 .call = parse_vc,
3247         },
3248         [ACTION_SET_IPV6_SRC_IPV6_SRC] = {
3249                 .name = "ipv6_addr",
3250                 .help = "new IPv6 source address to set",
3251                 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(IPV6_ADDR)),
3252                 .args = ARGS(ARGS_ENTRY_HTON
3253                         (struct rte_flow_action_set_ipv6, ipv6_addr)),
3254                 .call = parse_vc_conf,
3255         },
3256         [ACTION_SET_IPV6_DST] = {
3257                 .name = "set_ipv6_dst",
3258                 .help = "Set a new IPv6 destination address in the outermost"
3259                         " IPv6 header",
3260                 .priv = PRIV_ACTION(SET_IPV6_DST,
3261                         sizeof(struct rte_flow_action_set_ipv6)),
3262                 .next = NEXT(action_set_ipv6_dst),
3263                 .call = parse_vc,
3264         },
3265         [ACTION_SET_IPV6_DST_IPV6_DST] = {
3266                 .name = "ipv6_addr",
3267                 .help = "new IPv6 destination address to set",
3268                 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(IPV6_ADDR)),
3269                 .args = ARGS(ARGS_ENTRY_HTON
3270                         (struct rte_flow_action_set_ipv6, ipv6_addr)),
3271                 .call = parse_vc_conf,
3272         },
3273         [ACTION_SET_TP_SRC] = {
3274                 .name = "set_tp_src",
3275                 .help = "set a new source port number in the outermost"
3276                         " TCP/UDP header",
3277                 .priv = PRIV_ACTION(SET_TP_SRC,
3278                         sizeof(struct rte_flow_action_set_tp)),
3279                 .next = NEXT(action_set_tp_src),
3280                 .call = parse_vc,
3281         },
3282         [ACTION_SET_TP_SRC_TP_SRC] = {
3283                 .name = "port",
3284                 .help = "new source port number to set",
3285                 .next = NEXT(action_set_tp_src, NEXT_ENTRY(UNSIGNED)),
3286                 .args = ARGS(ARGS_ENTRY_HTON
3287                              (struct rte_flow_action_set_tp, port)),
3288                 .call = parse_vc_conf,
3289         },
3290         [ACTION_SET_TP_DST] = {
3291                 .name = "set_tp_dst",
3292                 .help = "set a new destination port number in the outermost"
3293                         " TCP/UDP header",
3294                 .priv = PRIV_ACTION(SET_TP_DST,
3295                         sizeof(struct rte_flow_action_set_tp)),
3296                 .next = NEXT(action_set_tp_dst),
3297                 .call = parse_vc,
3298         },
3299         [ACTION_SET_TP_DST_TP_DST] = {
3300                 .name = "port",
3301                 .help = "new destination port number to set",
3302                 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(UNSIGNED)),
3303                 .args = ARGS(ARGS_ENTRY_HTON
3304                              (struct rte_flow_action_set_tp, port)),
3305                 .call = parse_vc_conf,
3306         },
3307         [ACTION_MAC_SWAP] = {
3308                 .name = "mac_swap",
3309                 .help = "Swap the source and destination MAC addresses"
3310                         " in the outermost Ethernet header",
3311                 .priv = PRIV_ACTION(MAC_SWAP, 0),
3312                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3313                 .call = parse_vc,
3314         },
3315         [ACTION_DEC_TTL] = {
3316                 .name = "dec_ttl",
3317                 .help = "decrease network TTL if available",
3318                 .priv = PRIV_ACTION(DEC_TTL, 0),
3319                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3320                 .call = parse_vc,
3321         },
3322         [ACTION_SET_TTL] = {
3323                 .name = "set_ttl",
3324                 .help = "set ttl value",
3325                 .priv = PRIV_ACTION(SET_TTL,
3326                         sizeof(struct rte_flow_action_set_ttl)),
3327                 .next = NEXT(action_set_ttl),
3328                 .call = parse_vc,
3329         },
3330         [ACTION_SET_TTL_TTL] = {
3331                 .name = "ttl_value",
3332                 .help = "new ttl value to set",
3333                 .next = NEXT(action_set_ttl, NEXT_ENTRY(UNSIGNED)),
3334                 .args = ARGS(ARGS_ENTRY_HTON
3335                              (struct rte_flow_action_set_ttl, ttl_value)),
3336                 .call = parse_vc_conf,
3337         },
3338         [ACTION_SET_MAC_SRC] = {
3339                 .name = "set_mac_src",
3340                 .help = "set source mac address",
3341                 .priv = PRIV_ACTION(SET_MAC_SRC,
3342                         sizeof(struct rte_flow_action_set_mac)),
3343                 .next = NEXT(action_set_mac_src),
3344                 .call = parse_vc,
3345         },
3346         [ACTION_SET_MAC_SRC_MAC_SRC] = {
3347                 .name = "mac_addr",
3348                 .help = "new source mac address",
3349                 .next = NEXT(action_set_mac_src, NEXT_ENTRY(MAC_ADDR)),
3350                 .args = ARGS(ARGS_ENTRY_HTON
3351                              (struct rte_flow_action_set_mac, mac_addr)),
3352                 .call = parse_vc_conf,
3353         },
3354         [ACTION_SET_MAC_DST] = {
3355                 .name = "set_mac_dst",
3356                 .help = "set destination mac address",
3357                 .priv = PRIV_ACTION(SET_MAC_DST,
3358                         sizeof(struct rte_flow_action_set_mac)),
3359                 .next = NEXT(action_set_mac_dst),
3360                 .call = parse_vc,
3361         },
3362         [ACTION_SET_MAC_DST_MAC_DST] = {
3363                 .name = "mac_addr",
3364                 .help = "new destination mac address to set",
3365                 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(MAC_ADDR)),
3366                 .args = ARGS(ARGS_ENTRY_HTON
3367                              (struct rte_flow_action_set_mac, mac_addr)),
3368                 .call = parse_vc_conf,
3369         },
3370         [ACTION_INC_TCP_SEQ] = {
3371                 .name = "inc_tcp_seq",
3372                 .help = "increase TCP sequence number",
3373                 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)),
3374                 .next = NEXT(action_inc_tcp_seq),
3375                 .call = parse_vc,
3376         },
3377         [ACTION_INC_TCP_SEQ_VALUE] = {
3378                 .name = "value",
3379                 .help = "the value to increase TCP sequence number by",
3380                 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(UNSIGNED)),
3381                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
3382                 .call = parse_vc_conf,
3383         },
3384         [ACTION_DEC_TCP_SEQ] = {
3385                 .name = "dec_tcp_seq",
3386                 .help = "decrease TCP sequence number",
3387                 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)),
3388                 .next = NEXT(action_dec_tcp_seq),
3389                 .call = parse_vc,
3390         },
3391         [ACTION_DEC_TCP_SEQ_VALUE] = {
3392                 .name = "value",
3393                 .help = "the value to decrease TCP sequence number by",
3394                 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(UNSIGNED)),
3395                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
3396                 .call = parse_vc_conf,
3397         },
3398         [ACTION_INC_TCP_ACK] = {
3399                 .name = "inc_tcp_ack",
3400                 .help = "increase TCP acknowledgment number",
3401                 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)),
3402                 .next = NEXT(action_inc_tcp_ack),
3403                 .call = parse_vc,
3404         },
3405         [ACTION_INC_TCP_ACK_VALUE] = {
3406                 .name = "value",
3407                 .help = "the value to increase TCP acknowledgment number by",
3408                 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(UNSIGNED)),
3409                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
3410                 .call = parse_vc_conf,
3411         },
3412         [ACTION_DEC_TCP_ACK] = {
3413                 .name = "dec_tcp_ack",
3414                 .help = "decrease TCP acknowledgment number",
3415                 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
3416                 .next = NEXT(action_dec_tcp_ack),
3417                 .call = parse_vc,
3418         },
3419         [ACTION_DEC_TCP_ACK_VALUE] = {
3420                 .name = "value",
3421                 .help = "the value to decrease TCP acknowledgment number by",
3422                 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(UNSIGNED)),
3423                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
3424                 .call = parse_vc_conf,
3425         },
3426         [ACTION_RAW_ENCAP] = {
3427                 .name = "raw_encap",
3428                 .help = "encapsulation data, defined by set raw_encap",
3429                 .priv = PRIV_ACTION(RAW_ENCAP,
3430                         sizeof(struct action_raw_encap_data)),
3431                 .next = NEXT(action_raw_encap),
3432                 .call = parse_vc_action_raw_encap,
3433         },
3434         [ACTION_RAW_ENCAP_INDEX] = {
3435                 .name = "index",
3436                 .help = "the index of raw_encap_confs",
3437                 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)),
3438         },
3439         [ACTION_RAW_ENCAP_INDEX_VALUE] = {
3440                 .name = "{index}",
3441                 .type = "UNSIGNED",
3442                 .help = "unsigned integer value",
3443                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3444                 .call = parse_vc_action_raw_encap_index,
3445                 .comp = comp_set_raw_index,
3446         },
3447         [ACTION_RAW_DECAP] = {
3448                 .name = "raw_decap",
3449                 .help = "decapsulation data, defined by set raw_encap",
3450                 .priv = PRIV_ACTION(RAW_DECAP,
3451                         sizeof(struct action_raw_decap_data)),
3452                 .next = NEXT(action_raw_decap),
3453                 .call = parse_vc_action_raw_decap,
3454         },
3455         [ACTION_RAW_DECAP_INDEX] = {
3456                 .name = "index",
3457                 .help = "the index of raw_encap_confs",
3458                 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)),
3459         },
3460         [ACTION_RAW_DECAP_INDEX_VALUE] = {
3461                 .name = "{index}",
3462                 .type = "UNSIGNED",
3463                 .help = "unsigned integer value",
3464                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3465                 .call = parse_vc_action_raw_decap_index,
3466                 .comp = comp_set_raw_index,
3467         },
3468         /* Top level command. */
3469         [SET] = {
3470                 .name = "set",
3471                 .help = "set raw encap/decap data",
3472                 .type = "set raw_encap|raw_decap <index> <pattern>",
3473                 .next = NEXT(NEXT_ENTRY
3474                              (SET_RAW_ENCAP,
3475                               SET_RAW_DECAP)),
3476                 .call = parse_set_init,
3477         },
3478         /* Sub-level commands. */
3479         [SET_RAW_ENCAP] = {
3480                 .name = "raw_encap",
3481                 .help = "set raw encap data",
3482                 .next = NEXT(next_set_raw),
3483                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
3484                                 (offsetof(struct buffer, port),
3485                                  sizeof(((struct buffer *)0)->port),
3486                                  0, RAW_ENCAP_CONFS_MAX_NUM - 1)),
3487                 .call = parse_set_raw_encap_decap,
3488         },
3489         [SET_RAW_DECAP] = {
3490                 .name = "raw_decap",
3491                 .help = "set raw decap data",
3492                 .next = NEXT(next_set_raw),
3493                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
3494                                 (offsetof(struct buffer, port),
3495                                  sizeof(((struct buffer *)0)->port),
3496                                  0, RAW_ENCAP_CONFS_MAX_NUM - 1)),
3497                 .call = parse_set_raw_encap_decap,
3498         },
3499         [SET_RAW_INDEX] = {
3500                 .name = "{index}",
3501                 .type = "UNSIGNED",
3502                 .help = "index of raw_encap/raw_decap data",
3503                 .next = NEXT(next_item),
3504                 .call = parse_port,
3505         },
3506         [ACTION_SET_TAG] = {
3507                 .name = "set_tag",
3508                 .help = "set tag",
3509                 .priv = PRIV_ACTION(SET_TAG,
3510                         sizeof(struct rte_flow_action_set_tag)),
3511                 .next = NEXT(action_set_tag),
3512                 .call = parse_vc,
3513         },
3514         [ACTION_SET_TAG_INDEX] = {
3515                 .name = "index",
3516                 .help = "index of tag array",
3517                 .next = NEXT(action_set_tag, NEXT_ENTRY(UNSIGNED)),
3518                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)),
3519                 .call = parse_vc_conf,
3520         },
3521         [ACTION_SET_TAG_DATA] = {
3522                 .name = "data",
3523                 .help = "tag value",
3524                 .next = NEXT(action_set_tag, NEXT_ENTRY(UNSIGNED)),
3525                 .args = ARGS(ARGS_ENTRY
3526                              (struct rte_flow_action_set_tag, data)),
3527                 .call = parse_vc_conf,
3528         },
3529         [ACTION_SET_TAG_MASK] = {
3530                 .name = "mask",
3531                 .help = "mask for tag value",
3532                 .next = NEXT(action_set_tag, NEXT_ENTRY(UNSIGNED)),
3533                 .args = ARGS(ARGS_ENTRY
3534                              (struct rte_flow_action_set_tag, mask)),
3535                 .call = parse_vc_conf,
3536         },
3537         [ACTION_SET_META] = {
3538                 .name = "set_meta",
3539                 .help = "set metadata",
3540                 .priv = PRIV_ACTION(SET_META,
3541                         sizeof(struct rte_flow_action_set_meta)),
3542                 .next = NEXT(action_set_meta),
3543                 .call = parse_vc_action_set_meta,
3544         },
3545         [ACTION_SET_META_DATA] = {
3546                 .name = "data",
3547                 .help = "metadata value",
3548                 .next = NEXT(action_set_meta, NEXT_ENTRY(UNSIGNED)),
3549                 .args = ARGS(ARGS_ENTRY
3550                              (struct rte_flow_action_set_meta, data)),
3551                 .call = parse_vc_conf,
3552         },
3553         [ACTION_SET_META_MASK] = {
3554                 .name = "mask",
3555                 .help = "mask for metadata value",
3556                 .next = NEXT(action_set_meta, NEXT_ENTRY(UNSIGNED)),
3557                 .args = ARGS(ARGS_ENTRY
3558                              (struct rte_flow_action_set_meta, mask)),
3559                 .call = parse_vc_conf,
3560         },
3561         [ACTION_SET_IPV4_DSCP] = {
3562                 .name = "set_ipv4_dscp",
3563                 .help = "set DSCP value",
3564                 .priv = PRIV_ACTION(SET_IPV4_DSCP,
3565                         sizeof(struct rte_flow_action_set_dscp)),
3566                 .next = NEXT(action_set_ipv4_dscp),
3567                 .call = parse_vc,
3568         },
3569         [ACTION_SET_IPV4_DSCP_VALUE] = {
3570                 .name = "dscp_value",
3571                 .help = "new IPv4 DSCP value to set",
3572                 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(UNSIGNED)),
3573                 .args = ARGS(ARGS_ENTRY
3574                              (struct rte_flow_action_set_dscp, dscp)),
3575                 .call = parse_vc_conf,
3576         },
3577         [ACTION_SET_IPV6_DSCP] = {
3578                 .name = "set_ipv6_dscp",
3579                 .help = "set DSCP value",
3580                 .priv = PRIV_ACTION(SET_IPV6_DSCP,
3581                         sizeof(struct rte_flow_action_set_dscp)),
3582                 .next = NEXT(action_set_ipv6_dscp),
3583                 .call = parse_vc,
3584         },
3585         [ACTION_SET_IPV6_DSCP_VALUE] = {
3586                 .name = "dscp_value",
3587                 .help = "new IPv6 DSCP value to set",
3588                 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(UNSIGNED)),
3589                 .args = ARGS(ARGS_ENTRY
3590                              (struct rte_flow_action_set_dscp, dscp)),
3591                 .call = parse_vc_conf,
3592         },
3593 };
3594
3595 /** Remove and return last entry from argument stack. */
3596 static const struct arg *
3597 pop_args(struct context *ctx)
3598 {
3599         return ctx->args_num ? ctx->args[--ctx->args_num] : NULL;
3600 }
3601
3602 /** Add entry on top of the argument stack. */
3603 static int
3604 push_args(struct context *ctx, const struct arg *arg)
3605 {
3606         if (ctx->args_num == CTX_STACK_SIZE)
3607                 return -1;
3608         ctx->args[ctx->args_num++] = arg;
3609         return 0;
3610 }
3611
3612 /** Spread value into buffer according to bit-mask. */
3613 static size_t
3614 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg)
3615 {
3616         uint32_t i = arg->size;
3617         uint32_t end = 0;
3618         int sub = 1;
3619         int add = 0;
3620         size_t len = 0;
3621
3622         if (!arg->mask)
3623                 return 0;
3624 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
3625         if (!arg->hton) {
3626                 i = 0;
3627                 end = arg->size;
3628                 sub = 0;
3629                 add = 1;
3630         }
3631 #endif
3632         while (i != end) {
3633                 unsigned int shift = 0;
3634                 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub);
3635
3636                 for (shift = 0; arg->mask[i] >> shift; ++shift) {
3637                         if (!(arg->mask[i] & (1 << shift)))
3638                                 continue;
3639                         ++len;
3640                         if (!dst)
3641                                 continue;
3642                         *buf &= ~(1 << shift);
3643                         *buf |= (val & 1) << shift;
3644                         val >>= 1;
3645                 }
3646                 i += add;
3647         }
3648         return len;
3649 }
3650
3651 /** Compare a string with a partial one of a given length. */
3652 static int
3653 strcmp_partial(const char *full, const char *partial, size_t partial_len)
3654 {
3655         int r = strncmp(full, partial, partial_len);
3656
3657         if (r)
3658                 return r;
3659         if (strlen(full) <= partial_len)
3660                 return 0;
3661         return full[partial_len];
3662 }
3663
3664 /**
3665  * Parse a prefix length and generate a bit-mask.
3666  *
3667  * Last argument (ctx->args) is retrieved to determine mask size, storage
3668  * location and whether the result must use network byte ordering.
3669  */
3670 static int
3671 parse_prefix(struct context *ctx, const struct token *token,
3672              const char *str, unsigned int len,
3673              void *buf, unsigned int size)
3674 {
3675         const struct arg *arg = pop_args(ctx);
3676         static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff";
3677         char *end;
3678         uintmax_t u;
3679         unsigned int bytes;
3680         unsigned int extra;
3681
3682         (void)token;
3683         /* Argument is expected. */
3684         if (!arg)
3685                 return -1;
3686         errno = 0;
3687         u = strtoumax(str, &end, 0);
3688         if (errno || (size_t)(end - str) != len)
3689                 goto error;
3690         if (arg->mask) {
3691                 uintmax_t v = 0;
3692
3693                 extra = arg_entry_bf_fill(NULL, 0, arg);
3694                 if (u > extra)
3695                         goto error;
3696                 if (!ctx->object)
3697                         return len;
3698                 extra -= u;
3699                 while (u--)
3700                         (v <<= 1, v |= 1);
3701                 v <<= extra;
3702                 if (!arg_entry_bf_fill(ctx->object, v, arg) ||
3703                     !arg_entry_bf_fill(ctx->objmask, -1, arg))
3704                         goto error;
3705                 return len;
3706         }
3707         bytes = u / 8;
3708         extra = u % 8;
3709         size = arg->size;
3710         if (bytes > size || bytes + !!extra > size)
3711                 goto error;
3712         if (!ctx->object)
3713                 return len;
3714         buf = (uint8_t *)ctx->object + arg->offset;
3715 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
3716         if (!arg->hton) {
3717                 memset((uint8_t *)buf + size - bytes, 0xff, bytes);
3718                 memset(buf, 0x00, size - bytes);
3719                 if (extra)
3720                         ((uint8_t *)buf)[size - bytes - 1] = conv[extra];
3721         } else
3722 #endif
3723         {
3724                 memset(buf, 0xff, bytes);
3725                 memset((uint8_t *)buf + bytes, 0x00, size - bytes);
3726                 if (extra)
3727                         ((uint8_t *)buf)[bytes] = conv[extra];
3728         }
3729         if (ctx->objmask)
3730                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
3731         return len;
3732 error:
3733         push_args(ctx, arg);
3734         return -1;
3735 }
3736
3737 /** Default parsing function for token name matching. */
3738 static int
3739 parse_default(struct context *ctx, const struct token *token,
3740               const char *str, unsigned int len,
3741               void *buf, unsigned int size)
3742 {
3743         (void)ctx;
3744         (void)buf;
3745         (void)size;
3746         if (strcmp_partial(token->name, str, len))
3747                 return -1;
3748         return len;
3749 }
3750
3751 /** Parse flow command, initialize output buffer for subsequent tokens. */
3752 static int
3753 parse_init(struct context *ctx, const struct token *token,
3754            const char *str, unsigned int len,
3755            void *buf, unsigned int size)
3756 {
3757         struct buffer *out = buf;
3758
3759         /* Token name must match. */
3760         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
3761                 return -1;
3762         /* Nothing else to do if there is no buffer. */
3763         if (!out)
3764                 return len;
3765         /* Make sure buffer is large enough. */
3766         if (size < sizeof(*out))
3767                 return -1;
3768         /* Initialize buffer. */
3769         memset(out, 0x00, sizeof(*out));
3770         memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out));
3771         ctx->objdata = 0;
3772         ctx->object = out;
3773         ctx->objmask = NULL;
3774         return len;
3775 }
3776
3777 /** Parse tokens for validate/create commands. */
3778 static int
3779 parse_vc(struct context *ctx, const struct token *token,
3780          const char *str, unsigned int len,
3781          void *buf, unsigned int size)
3782 {
3783         struct buffer *out = buf;
3784         uint8_t *data;
3785         uint32_t data_size;
3786
3787         /* Token name must match. */
3788         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
3789                 return -1;
3790         /* Nothing else to do if there is no buffer. */
3791         if (!out)
3792                 return len;
3793         if (!out->command) {
3794                 if (ctx->curr != VALIDATE && ctx->curr != CREATE)
3795                         return -1;
3796                 if (sizeof(*out) > size)
3797                         return -1;
3798                 out->command = ctx->curr;
3799                 ctx->objdata = 0;
3800                 ctx->object = out;
3801                 ctx->objmask = NULL;
3802                 out->args.vc.data = (uint8_t *)out + size;
3803                 return len;
3804         }
3805         ctx->objdata = 0;
3806         ctx->object = &out->args.vc.attr;
3807         ctx->objmask = NULL;
3808         switch (ctx->curr) {
3809         case GROUP:
3810         case PRIORITY:
3811                 return len;
3812         case INGRESS:
3813                 out->args.vc.attr.ingress = 1;
3814                 return len;
3815         case EGRESS:
3816                 out->args.vc.attr.egress = 1;
3817                 return len;
3818         case TRANSFER:
3819                 out->args.vc.attr.transfer = 1;
3820                 return len;
3821         case PATTERN:
3822                 out->args.vc.pattern =
3823                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
3824                                                sizeof(double));
3825                 ctx->object = out->args.vc.pattern;
3826                 ctx->objmask = NULL;
3827                 return len;
3828         case ACTIONS:
3829                 out->args.vc.actions =
3830                         (void *)RTE_ALIGN_CEIL((uintptr_t)
3831                                                (out->args.vc.pattern +
3832                                                 out->args.vc.pattern_n),
3833                                                sizeof(double));
3834                 ctx->object = out->args.vc.actions;
3835                 ctx->objmask = NULL;
3836                 return len;
3837         default:
3838                 if (!token->priv)
3839                         return -1;
3840                 break;
3841         }
3842         if (!out->args.vc.actions) {
3843                 const struct parse_item_priv *priv = token->priv;
3844                 struct rte_flow_item *item =
3845                         out->args.vc.pattern + out->args.vc.pattern_n;
3846
3847                 data_size = priv->size * 3; /* spec, last, mask */
3848                 data = (void *)RTE_ALIGN_FLOOR((uintptr_t)
3849                                                (out->args.vc.data - data_size),
3850                                                sizeof(double));
3851                 if ((uint8_t *)item + sizeof(*item) > data)
3852                         return -1;
3853                 *item = (struct rte_flow_item){
3854                         .type = priv->type,
3855                 };
3856                 ++out->args.vc.pattern_n;
3857                 ctx->object = item;
3858                 ctx->objmask = NULL;
3859         } else {
3860                 const struct parse_action_priv *priv = token->priv;
3861                 struct rte_flow_action *action =
3862                         out->args.vc.actions + out->args.vc.actions_n;
3863
3864                 data_size = priv->size; /* configuration */
3865                 data = (void *)RTE_ALIGN_FLOOR((uintptr_t)
3866                                                (out->args.vc.data - data_size),
3867                                                sizeof(double));
3868                 if ((uint8_t *)action + sizeof(*action) > data)
3869                         return -1;
3870                 *action = (struct rte_flow_action){
3871                         .type = priv->type,
3872                         .conf = data_size ? data : NULL,
3873                 };
3874                 ++out->args.vc.actions_n;
3875                 ctx->object = action;
3876                 ctx->objmask = NULL;
3877         }
3878         memset(data, 0, data_size);
3879         out->args.vc.data = data;
3880         ctx->objdata = data_size;
3881         return len;
3882 }
3883
3884 /** Parse pattern item parameter type. */
3885 static int
3886 parse_vc_spec(struct context *ctx, const struct token *token,
3887               const char *str, unsigned int len,
3888               void *buf, unsigned int size)
3889 {
3890         struct buffer *out = buf;
3891         struct rte_flow_item *item;
3892         uint32_t data_size;
3893         int index;
3894         int objmask = 0;
3895
3896         (void)size;
3897         /* Token name must match. */
3898         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
3899                 return -1;
3900         /* Parse parameter types. */
3901         switch (ctx->curr) {
3902                 static const enum index prefix[] = NEXT_ENTRY(PREFIX);
3903
3904         case ITEM_PARAM_IS:
3905                 index = 0;
3906                 objmask = 1;
3907                 break;
3908         case ITEM_PARAM_SPEC:
3909                 index = 0;
3910                 break;
3911         case ITEM_PARAM_LAST:
3912                 index = 1;
3913                 break;
3914         case ITEM_PARAM_PREFIX:
3915                 /* Modify next token to expect a prefix. */
3916                 if (ctx->next_num < 2)
3917                         return -1;
3918                 ctx->next[ctx->next_num - 2] = prefix;
3919                 /* Fall through. */
3920         case ITEM_PARAM_MASK:
3921                 index = 2;
3922                 break;
3923         default:
3924                 return -1;
3925         }
3926         /* Nothing else to do if there is no buffer. */
3927         if (!out)
3928                 return len;
3929         if (!out->args.vc.pattern_n)
3930                 return -1;
3931         item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
3932         data_size = ctx->objdata / 3; /* spec, last, mask */
3933         /* Point to selected object. */
3934         ctx->object = out->args.vc.data + (data_size * index);
3935         if (objmask) {
3936                 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */
3937                 item->mask = ctx->objmask;
3938         } else
3939                 ctx->objmask = NULL;
3940         /* Update relevant item pointer. */
3941         *((const void **[]){ &item->spec, &item->last, &item->mask })[index] =
3942                 ctx->object;
3943         return len;
3944 }
3945
3946 /** Parse action configuration field. */
3947 static int
3948 parse_vc_conf(struct context *ctx, const struct token *token,
3949               const char *str, unsigned int len,
3950               void *buf, unsigned int size)
3951 {
3952         struct buffer *out = buf;
3953
3954         (void)size;
3955         /* Token name must match. */
3956         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
3957                 return -1;
3958         /* Nothing else to do if there is no buffer. */
3959         if (!out)
3960                 return len;
3961         /* Point to selected object. */
3962         ctx->object = out->args.vc.data;
3963         ctx->objmask = NULL;
3964         return len;
3965 }
3966
3967 /** Parse RSS action. */
3968 static int
3969 parse_vc_action_rss(struct context *ctx, const struct token *token,
3970                     const char *str, unsigned int len,
3971                     void *buf, unsigned int size)
3972 {
3973         struct buffer *out = buf;
3974         struct rte_flow_action *action;
3975         struct action_rss_data *action_rss_data;
3976         unsigned int i;
3977         int ret;
3978
3979         ret = parse_vc(ctx, token, str, len, buf, size);
3980         if (ret < 0)
3981                 return ret;
3982         /* Nothing else to do if there is no buffer. */
3983         if (!out)
3984                 return ret;
3985         if (!out->args.vc.actions_n)
3986                 return -1;
3987         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
3988         /* Point to selected object. */
3989         ctx->object = out->args.vc.data;
3990         ctx->objmask = NULL;
3991         /* Set up default configuration. */
3992         action_rss_data = ctx->object;
3993         *action_rss_data = (struct action_rss_data){
3994                 .conf = (struct rte_flow_action_rss){
3995                         .func = RTE_ETH_HASH_FUNCTION_DEFAULT,
3996                         .level = 0,
3997                         .types = rss_hf,
3998                         .key_len = sizeof(action_rss_data->key),
3999                         .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
4000                         .key = action_rss_data->key,
4001                         .queue = action_rss_data->queue,
4002                 },
4003                 .key = "testpmd's default RSS hash key, "
4004                         "override it for better balancing",
4005                 .queue = { 0 },
4006         };
4007         for (i = 0; i < action_rss_data->conf.queue_num; ++i)
4008                 action_rss_data->queue[i] = i;
4009         if (!port_id_is_invalid(ctx->port, DISABLED_WARN) &&
4010             ctx->port != (portid_t)RTE_PORT_ALL) {
4011                 struct rte_eth_dev_info info;
4012                 int ret2;
4013
4014                 ret2 = rte_eth_dev_info_get(ctx->port, &info);
4015                 if (ret2 != 0)
4016                         return ret2;
4017
4018                 action_rss_data->conf.key_len =
4019                         RTE_MIN(sizeof(action_rss_data->key),
4020                                 info.hash_key_size);
4021         }
4022         action->conf = &action_rss_data->conf;
4023         return ret;
4024 }
4025
4026 /**
4027  * Parse func field for RSS action.
4028  *
4029  * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the
4030  * ACTION_RSS_FUNC_* index that called this function.
4031  */
4032 static int
4033 parse_vc_action_rss_func(struct context *ctx, const struct token *token,
4034                          const char *str, unsigned int len,
4035                          void *buf, unsigned int size)
4036 {
4037         struct action_rss_data *action_rss_data;
4038         enum rte_eth_hash_function func;
4039
4040         (void)buf;
4041         (void)size;
4042         /* Token name must match. */
4043         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
4044                 return -1;
4045         switch (ctx->curr) {
4046         case ACTION_RSS_FUNC_DEFAULT:
4047                 func = RTE_ETH_HASH_FUNCTION_DEFAULT;
4048                 break;
4049         case ACTION_RSS_FUNC_TOEPLITZ:
4050                 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
4051                 break;
4052         case ACTION_RSS_FUNC_SIMPLE_XOR:
4053                 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
4054                 break;
4055         case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ:
4056                 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ;
4057                 break;
4058         default:
4059                 return -1;
4060         }
4061         if (!ctx->object)
4062                 return len;
4063         action_rss_data = ctx->object;
4064         action_rss_data->conf.func = func;
4065         return len;
4066 }
4067
4068 /**
4069  * Parse type field for RSS action.
4070  *
4071  * Valid tokens are type field names and the "end" token.
4072  */
4073 static int
4074 parse_vc_action_rss_type(struct context *ctx, const struct token *token,
4075                           const char *str, unsigned int len,
4076                           void *buf, unsigned int size)
4077 {
4078         static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE);
4079         struct action_rss_data *action_rss_data;
4080         unsigned int i;
4081
4082         (void)token;
4083         (void)buf;
4084         (void)size;
4085         if (ctx->curr != ACTION_RSS_TYPE)
4086                 return -1;
4087         if (!(ctx->objdata >> 16) && ctx->object) {
4088                 action_rss_data = ctx->object;
4089                 action_rss_data->conf.types = 0;
4090         }
4091         if (!strcmp_partial("end", str, len)) {
4092                 ctx->objdata &= 0xffff;
4093                 return len;
4094         }
4095         for (i = 0; rss_type_table[i].str; ++i)
4096                 if (!strcmp_partial(rss_type_table[i].str, str, len))
4097                         break;
4098         if (!rss_type_table[i].str)
4099                 return -1;
4100         ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff);
4101         /* Repeat token. */
4102         if (ctx->next_num == RTE_DIM(ctx->next))
4103                 return -1;
4104         ctx->next[ctx->next_num++] = next;
4105         if (!ctx->object)
4106                 return len;
4107         action_rss_data = ctx->object;
4108         action_rss_data->conf.types |= rss_type_table[i].rss_type;
4109         return len;
4110 }
4111
4112 /**
4113  * Parse queue field for RSS action.
4114  *
4115  * Valid tokens are queue indices and the "end" token.
4116  */
4117 static int
4118 parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
4119                           const char *str, unsigned int len,
4120                           void *buf, unsigned int size)
4121 {
4122         static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE);
4123         struct action_rss_data *action_rss_data;
4124         const struct arg *arg;
4125         int ret;
4126         int i;
4127
4128         (void)token;
4129         (void)buf;
4130         (void)size;
4131         if (ctx->curr != ACTION_RSS_QUEUE)
4132                 return -1;
4133         i = ctx->objdata >> 16;
4134         if (!strcmp_partial("end", str, len)) {
4135                 ctx->objdata &= 0xffff;
4136                 goto end;
4137         }
4138         if (i >= ACTION_RSS_QUEUE_NUM)
4139                 return -1;
4140         arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) +
4141                              i * sizeof(action_rss_data->queue[i]),
4142                              sizeof(action_rss_data->queue[i]));
4143         if (push_args(ctx, arg))
4144                 return -1;
4145         ret = parse_int(ctx, token, str, len, NULL, 0);
4146         if (ret < 0) {
4147                 pop_args(ctx);
4148                 return -1;
4149         }
4150         ++i;
4151         ctx->objdata = i << 16 | (ctx->objdata & 0xffff);
4152         /* Repeat token. */
4153         if (ctx->next_num == RTE_DIM(ctx->next))
4154                 return -1;
4155         ctx->next[ctx->next_num++] = next;
4156 end:
4157         if (!ctx->object)
4158                 return len;
4159         action_rss_data = ctx->object;
4160         action_rss_data->conf.queue_num = i;
4161         action_rss_data->conf.queue = i ? action_rss_data->queue : NULL;
4162         return len;
4163 }
4164
4165 /** Parse VXLAN encap action. */
4166 static int
4167 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token,
4168                             const char *str, unsigned int len,
4169                             void *buf, unsigned int size)
4170 {
4171         struct buffer *out = buf;
4172         struct rte_flow_action *action;
4173         struct action_vxlan_encap_data *action_vxlan_encap_data;
4174         int ret;
4175
4176         ret = parse_vc(ctx, token, str, len, buf, size);
4177         if (ret < 0)
4178                 return ret;
4179         /* Nothing else to do if there is no buffer. */
4180         if (!out)
4181                 return ret;
4182         if (!out->args.vc.actions_n)
4183                 return -1;
4184         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4185         /* Point to selected object. */
4186         ctx->object = out->args.vc.data;
4187         ctx->objmask = NULL;
4188         /* Set up default configuration. */
4189         action_vxlan_encap_data = ctx->object;
4190         *action_vxlan_encap_data = (struct action_vxlan_encap_data){
4191                 .conf = (struct rte_flow_action_vxlan_encap){
4192                         .definition = action_vxlan_encap_data->items,
4193                 },
4194                 .items = {
4195                         {
4196                                 .type = RTE_FLOW_ITEM_TYPE_ETH,
4197                                 .spec = &action_vxlan_encap_data->item_eth,
4198                                 .mask = &rte_flow_item_eth_mask,
4199                         },
4200                         {
4201                                 .type = RTE_FLOW_ITEM_TYPE_VLAN,
4202                                 .spec = &action_vxlan_encap_data->item_vlan,
4203                                 .mask = &rte_flow_item_vlan_mask,
4204                         },
4205                         {
4206                                 .type = RTE_FLOW_ITEM_TYPE_IPV4,
4207                                 .spec = &action_vxlan_encap_data->item_ipv4,
4208                                 .mask = &rte_flow_item_ipv4_mask,
4209                         },
4210                         {
4211                                 .type = RTE_FLOW_ITEM_TYPE_UDP,
4212                                 .spec = &action_vxlan_encap_data->item_udp,
4213                                 .mask = &rte_flow_item_udp_mask,
4214                         },
4215                         {
4216                                 .type = RTE_FLOW_ITEM_TYPE_VXLAN,
4217                                 .spec = &action_vxlan_encap_data->item_vxlan,
4218                                 .mask = &rte_flow_item_vxlan_mask,
4219                         },
4220                         {
4221                                 .type = RTE_FLOW_ITEM_TYPE_END,
4222                         },
4223                 },
4224                 .item_eth.type = 0,
4225                 .item_vlan = {
4226                         .tci = vxlan_encap_conf.vlan_tci,
4227                         .inner_type = 0,
4228                 },
4229                 .item_ipv4.hdr = {
4230                         .src_addr = vxlan_encap_conf.ipv4_src,
4231                         .dst_addr = vxlan_encap_conf.ipv4_dst,
4232                 },
4233                 .item_udp.hdr = {
4234                         .src_port = vxlan_encap_conf.udp_src,
4235                         .dst_port = vxlan_encap_conf.udp_dst,
4236                 },
4237                 .item_vxlan.flags = 0,
4238         };
4239         memcpy(action_vxlan_encap_data->item_eth.dst.addr_bytes,
4240                vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4241         memcpy(action_vxlan_encap_data->item_eth.src.addr_bytes,
4242                vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4243         if (!vxlan_encap_conf.select_ipv4) {
4244                 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr,
4245                        &vxlan_encap_conf.ipv6_src,
4246                        sizeof(vxlan_encap_conf.ipv6_src));
4247                 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr,
4248                        &vxlan_encap_conf.ipv6_dst,
4249                        sizeof(vxlan_encap_conf.ipv6_dst));
4250                 action_vxlan_encap_data->items[2] = (struct rte_flow_item){
4251                         .type = RTE_FLOW_ITEM_TYPE_IPV6,
4252                         .spec = &action_vxlan_encap_data->item_ipv6,
4253                         .mask = &rte_flow_item_ipv6_mask,
4254                 };
4255         }
4256         if (!vxlan_encap_conf.select_vlan)
4257                 action_vxlan_encap_data->items[1].type =
4258                         RTE_FLOW_ITEM_TYPE_VOID;
4259         if (vxlan_encap_conf.select_tos_ttl) {
4260                 if (vxlan_encap_conf.select_ipv4) {
4261                         static struct rte_flow_item_ipv4 ipv4_mask_tos;
4262
4263                         memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask,
4264                                sizeof(ipv4_mask_tos));
4265                         ipv4_mask_tos.hdr.type_of_service = 0xff;
4266                         ipv4_mask_tos.hdr.time_to_live = 0xff;
4267                         action_vxlan_encap_data->item_ipv4.hdr.type_of_service =
4268                                         vxlan_encap_conf.ip_tos;
4269                         action_vxlan_encap_data->item_ipv4.hdr.time_to_live =
4270                                         vxlan_encap_conf.ip_ttl;
4271                         action_vxlan_encap_data->items[2].mask =
4272                                                         &ipv4_mask_tos;
4273                 } else {
4274                         static struct rte_flow_item_ipv6 ipv6_mask_tos;
4275
4276                         memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask,
4277                                sizeof(ipv6_mask_tos));
4278                         ipv6_mask_tos.hdr.vtc_flow |=
4279                                 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT);
4280                         ipv6_mask_tos.hdr.hop_limits = 0xff;
4281                         action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |=
4282                                 rte_cpu_to_be_32
4283                                         ((uint32_t)vxlan_encap_conf.ip_tos <<
4284                                          RTE_IPV6_HDR_TC_SHIFT);
4285                         action_vxlan_encap_data->item_ipv6.hdr.hop_limits =
4286                                         vxlan_encap_conf.ip_ttl;
4287                         action_vxlan_encap_data->items[2].mask =
4288                                                         &ipv6_mask_tos;
4289                 }
4290         }
4291         memcpy(action_vxlan_encap_data->item_vxlan.vni, vxlan_encap_conf.vni,
4292                RTE_DIM(vxlan_encap_conf.vni));
4293         action->conf = &action_vxlan_encap_data->conf;
4294         return ret;
4295 }
4296
4297 /** Parse NVGRE encap action. */
4298 static int
4299 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token,
4300                             const char *str, unsigned int len,
4301                             void *buf, unsigned int size)
4302 {
4303         struct buffer *out = buf;
4304         struct rte_flow_action *action;
4305         struct action_nvgre_encap_data *action_nvgre_encap_data;
4306         int ret;
4307
4308         ret = parse_vc(ctx, token, str, len, buf, size);
4309         if (ret < 0)
4310                 return ret;
4311         /* Nothing else to do if there is no buffer. */
4312         if (!out)
4313                 return ret;
4314         if (!out->args.vc.actions_n)
4315                 return -1;
4316         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4317         /* Point to selected object. */
4318         ctx->object = out->args.vc.data;
4319         ctx->objmask = NULL;
4320         /* Set up default configuration. */
4321         action_nvgre_encap_data = ctx->object;
4322         *action_nvgre_encap_data = (struct action_nvgre_encap_data){
4323                 .conf = (struct rte_flow_action_nvgre_encap){
4324                         .definition = action_nvgre_encap_data->items,
4325                 },
4326                 .items = {
4327                         {
4328                                 .type = RTE_FLOW_ITEM_TYPE_ETH,
4329                                 .spec = &action_nvgre_encap_data->item_eth,
4330                                 .mask = &rte_flow_item_eth_mask,
4331                         },
4332                         {
4333                                 .type = RTE_FLOW_ITEM_TYPE_VLAN,
4334                                 .spec = &action_nvgre_encap_data->item_vlan,
4335                                 .mask = &rte_flow_item_vlan_mask,
4336                         },
4337                         {
4338                                 .type = RTE_FLOW_ITEM_TYPE_IPV4,
4339                                 .spec = &action_nvgre_encap_data->item_ipv4,
4340                                 .mask = &rte_flow_item_ipv4_mask,
4341                         },
4342                         {
4343                                 .type = RTE_FLOW_ITEM_TYPE_NVGRE,
4344                                 .spec = &action_nvgre_encap_data->item_nvgre,
4345                                 .mask = &rte_flow_item_nvgre_mask,
4346                         },
4347                         {
4348                                 .type = RTE_FLOW_ITEM_TYPE_END,
4349                         },
4350                 },
4351                 .item_eth.type = 0,
4352                 .item_vlan = {
4353                         .tci = nvgre_encap_conf.vlan_tci,
4354                         .inner_type = 0,
4355                 },
4356                 .item_ipv4.hdr = {
4357                        .src_addr = nvgre_encap_conf.ipv4_src,
4358                        .dst_addr = nvgre_encap_conf.ipv4_dst,
4359                 },
4360                 .item_nvgre.flow_id = 0,
4361         };
4362         memcpy(action_nvgre_encap_data->item_eth.dst.addr_bytes,
4363                nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4364         memcpy(action_nvgre_encap_data->item_eth.src.addr_bytes,
4365                nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4366         if (!nvgre_encap_conf.select_ipv4) {
4367                 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr,
4368                        &nvgre_encap_conf.ipv6_src,
4369                        sizeof(nvgre_encap_conf.ipv6_src));
4370                 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr,
4371                        &nvgre_encap_conf.ipv6_dst,
4372                        sizeof(nvgre_encap_conf.ipv6_dst));
4373                 action_nvgre_encap_data->items[2] = (struct rte_flow_item){
4374                         .type = RTE_FLOW_ITEM_TYPE_IPV6,
4375                         .spec = &action_nvgre_encap_data->item_ipv6,
4376                         .mask = &rte_flow_item_ipv6_mask,
4377                 };
4378         }
4379         if (!nvgre_encap_conf.select_vlan)
4380                 action_nvgre_encap_data->items[1].type =
4381                         RTE_FLOW_ITEM_TYPE_VOID;
4382         memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni,
4383                RTE_DIM(nvgre_encap_conf.tni));
4384         action->conf = &action_nvgre_encap_data->conf;
4385         return ret;
4386 }
4387
4388 /** Parse l2 encap action. */
4389 static int
4390 parse_vc_action_l2_encap(struct context *ctx, const struct token *token,
4391                          const char *str, unsigned int len,
4392                          void *buf, unsigned int size)
4393 {
4394         struct buffer *out = buf;
4395         struct rte_flow_action *action;
4396         struct action_raw_encap_data *action_encap_data;
4397         struct rte_flow_item_eth eth = { .type = 0, };
4398         struct rte_flow_item_vlan vlan = {
4399                 .tci = mplsoudp_encap_conf.vlan_tci,
4400                 .inner_type = 0,
4401         };
4402         uint8_t *header;
4403         int ret;
4404
4405         ret = parse_vc(ctx, token, str, len, buf, size);
4406         if (ret < 0)
4407                 return ret;
4408         /* Nothing else to do if there is no buffer. */
4409         if (!out)
4410                 return ret;
4411         if (!out->args.vc.actions_n)
4412                 return -1;
4413         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4414         /* Point to selected object. */
4415         ctx->object = out->args.vc.data;
4416         ctx->objmask = NULL;
4417         /* Copy the headers to the buffer. */
4418         action_encap_data = ctx->object;
4419         *action_encap_data = (struct action_raw_encap_data) {
4420                 .conf = (struct rte_flow_action_raw_encap){
4421                         .data = action_encap_data->data,
4422                 },
4423                 .data = {},
4424         };
4425         header = action_encap_data->data;
4426         if (l2_encap_conf.select_vlan)
4427                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4428         else if (l2_encap_conf.select_ipv4)
4429                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4430         else
4431                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4432         memcpy(eth.dst.addr_bytes,
4433                l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4434         memcpy(eth.src.addr_bytes,
4435                l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4436         memcpy(header, &eth, sizeof(eth));
4437         header += sizeof(eth);
4438         if (l2_encap_conf.select_vlan) {
4439                 if (l2_encap_conf.select_ipv4)
4440                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4441                 else
4442                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4443                 memcpy(header, &vlan, sizeof(vlan));
4444                 header += sizeof(vlan);
4445         }
4446         action_encap_data->conf.size = header -
4447                 action_encap_data->data;
4448         action->conf = &action_encap_data->conf;
4449         return ret;
4450 }
4451
4452 /** Parse l2 decap action. */
4453 static int
4454 parse_vc_action_l2_decap(struct context *ctx, const struct token *token,
4455                          const char *str, unsigned int len,
4456                          void *buf, unsigned int size)
4457 {
4458         struct buffer *out = buf;
4459         struct rte_flow_action *action;
4460         struct action_raw_decap_data *action_decap_data;
4461         struct rte_flow_item_eth eth = { .type = 0, };
4462         struct rte_flow_item_vlan vlan = {
4463                 .tci = mplsoudp_encap_conf.vlan_tci,
4464                 .inner_type = 0,
4465         };
4466         uint8_t *header;
4467         int ret;
4468
4469         ret = parse_vc(ctx, token, str, len, buf, size);
4470         if (ret < 0)
4471                 return ret;
4472         /* Nothing else to do if there is no buffer. */
4473         if (!out)
4474                 return ret;
4475         if (!out->args.vc.actions_n)
4476                 return -1;
4477         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4478         /* Point to selected object. */
4479         ctx->object = out->args.vc.data;
4480         ctx->objmask = NULL;
4481         /* Copy the headers to the buffer. */
4482         action_decap_data = ctx->object;
4483         *action_decap_data = (struct action_raw_decap_data) {
4484                 .conf = (struct rte_flow_action_raw_decap){
4485                         .data = action_decap_data->data,
4486                 },
4487                 .data = {},
4488         };
4489         header = action_decap_data->data;
4490         if (l2_decap_conf.select_vlan)
4491                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4492         memcpy(header, &eth, sizeof(eth));
4493         header += sizeof(eth);
4494         if (l2_decap_conf.select_vlan) {
4495                 memcpy(header, &vlan, sizeof(vlan));
4496                 header += sizeof(vlan);
4497         }
4498         action_decap_data->conf.size = header -
4499                 action_decap_data->data;
4500         action->conf = &action_decap_data->conf;
4501         return ret;
4502 }
4503
4504 #define ETHER_TYPE_MPLS_UNICAST 0x8847
4505
4506 /** Parse MPLSOGRE encap action. */
4507 static int
4508 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token,
4509                                const char *str, unsigned int len,
4510                                void *buf, unsigned int size)
4511 {
4512         struct buffer *out = buf;
4513         struct rte_flow_action *action;
4514         struct action_raw_encap_data *action_encap_data;
4515         struct rte_flow_item_eth eth = { .type = 0, };
4516         struct rte_flow_item_vlan vlan = {
4517                 .tci = mplsogre_encap_conf.vlan_tci,
4518                 .inner_type = 0,
4519         };
4520         struct rte_flow_item_ipv4 ipv4 = {
4521                 .hdr =  {
4522                         .src_addr = mplsogre_encap_conf.ipv4_src,
4523                         .dst_addr = mplsogre_encap_conf.ipv4_dst,
4524                         .next_proto_id = IPPROTO_GRE,
4525                         .version_ihl = RTE_IPV4_VHL_DEF,
4526                         .time_to_live = IPDEFTTL,
4527                 },
4528         };
4529         struct rte_flow_item_ipv6 ipv6 = {
4530                 .hdr =  {
4531                         .proto = IPPROTO_GRE,
4532                         .hop_limits = IPDEFTTL,
4533                 },
4534         };
4535         struct rte_flow_item_gre gre = {
4536                 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST),
4537         };
4538         struct rte_flow_item_mpls mpls;
4539         uint8_t *header;
4540         int ret;
4541
4542         ret = parse_vc(ctx, token, str, len, buf, size);
4543         if (ret < 0)
4544                 return ret;
4545         /* Nothing else to do if there is no buffer. */
4546         if (!out)
4547                 return ret;
4548         if (!out->args.vc.actions_n)
4549                 return -1;
4550         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4551         /* Point to selected object. */
4552         ctx->object = out->args.vc.data;
4553         ctx->objmask = NULL;
4554         /* Copy the headers to the buffer. */
4555         action_encap_data = ctx->object;
4556         *action_encap_data = (struct action_raw_encap_data) {
4557                 .conf = (struct rte_flow_action_raw_encap){
4558                         .data = action_encap_data->data,
4559                 },
4560                 .data = {},
4561                 .preserve = {},
4562         };
4563         header = action_encap_data->data;
4564         if (mplsogre_encap_conf.select_vlan)
4565                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4566         else if (mplsogre_encap_conf.select_ipv4)
4567                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4568         else
4569                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4570         memcpy(eth.dst.addr_bytes,
4571                mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4572         memcpy(eth.src.addr_bytes,
4573                mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4574         memcpy(header, &eth, sizeof(eth));
4575         header += sizeof(eth);
4576         if (mplsogre_encap_conf.select_vlan) {
4577                 if (mplsogre_encap_conf.select_ipv4)
4578                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4579                 else
4580                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4581                 memcpy(header, &vlan, sizeof(vlan));
4582                 header += sizeof(vlan);
4583         }
4584         if (mplsogre_encap_conf.select_ipv4) {
4585                 memcpy(header, &ipv4, sizeof(ipv4));
4586                 header += sizeof(ipv4);
4587         } else {
4588                 memcpy(&ipv6.hdr.src_addr,
4589                        &mplsogre_encap_conf.ipv6_src,
4590                        sizeof(mplsogre_encap_conf.ipv6_src));
4591                 memcpy(&ipv6.hdr.dst_addr,
4592                        &mplsogre_encap_conf.ipv6_dst,
4593                        sizeof(mplsogre_encap_conf.ipv6_dst));
4594                 memcpy(header, &ipv6, sizeof(ipv6));
4595                 header += sizeof(ipv6);
4596         }
4597         memcpy(header, &gre, sizeof(gre));
4598         header += sizeof(gre);
4599         memcpy(mpls.label_tc_s, mplsogre_encap_conf.label,
4600                RTE_DIM(mplsogre_encap_conf.label));
4601         mpls.label_tc_s[2] |= 0x1;
4602         memcpy(header, &mpls, sizeof(mpls));
4603         header += sizeof(mpls);
4604         action_encap_data->conf.size = header -
4605                 action_encap_data->data;
4606         action->conf = &action_encap_data->conf;
4607         return ret;
4608 }
4609
4610 /** Parse MPLSOGRE decap action. */
4611 static int
4612 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token,
4613                                const char *str, unsigned int len,
4614                                void *buf, unsigned int size)
4615 {
4616         struct buffer *out = buf;
4617         struct rte_flow_action *action;
4618         struct action_raw_decap_data *action_decap_data;
4619         struct rte_flow_item_eth eth = { .type = 0, };
4620         struct rte_flow_item_vlan vlan = {.tci = 0};
4621         struct rte_flow_item_ipv4 ipv4 = {
4622                 .hdr =  {
4623                         .next_proto_id = IPPROTO_GRE,
4624                 },
4625         };
4626         struct rte_flow_item_ipv6 ipv6 = {
4627                 .hdr =  {
4628                         .proto = IPPROTO_GRE,
4629                 },
4630         };
4631         struct rte_flow_item_gre gre = {
4632                 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST),
4633         };
4634         struct rte_flow_item_mpls mpls;
4635         uint8_t *header;
4636         int ret;
4637
4638         ret = parse_vc(ctx, token, str, len, buf, size);
4639         if (ret < 0)
4640                 return ret;
4641         /* Nothing else to do if there is no buffer. */
4642         if (!out)
4643                 return ret;
4644         if (!out->args.vc.actions_n)
4645                 return -1;
4646         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4647         /* Point to selected object. */
4648         ctx->object = out->args.vc.data;
4649         ctx->objmask = NULL;
4650         /* Copy the headers to the buffer. */
4651         action_decap_data = ctx->object;
4652         *action_decap_data = (struct action_raw_decap_data) {
4653                 .conf = (struct rte_flow_action_raw_decap){
4654                         .data = action_decap_data->data,
4655                 },
4656                 .data = {},
4657         };
4658         header = action_decap_data->data;
4659         if (mplsogre_decap_conf.select_vlan)
4660                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4661         else if (mplsogre_encap_conf.select_ipv4)
4662                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4663         else
4664                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4665         memcpy(eth.dst.addr_bytes,
4666                mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4667         memcpy(eth.src.addr_bytes,
4668                mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4669         memcpy(header, &eth, sizeof(eth));
4670         header += sizeof(eth);
4671         if (mplsogre_encap_conf.select_vlan) {
4672                 if (mplsogre_encap_conf.select_ipv4)
4673                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4674                 else
4675                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4676                 memcpy(header, &vlan, sizeof(vlan));
4677                 header += sizeof(vlan);
4678         }
4679         if (mplsogre_encap_conf.select_ipv4) {
4680                 memcpy(header, &ipv4, sizeof(ipv4));
4681                 header += sizeof(ipv4);
4682         } else {
4683                 memcpy(header, &ipv6, sizeof(ipv6));
4684                 header += sizeof(ipv6);
4685         }
4686         memcpy(header, &gre, sizeof(gre));
4687         header += sizeof(gre);
4688         memset(&mpls, 0, sizeof(mpls));
4689         memcpy(header, &mpls, sizeof(mpls));
4690         header += sizeof(mpls);
4691         action_decap_data->conf.size = header -
4692                 action_decap_data->data;
4693         action->conf = &action_decap_data->conf;
4694         return ret;
4695 }
4696
4697 /** Parse MPLSOUDP encap action. */
4698 static int
4699 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token,
4700                                const char *str, unsigned int len,
4701                                void *buf, unsigned int size)
4702 {
4703         struct buffer *out = buf;
4704         struct rte_flow_action *action;
4705         struct action_raw_encap_data *action_encap_data;
4706         struct rte_flow_item_eth eth = { .type = 0, };
4707         struct rte_flow_item_vlan vlan = {
4708                 .tci = mplsoudp_encap_conf.vlan_tci,
4709                 .inner_type = 0,
4710         };
4711         struct rte_flow_item_ipv4 ipv4 = {
4712                 .hdr =  {
4713                         .src_addr = mplsoudp_encap_conf.ipv4_src,
4714                         .dst_addr = mplsoudp_encap_conf.ipv4_dst,
4715                         .next_proto_id = IPPROTO_UDP,
4716                         .version_ihl = RTE_IPV4_VHL_DEF,
4717                         .time_to_live = IPDEFTTL,
4718                 },
4719         };
4720         struct rte_flow_item_ipv6 ipv6 = {
4721                 .hdr =  {
4722                         .proto = IPPROTO_UDP,
4723                         .hop_limits = IPDEFTTL,
4724                 },
4725         };
4726         struct rte_flow_item_udp udp = {
4727                 .hdr = {
4728                         .src_port = mplsoudp_encap_conf.udp_src,
4729                         .dst_port = mplsoudp_encap_conf.udp_dst,
4730                 },
4731         };
4732         struct rte_flow_item_mpls mpls;
4733         uint8_t *header;
4734         int ret;
4735
4736         ret = parse_vc(ctx, token, str, len, buf, size);
4737         if (ret < 0)
4738                 return ret;
4739         /* Nothing else to do if there is no buffer. */
4740         if (!out)
4741                 return ret;
4742         if (!out->args.vc.actions_n)
4743                 return -1;
4744         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4745         /* Point to selected object. */
4746         ctx->object = out->args.vc.data;
4747         ctx->objmask = NULL;
4748         /* Copy the headers to the buffer. */
4749         action_encap_data = ctx->object;
4750         *action_encap_data = (struct action_raw_encap_data) {
4751                 .conf = (struct rte_flow_action_raw_encap){
4752                         .data = action_encap_data->data,
4753                 },
4754                 .data = {},
4755                 .preserve = {},
4756         };
4757         header = action_encap_data->data;
4758         if (mplsoudp_encap_conf.select_vlan)
4759                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4760         else if (mplsoudp_encap_conf.select_ipv4)
4761                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4762         else
4763                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4764         memcpy(eth.dst.addr_bytes,
4765                mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4766         memcpy(eth.src.addr_bytes,
4767                mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4768         memcpy(header, &eth, sizeof(eth));
4769         header += sizeof(eth);
4770         if (mplsoudp_encap_conf.select_vlan) {
4771                 if (mplsoudp_encap_conf.select_ipv4)
4772                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4773                 else
4774                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4775                 memcpy(header, &vlan, sizeof(vlan));
4776                 header += sizeof(vlan);
4777         }
4778         if (mplsoudp_encap_conf.select_ipv4) {
4779                 memcpy(header, &ipv4, sizeof(ipv4));
4780                 header += sizeof(ipv4);
4781         } else {
4782                 memcpy(&ipv6.hdr.src_addr,
4783                        &mplsoudp_encap_conf.ipv6_src,
4784                        sizeof(mplsoudp_encap_conf.ipv6_src));
4785                 memcpy(&ipv6.hdr.dst_addr,
4786                        &mplsoudp_encap_conf.ipv6_dst,
4787                        sizeof(mplsoudp_encap_conf.ipv6_dst));
4788                 memcpy(header, &ipv6, sizeof(ipv6));
4789                 header += sizeof(ipv6);
4790         }
4791         memcpy(header, &udp, sizeof(udp));
4792         header += sizeof(udp);
4793         memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label,
4794                RTE_DIM(mplsoudp_encap_conf.label));
4795         mpls.label_tc_s[2] |= 0x1;
4796         memcpy(header, &mpls, sizeof(mpls));
4797         header += sizeof(mpls);
4798         action_encap_data->conf.size = header -
4799                 action_encap_data->data;
4800         action->conf = &action_encap_data->conf;
4801         return ret;
4802 }
4803
4804 /** Parse MPLSOUDP decap action. */
4805 static int
4806 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token,
4807                                const char *str, unsigned int len,
4808                                void *buf, unsigned int size)
4809 {
4810         struct buffer *out = buf;
4811         struct rte_flow_action *action;
4812         struct action_raw_decap_data *action_decap_data;
4813         struct rte_flow_item_eth eth = { .type = 0, };
4814         struct rte_flow_item_vlan vlan = {.tci = 0};
4815         struct rte_flow_item_ipv4 ipv4 = {
4816                 .hdr =  {
4817                         .next_proto_id = IPPROTO_UDP,
4818                 },
4819         };
4820         struct rte_flow_item_ipv6 ipv6 = {
4821                 .hdr =  {
4822                         .proto = IPPROTO_UDP,
4823                 },
4824         };
4825         struct rte_flow_item_udp udp = {
4826                 .hdr = {
4827                         .dst_port = rte_cpu_to_be_16(6635),
4828                 },
4829         };
4830         struct rte_flow_item_mpls mpls;
4831         uint8_t *header;
4832         int ret;
4833
4834         ret = parse_vc(ctx, token, str, len, buf, size);
4835         if (ret < 0)
4836                 return ret;
4837         /* Nothing else to do if there is no buffer. */
4838         if (!out)
4839                 return ret;
4840         if (!out->args.vc.actions_n)
4841                 return -1;
4842         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4843         /* Point to selected object. */
4844         ctx->object = out->args.vc.data;
4845         ctx->objmask = NULL;
4846         /* Copy the headers to the buffer. */
4847         action_decap_data = ctx->object;
4848         *action_decap_data = (struct action_raw_decap_data) {
4849                 .conf = (struct rte_flow_action_raw_decap){
4850                         .data = action_decap_data->data,
4851                 },
4852                 .data = {},
4853         };
4854         header = action_decap_data->data;
4855         if (mplsoudp_decap_conf.select_vlan)
4856                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4857         else if (mplsoudp_encap_conf.select_ipv4)
4858                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4859         else
4860                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4861         memcpy(eth.dst.addr_bytes,
4862                mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4863         memcpy(eth.src.addr_bytes,
4864                mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4865         memcpy(header, &eth, sizeof(eth));
4866         header += sizeof(eth);
4867         if (mplsoudp_encap_conf.select_vlan) {
4868                 if (mplsoudp_encap_conf.select_ipv4)
4869                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4870                 else
4871                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4872                 memcpy(header, &vlan, sizeof(vlan));
4873                 header += sizeof(vlan);
4874         }
4875         if (mplsoudp_encap_conf.select_ipv4) {
4876                 memcpy(header, &ipv4, sizeof(ipv4));
4877                 header += sizeof(ipv4);
4878         } else {
4879                 memcpy(header, &ipv6, sizeof(ipv6));
4880                 header += sizeof(ipv6);
4881         }
4882         memcpy(header, &udp, sizeof(udp));
4883         header += sizeof(udp);
4884         memset(&mpls, 0, sizeof(mpls));
4885         memcpy(header, &mpls, sizeof(mpls));
4886         header += sizeof(mpls);
4887         action_decap_data->conf.size = header -
4888                 action_decap_data->data;
4889         action->conf = &action_decap_data->conf;
4890         return ret;
4891 }
4892
4893 static int
4894 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token,
4895                                 const char *str, unsigned int len, void *buf,
4896                                 unsigned int size)
4897 {
4898         struct action_raw_decap_data *action_raw_decap_data;
4899         struct rte_flow_action *action;
4900         const struct arg *arg;
4901         struct buffer *out = buf;
4902         int ret;
4903         uint16_t idx;
4904
4905         RTE_SET_USED(token);
4906         RTE_SET_USED(buf);
4907         RTE_SET_USED(size);
4908         arg = ARGS_ENTRY_ARB_BOUNDED
4909                 (offsetof(struct action_raw_decap_data, idx),
4910                  sizeof(((struct action_raw_decap_data *)0)->idx),
4911                  0, RAW_ENCAP_CONFS_MAX_NUM - 1);
4912         if (push_args(ctx, arg))
4913                 return -1;
4914         ret = parse_int(ctx, token, str, len, NULL, 0);
4915         if (ret < 0) {
4916                 pop_args(ctx);
4917                 return -1;
4918         }
4919         if (!ctx->object)
4920                 return len;
4921         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4922         action_raw_decap_data = ctx->object;
4923         idx = action_raw_decap_data->idx;
4924         action_raw_decap_data->conf.data = raw_decap_confs[idx].data;
4925         action_raw_decap_data->conf.size = raw_decap_confs[idx].size;
4926         action->conf = &action_raw_decap_data->conf;
4927         return len;
4928 }
4929
4930
4931 static int
4932 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token,
4933                                 const char *str, unsigned int len, void *buf,
4934                                 unsigned int size)
4935 {
4936         struct action_raw_encap_data *action_raw_encap_data;
4937         struct rte_flow_action *action;
4938         const struct arg *arg;
4939         struct buffer *out = buf;
4940         int ret;
4941         uint16_t idx;
4942
4943         RTE_SET_USED(token);
4944         RTE_SET_USED(buf);
4945         RTE_SET_USED(size);
4946         if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE)
4947                 return -1;
4948         arg = ARGS_ENTRY_ARB_BOUNDED
4949                 (offsetof(struct action_raw_encap_data, idx),
4950                  sizeof(((struct action_raw_encap_data *)0)->idx),
4951                  0, RAW_ENCAP_CONFS_MAX_NUM - 1);
4952         if (push_args(ctx, arg))
4953                 return -1;
4954         ret = parse_int(ctx, token, str, len, NULL, 0);
4955         if (ret < 0) {
4956                 pop_args(ctx);
4957                 return -1;
4958         }
4959         if (!ctx->object)
4960                 return len;
4961         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4962         action_raw_encap_data = ctx->object;
4963         idx = action_raw_encap_data->idx;
4964         action_raw_encap_data->conf.data = raw_encap_confs[idx].data;
4965         action_raw_encap_data->conf.size = raw_encap_confs[idx].size;
4966         action_raw_encap_data->conf.preserve = NULL;
4967         action->conf = &action_raw_encap_data->conf;
4968         return len;
4969 }
4970
4971 static int
4972 parse_vc_action_raw_encap(struct context *ctx, const struct token *token,
4973                           const char *str, unsigned int len, void *buf,
4974                           unsigned int size)
4975 {
4976         struct buffer *out = buf;
4977         struct rte_flow_action *action;
4978         struct action_raw_encap_data *action_raw_encap_data = NULL;
4979         int ret;
4980
4981         ret = parse_vc(ctx, token, str, len, buf, size);
4982         if (ret < 0)
4983                 return ret;
4984         /* Nothing else to do if there is no buffer. */
4985         if (!out)
4986                 return ret;
4987         if (!out->args.vc.actions_n)
4988                 return -1;
4989         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4990         /* Point to selected object. */
4991         ctx->object = out->args.vc.data;
4992         ctx->objmask = NULL;
4993         /* Copy the headers to the buffer. */
4994         action_raw_encap_data = ctx->object;
4995         action_raw_encap_data->conf.data = raw_encap_confs[0].data;
4996         action_raw_encap_data->conf.preserve = NULL;
4997         action_raw_encap_data->conf.size = raw_encap_confs[0].size;
4998         action->conf = &action_raw_encap_data->conf;
4999         return ret;
5000 }
5001
5002 static int
5003 parse_vc_action_raw_decap(struct context *ctx, const struct token *token,
5004                           const char *str, unsigned int len, void *buf,
5005                           unsigned int size)
5006 {
5007         struct buffer *out = buf;
5008         struct rte_flow_action *action;
5009         struct action_raw_decap_data *action_raw_decap_data = NULL;
5010         int ret;
5011
5012         ret = parse_vc(ctx, token, str, len, buf, size);
5013         if (ret < 0)
5014                 return ret;
5015         /* Nothing else to do if there is no buffer. */
5016         if (!out)
5017                 return ret;
5018         if (!out->args.vc.actions_n)
5019                 return -1;
5020         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
5021         /* Point to selected object. */
5022         ctx->object = out->args.vc.data;
5023         ctx->objmask = NULL;
5024         /* Copy the headers to the buffer. */
5025         action_raw_decap_data = ctx->object;
5026         action_raw_decap_data->conf.data = raw_decap_confs[0].data;
5027         action_raw_decap_data->conf.size = raw_decap_confs[0].size;
5028         action->conf = &action_raw_decap_data->conf;
5029         return ret;
5030 }
5031
5032 static int
5033 parse_vc_action_set_meta(struct context *ctx, const struct token *token,
5034                          const char *str, unsigned int len, void *buf,
5035                          unsigned int size)
5036 {
5037         int ret;
5038
5039         ret = parse_vc(ctx, token, str, len, buf, size);
5040         if (ret < 0)
5041                 return ret;
5042         ret = rte_flow_dynf_metadata_register();
5043         if (ret < 0)
5044                 return -1;
5045         return len;
5046 }
5047
5048 /** Parse tokens for destroy command. */
5049 static int
5050 parse_destroy(struct context *ctx, const struct token *token,
5051               const char *str, unsigned int len,
5052               void *buf, unsigned int size)
5053 {
5054         struct buffer *out = buf;
5055
5056         /* Token name must match. */
5057         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5058                 return -1;
5059         /* Nothing else to do if there is no buffer. */
5060         if (!out)
5061                 return len;
5062         if (!out->command) {
5063                 if (ctx->curr != DESTROY)
5064                         return -1;
5065                 if (sizeof(*out) > size)
5066                         return -1;
5067                 out->command = ctx->curr;
5068                 ctx->objdata = 0;
5069                 ctx->object = out;
5070                 ctx->objmask = NULL;
5071                 out->args.destroy.rule =
5072                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
5073                                                sizeof(double));
5074                 return len;
5075         }
5076         if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) +
5077              sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size)
5078                 return -1;
5079         ctx->objdata = 0;
5080         ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++;
5081         ctx->objmask = NULL;
5082         return len;
5083 }
5084
5085 /** Parse tokens for flush command. */
5086 static int
5087 parse_flush(struct context *ctx, const struct token *token,
5088             const char *str, unsigned int len,
5089             void *buf, unsigned int size)
5090 {
5091         struct buffer *out = buf;
5092
5093         /* Token name must match. */
5094         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5095                 return -1;
5096         /* Nothing else to do if there is no buffer. */
5097         if (!out)
5098                 return len;
5099         if (!out->command) {
5100                 if (ctx->curr != FLUSH)
5101                         return -1;
5102                 if (sizeof(*out) > size)
5103                         return -1;
5104                 out->command = ctx->curr;
5105                 ctx->objdata = 0;
5106                 ctx->object = out;
5107                 ctx->objmask = NULL;
5108         }
5109         return len;
5110 }
5111
5112 /** Parse tokens for query command. */
5113 static int
5114 parse_query(struct context *ctx, const struct token *token,
5115             const char *str, unsigned int len,
5116             void *buf, unsigned int size)
5117 {
5118         struct buffer *out = buf;
5119
5120         /* Token name must match. */
5121         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5122                 return -1;
5123         /* Nothing else to do if there is no buffer. */
5124         if (!out)
5125                 return len;
5126         if (!out->command) {
5127                 if (ctx->curr != QUERY)
5128                         return -1;
5129                 if (sizeof(*out) > size)
5130                         return -1;
5131                 out->command = ctx->curr;
5132                 ctx->objdata = 0;
5133                 ctx->object = out;
5134                 ctx->objmask = NULL;
5135         }
5136         return len;
5137 }
5138
5139 /** Parse action names. */
5140 static int
5141 parse_action(struct context *ctx, const struct token *token,
5142              const char *str, unsigned int len,
5143              void *buf, unsigned int size)
5144 {
5145         struct buffer *out = buf;
5146         const struct arg *arg = pop_args(ctx);
5147         unsigned int i;
5148
5149         (void)size;
5150         /* Argument is expected. */
5151         if (!arg)
5152                 return -1;
5153         /* Parse action name. */
5154         for (i = 0; next_action[i]; ++i) {
5155                 const struct parse_action_priv *priv;
5156
5157                 token = &token_list[next_action[i]];
5158                 if (strcmp_partial(token->name, str, len))
5159                         continue;
5160                 priv = token->priv;
5161                 if (!priv)
5162                         goto error;
5163                 if (out)
5164                         memcpy((uint8_t *)ctx->object + arg->offset,
5165                                &priv->type,
5166                                arg->size);
5167                 return len;
5168         }
5169 error:
5170         push_args(ctx, arg);
5171         return -1;
5172 }
5173
5174 /** Parse tokens for list command. */
5175 static int
5176 parse_list(struct context *ctx, const struct token *token,
5177            const char *str, unsigned int len,
5178            void *buf, unsigned int size)
5179 {
5180         struct buffer *out = buf;
5181
5182         /* Token name must match. */
5183         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5184                 return -1;
5185         /* Nothing else to do if there is no buffer. */
5186         if (!out)
5187                 return len;
5188         if (!out->command) {
5189                 if (ctx->curr != LIST)
5190                         return -1;
5191                 if (sizeof(*out) > size)
5192                         return -1;
5193                 out->command = ctx->curr;
5194                 ctx->objdata = 0;
5195                 ctx->object = out;
5196                 ctx->objmask = NULL;
5197                 out->args.list.group =
5198                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
5199                                                sizeof(double));
5200                 return len;
5201         }
5202         if (((uint8_t *)(out->args.list.group + out->args.list.group_n) +
5203              sizeof(*out->args.list.group)) > (uint8_t *)out + size)
5204                 return -1;
5205         ctx->objdata = 0;
5206         ctx->object = out->args.list.group + out->args.list.group_n++;
5207         ctx->objmask = NULL;
5208         return len;
5209 }
5210
5211 /** Parse tokens for isolate command. */
5212 static int
5213 parse_isolate(struct context *ctx, const struct token *token,
5214               const char *str, unsigned int len,
5215               void *buf, unsigned int size)
5216 {
5217         struct buffer *out = buf;
5218
5219         /* Token name must match. */
5220         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5221                 return -1;
5222         /* Nothing else to do if there is no buffer. */
5223         if (!out)
5224                 return len;
5225         if (!out->command) {
5226                 if (ctx->curr != ISOLATE)
5227                         return -1;
5228                 if (sizeof(*out) > size)
5229                         return -1;
5230                 out->command = ctx->curr;
5231                 ctx->objdata = 0;
5232                 ctx->object = out;
5233                 ctx->objmask = NULL;
5234         }
5235         return len;
5236 }
5237
5238 /**
5239  * Parse signed/unsigned integers 8 to 64-bit long.
5240  *
5241  * Last argument (ctx->args) is retrieved to determine integer type and
5242  * storage location.
5243  */
5244 static int
5245 parse_int(struct context *ctx, const struct token *token,
5246           const char *str, unsigned int len,
5247           void *buf, unsigned int size)
5248 {
5249         const struct arg *arg = pop_args(ctx);
5250         uintmax_t u;
5251         char *end;
5252
5253         (void)token;
5254         /* Argument is expected. */
5255         if (!arg)
5256                 return -1;
5257         errno = 0;
5258         u = arg->sign ?
5259                 (uintmax_t)strtoimax(str, &end, 0) :
5260                 strtoumax(str, &end, 0);
5261         if (errno || (size_t)(end - str) != len)
5262                 goto error;
5263         if (arg->bounded &&
5264             ((arg->sign && ((intmax_t)u < (intmax_t)arg->min ||
5265                             (intmax_t)u > (intmax_t)arg->max)) ||
5266              (!arg->sign && (u < arg->min || u > arg->max))))
5267                 goto error;
5268         if (!ctx->object)
5269                 return len;
5270         if (arg->mask) {
5271                 if (!arg_entry_bf_fill(ctx->object, u, arg) ||
5272                     !arg_entry_bf_fill(ctx->objmask, -1, arg))
5273                         goto error;
5274                 return len;
5275         }
5276         buf = (uint8_t *)ctx->object + arg->offset;
5277         size = arg->size;
5278         if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t))
5279                 return -1;
5280 objmask:
5281         switch (size) {
5282         case sizeof(uint8_t):
5283                 *(uint8_t *)buf = u;
5284                 break;
5285         case sizeof(uint16_t):
5286                 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u;
5287                 break;
5288         case sizeof(uint8_t [3]):
5289 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
5290                 if (!arg->hton) {
5291                         ((uint8_t *)buf)[0] = u;
5292                         ((uint8_t *)buf)[1] = u >> 8;
5293                         ((uint8_t *)buf)[2] = u >> 16;
5294                         break;
5295                 }
5296 #endif
5297                 ((uint8_t *)buf)[0] = u >> 16;
5298                 ((uint8_t *)buf)[1] = u >> 8;
5299                 ((uint8_t *)buf)[2] = u;
5300                 break;
5301         case sizeof(uint32_t):
5302                 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u;
5303                 break;
5304         case sizeof(uint64_t):
5305                 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u;
5306                 break;
5307         default:
5308                 goto error;
5309         }
5310         if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) {
5311                 u = -1;
5312                 buf = (uint8_t *)ctx->objmask + arg->offset;
5313                 goto objmask;
5314         }
5315         return len;
5316 error:
5317         push_args(ctx, arg);
5318         return -1;
5319 }
5320
5321 /**
5322  * Parse a string.
5323  *
5324  * Three arguments (ctx->args) are retrieved from the stack to store data,
5325  * its actual length and address (in that order).
5326  */
5327 static int
5328 parse_string(struct context *ctx, const struct token *token,
5329              const char *str, unsigned int len,
5330              void *buf, unsigned int size)
5331 {
5332         const struct arg *arg_data = pop_args(ctx);
5333         const struct arg *arg_len = pop_args(ctx);
5334         const struct arg *arg_addr = pop_args(ctx);
5335         char tmp[16]; /* Ought to be enough. */
5336         int ret;
5337
5338         /* Arguments are expected. */
5339         if (!arg_data)
5340                 return -1;
5341         if (!arg_len) {
5342                 push_args(ctx, arg_data);
5343                 return -1;
5344         }
5345         if (!arg_addr) {
5346                 push_args(ctx, arg_len);
5347                 push_args(ctx, arg_data);
5348                 return -1;
5349         }
5350         size = arg_data->size;
5351         /* Bit-mask fill is not supported. */
5352         if (arg_data->mask || size < len)
5353                 goto error;
5354         if (!ctx->object)
5355                 return len;
5356         /* Let parse_int() fill length information first. */
5357         ret = snprintf(tmp, sizeof(tmp), "%u", len);
5358         if (ret < 0)
5359                 goto error;
5360         push_args(ctx, arg_len);
5361         ret = parse_int(ctx, token, tmp, ret, NULL, 0);
5362         if (ret < 0) {
5363                 pop_args(ctx);
5364                 goto error;
5365         }
5366         buf = (uint8_t *)ctx->object + arg_data->offset;
5367         /* Output buffer is not necessarily NUL-terminated. */
5368         memcpy(buf, str, len);
5369         memset((uint8_t *)buf + len, 0x00, size - len);
5370         if (ctx->objmask)
5371                 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len);
5372         /* Save address if requested. */
5373         if (arg_addr->size) {
5374                 memcpy((uint8_t *)ctx->object + arg_addr->offset,
5375                        (void *[]){
5376                         (uint8_t *)ctx->object + arg_data->offset
5377                        },
5378                        arg_addr->size);
5379                 if (ctx->objmask)
5380                         memcpy((uint8_t *)ctx->objmask + arg_addr->offset,
5381                                (void *[]){
5382                                 (uint8_t *)ctx->objmask + arg_data->offset
5383                                },
5384                                arg_addr->size);
5385         }
5386         return len;
5387 error:
5388         push_args(ctx, arg_addr);
5389         push_args(ctx, arg_len);
5390         push_args(ctx, arg_data);
5391         return -1;
5392 }
5393
5394 static int
5395 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size)
5396 {
5397         char *c = NULL;
5398         uint32_t i, len;
5399         char tmp[3];
5400
5401         /* Check input parameters */
5402         if ((src == NULL) ||
5403                 (dst == NULL) ||
5404                 (size == NULL) ||
5405                 (*size == 0))
5406                 return -1;
5407
5408         /* Convert chars to bytes */
5409         for (i = 0, len = 0; i < *size; i += 2) {
5410                 snprintf(tmp, 3, "%s", src + i);
5411                 dst[len++] = strtoul(tmp, &c, 16);
5412                 if (*c != 0) {
5413                         len--;
5414                         dst[len] = 0;
5415                         *size = len;
5416                         return -1;
5417                 }
5418         }
5419         dst[len] = 0;
5420         *size = len;
5421
5422         return 0;
5423 }
5424
5425 static int
5426 parse_hex(struct context *ctx, const struct token *token,
5427                 const char *str, unsigned int len,
5428                 void *buf, unsigned int size)
5429 {
5430         const struct arg *arg_data = pop_args(ctx);
5431         const struct arg *arg_len = pop_args(ctx);
5432         const struct arg *arg_addr = pop_args(ctx);
5433         char tmp[16]; /* Ought to be enough. */
5434         int ret;
5435         unsigned int hexlen = len;
5436         unsigned int length = 256;
5437         uint8_t hex_tmp[length];
5438
5439         /* Arguments are expected. */
5440         if (!arg_data)
5441                 return -1;
5442         if (!arg_len) {
5443                 push_args(ctx, arg_data);
5444                 return -1;
5445         }
5446         if (!arg_addr) {
5447                 push_args(ctx, arg_len);
5448                 push_args(ctx, arg_data);
5449                 return -1;
5450         }
5451         size = arg_data->size;
5452         /* Bit-mask fill is not supported. */
5453         if (arg_data->mask)
5454                 goto error;
5455         if (!ctx->object)
5456                 return len;
5457
5458         /* translate bytes string to array. */
5459         if (str[0] == '0' && ((str[1] == 'x') ||
5460                         (str[1] == 'X'))) {
5461                 str += 2;
5462                 hexlen -= 2;
5463         }
5464         if (hexlen > length)
5465                 return -1;
5466         ret = parse_hex_string(str, hex_tmp, &hexlen);
5467         if (ret < 0)
5468                 goto error;
5469         /* Let parse_int() fill length information first. */
5470         ret = snprintf(tmp, sizeof(tmp), "%u", hexlen);
5471         if (ret < 0)
5472                 goto error;
5473         push_args(ctx, arg_len);
5474         ret = parse_int(ctx, token, tmp, ret, NULL, 0);
5475         if (ret < 0) {
5476                 pop_args(ctx);
5477                 goto error;
5478         }
5479         buf = (uint8_t *)ctx->object + arg_data->offset;
5480         /* Output buffer is not necessarily NUL-terminated. */
5481         memcpy(buf, hex_tmp, hexlen);
5482         memset((uint8_t *)buf + hexlen, 0x00, size - hexlen);
5483         if (ctx->objmask)
5484                 memset((uint8_t *)ctx->objmask + arg_data->offset,
5485                                         0xff, hexlen);
5486         /* Save address if requested. */
5487         if (arg_addr->size) {
5488                 memcpy((uint8_t *)ctx->object + arg_addr->offset,
5489                        (void *[]){
5490                         (uint8_t *)ctx->object + arg_data->offset
5491                        },
5492                        arg_addr->size);
5493                 if (ctx->objmask)
5494                         memcpy((uint8_t *)ctx->objmask + arg_addr->offset,
5495                                (void *[]){
5496                                 (uint8_t *)ctx->objmask + arg_data->offset
5497                                },
5498                                arg_addr->size);
5499         }
5500         return len;
5501 error:
5502         push_args(ctx, arg_addr);
5503         push_args(ctx, arg_len);
5504         push_args(ctx, arg_data);
5505         return -1;
5506
5507 }
5508
5509 /**
5510  * Parse a MAC address.
5511  *
5512  * Last argument (ctx->args) is retrieved to determine storage size and
5513  * location.
5514  */
5515 static int
5516 parse_mac_addr(struct context *ctx, const struct token *token,
5517                const char *str, unsigned int len,
5518                void *buf, unsigned int size)
5519 {
5520         const struct arg *arg = pop_args(ctx);
5521         struct rte_ether_addr tmp;
5522         int ret;
5523
5524         (void)token;
5525         /* Argument is expected. */
5526         if (!arg)
5527                 return -1;
5528         size = arg->size;
5529         /* Bit-mask fill is not supported. */
5530         if (arg->mask || size != sizeof(tmp))
5531                 goto error;
5532         /* Only network endian is supported. */
5533         if (!arg->hton)
5534                 goto error;
5535         ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
5536         if (ret < 0 || (unsigned int)ret != len)
5537                 goto error;
5538         if (!ctx->object)
5539                 return len;
5540         buf = (uint8_t *)ctx->object + arg->offset;
5541         memcpy(buf, &tmp, size);
5542         if (ctx->objmask)
5543                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
5544         return len;
5545 error:
5546         push_args(ctx, arg);
5547         return -1;
5548 }
5549
5550 /**
5551  * Parse an IPv4 address.
5552  *
5553  * Last argument (ctx->args) is retrieved to determine storage size and
5554  * location.
5555  */
5556 static int
5557 parse_ipv4_addr(struct context *ctx, const struct token *token,
5558                 const char *str, unsigned int len,
5559                 void *buf, unsigned int size)
5560 {
5561         const struct arg *arg = pop_args(ctx);
5562         char str2[len + 1];
5563         struct in_addr tmp;
5564         int ret;
5565
5566         /* Argument is expected. */
5567         if (!arg)
5568                 return -1;
5569         size = arg->size;
5570         /* Bit-mask fill is not supported. */
5571         if (arg->mask || size != sizeof(tmp))
5572                 goto error;
5573         /* Only network endian is supported. */
5574         if (!arg->hton)
5575                 goto error;
5576         memcpy(str2, str, len);
5577         str2[len] = '\0';
5578         ret = inet_pton(AF_INET, str2, &tmp);
5579         if (ret != 1) {
5580                 /* Attempt integer parsing. */
5581                 push_args(ctx, arg);
5582                 return parse_int(ctx, token, str, len, buf, size);
5583         }
5584         if (!ctx->object)
5585                 return len;
5586         buf = (uint8_t *)ctx->object + arg->offset;
5587         memcpy(buf, &tmp, size);
5588         if (ctx->objmask)
5589                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
5590         return len;
5591 error:
5592         push_args(ctx, arg);
5593         return -1;
5594 }
5595
5596 /**
5597  * Parse an IPv6 address.
5598  *
5599  * Last argument (ctx->args) is retrieved to determine storage size and
5600  * location.
5601  */
5602 static int
5603 parse_ipv6_addr(struct context *ctx, const struct token *token,
5604                 const char *str, unsigned int len,
5605                 void *buf, unsigned int size)
5606 {
5607         const struct arg *arg = pop_args(ctx);
5608         char str2[len + 1];
5609         struct in6_addr tmp;
5610         int ret;
5611
5612         (void)token;
5613         /* Argument is expected. */
5614         if (!arg)
5615                 return -1;
5616         size = arg->size;
5617         /* Bit-mask fill is not supported. */
5618         if (arg->mask || size != sizeof(tmp))
5619                 goto error;
5620         /* Only network endian is supported. */
5621         if (!arg->hton)
5622                 goto error;
5623         memcpy(str2, str, len);
5624         str2[len] = '\0';
5625         ret = inet_pton(AF_INET6, str2, &tmp);
5626         if (ret != 1)
5627                 goto error;
5628         if (!ctx->object)
5629                 return len;
5630         buf = (uint8_t *)ctx->object + arg->offset;
5631         memcpy(buf, &tmp, size);
5632         if (ctx->objmask)
5633                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
5634         return len;
5635 error:
5636         push_args(ctx, arg);
5637         return -1;
5638 }
5639
5640 /** Boolean values (even indices stand for false). */
5641 static const char *const boolean_name[] = {
5642         "0", "1",
5643         "false", "true",
5644         "no", "yes",
5645         "N", "Y",
5646         "off", "on",
5647         NULL,
5648 };
5649
5650 /**
5651  * Parse a boolean value.
5652  *
5653  * Last argument (ctx->args) is retrieved to determine storage size and
5654  * location.
5655  */
5656 static int
5657 parse_boolean(struct context *ctx, const struct token *token,
5658               const char *str, unsigned int len,
5659               void *buf, unsigned int size)
5660 {
5661         const struct arg *arg = pop_args(ctx);
5662         unsigned int i;
5663         int ret;
5664
5665         /* Argument is expected. */
5666         if (!arg)
5667                 return -1;
5668         for (i = 0; boolean_name[i]; ++i)
5669                 if (!strcmp_partial(boolean_name[i], str, len))
5670                         break;
5671         /* Process token as integer. */
5672         if (boolean_name[i])
5673                 str = i & 1 ? "1" : "0";
5674         push_args(ctx, arg);
5675         ret = parse_int(ctx, token, str, strlen(str), buf, size);
5676         return ret > 0 ? (int)len : ret;
5677 }
5678
5679 /** Parse port and update context. */
5680 static int
5681 parse_port(struct context *ctx, const struct token *token,
5682            const char *str, unsigned int len,
5683            void *buf, unsigned int size)
5684 {
5685         struct buffer *out = &(struct buffer){ .port = 0 };
5686         int ret;
5687
5688         if (buf)
5689                 out = buf;
5690         else {
5691                 ctx->objdata = 0;
5692                 ctx->object = out;
5693                 ctx->objmask = NULL;
5694                 size = sizeof(*out);
5695         }
5696         ret = parse_int(ctx, token, str, len, out, size);
5697         if (ret >= 0)
5698                 ctx->port = out->port;
5699         if (!buf)
5700                 ctx->object = NULL;
5701         return ret;
5702 }
5703
5704 /** Parse set command, initialize output buffer for subsequent tokens. */
5705 static int
5706 parse_set_raw_encap_decap(struct context *ctx, const struct token *token,
5707                           const char *str, unsigned int len,
5708                           void *buf, unsigned int size)
5709 {
5710         struct buffer *out = buf;
5711
5712         /* Token name must match. */
5713         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5714                 return -1;
5715         /* Nothing else to do if there is no buffer. */
5716         if (!out)
5717                 return len;
5718         /* Make sure buffer is large enough. */
5719         if (size < sizeof(*out))
5720                 return -1;
5721         ctx->objdata = 0;
5722         ctx->objmask = NULL;
5723         ctx->object = out;
5724         if (!out->command)
5725                 return -1;
5726         out->command = ctx->curr;
5727         return len;
5728 }
5729
5730 /**
5731  * Parse set raw_encap/raw_decap command,
5732  * initialize output buffer for subsequent tokens.
5733  */
5734 static int
5735 parse_set_init(struct context *ctx, const struct token *token,
5736                const char *str, unsigned int len,
5737                void *buf, unsigned int size)
5738 {
5739         struct buffer *out = buf;
5740
5741         /* Token name must match. */
5742         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5743                 return -1;
5744         /* Nothing else to do if there is no buffer. */
5745         if (!out)
5746                 return len;
5747         /* Make sure buffer is large enough. */
5748         if (size < sizeof(*out))
5749                 return -1;
5750         /* Initialize buffer. */
5751         memset(out, 0x00, sizeof(*out));
5752         memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out));
5753         ctx->objdata = 0;
5754         ctx->object = out;
5755         ctx->objmask = NULL;
5756         if (!out->command) {
5757                 if (ctx->curr != SET)
5758                         return -1;
5759                 if (sizeof(*out) > size)
5760                         return -1;
5761                 out->command = ctx->curr;
5762                 out->args.vc.data = (uint8_t *)out + size;
5763                 /* All we need is pattern */
5764                 out->args.vc.pattern =
5765                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
5766                                                sizeof(double));
5767                 ctx->object = out->args.vc.pattern;
5768         }
5769         return len;
5770 }
5771
5772 /** No completion. */
5773 static int
5774 comp_none(struct context *ctx, const struct token *token,
5775           unsigned int ent, char *buf, unsigned int size)
5776 {
5777         (void)ctx;
5778         (void)token;
5779         (void)ent;
5780         (void)buf;
5781         (void)size;
5782         return 0;
5783 }
5784
5785 /** Complete boolean values. */
5786 static int
5787 comp_boolean(struct context *ctx, const struct token *token,
5788              unsigned int ent, char *buf, unsigned int size)
5789 {
5790         unsigned int i;
5791
5792         (void)ctx;
5793         (void)token;
5794         for (i = 0; boolean_name[i]; ++i)
5795                 if (buf && i == ent)
5796                         return strlcpy(buf, boolean_name[i], size);
5797         if (buf)
5798                 return -1;
5799         return i;
5800 }
5801
5802 /** Complete action names. */
5803 static int
5804 comp_action(struct context *ctx, const struct token *token,
5805             unsigned int ent, char *buf, unsigned int size)
5806 {
5807         unsigned int i;
5808
5809         (void)ctx;
5810         (void)token;
5811         for (i = 0; next_action[i]; ++i)
5812                 if (buf && i == ent)
5813                         return strlcpy(buf, token_list[next_action[i]].name,
5814                                        size);
5815         if (buf)
5816                 return -1;
5817         return i;
5818 }
5819
5820 /** Complete available ports. */
5821 static int
5822 comp_port(struct context *ctx, const struct token *token,
5823           unsigned int ent, char *buf, unsigned int size)
5824 {
5825         unsigned int i = 0;
5826         portid_t p;
5827
5828         (void)ctx;
5829         (void)token;
5830         RTE_ETH_FOREACH_DEV(p) {
5831                 if (buf && i == ent)
5832                         return snprintf(buf, size, "%u", p);
5833                 ++i;
5834         }
5835         if (buf)
5836                 return -1;
5837         return i;
5838 }
5839
5840 /** Complete available rule IDs. */
5841 static int
5842 comp_rule_id(struct context *ctx, const struct token *token,
5843              unsigned int ent, char *buf, unsigned int size)
5844 {
5845         unsigned int i = 0;
5846         struct rte_port *port;
5847         struct port_flow *pf;
5848
5849         (void)token;
5850         if (port_id_is_invalid(ctx->port, DISABLED_WARN) ||
5851             ctx->port == (portid_t)RTE_PORT_ALL)
5852                 return -1;
5853         port = &ports[ctx->port];
5854         for (pf = port->flow_list; pf != NULL; pf = pf->next) {
5855                 if (buf && i == ent)
5856                         return snprintf(buf, size, "%u", pf->id);
5857                 ++i;
5858         }
5859         if (buf)
5860                 return -1;
5861         return i;
5862 }
5863
5864 /** Complete type field for RSS action. */
5865 static int
5866 comp_vc_action_rss_type(struct context *ctx, const struct token *token,
5867                         unsigned int ent, char *buf, unsigned int size)
5868 {
5869         unsigned int i;
5870
5871         (void)ctx;
5872         (void)token;
5873         for (i = 0; rss_type_table[i].str; ++i)
5874                 ;
5875         if (!buf)
5876                 return i + 1;
5877         if (ent < i)
5878                 return strlcpy(buf, rss_type_table[ent].str, size);
5879         if (ent == i)
5880                 return snprintf(buf, size, "end");
5881         return -1;
5882 }
5883
5884 /** Complete queue field for RSS action. */
5885 static int
5886 comp_vc_action_rss_queue(struct context *ctx, const struct token *token,
5887                          unsigned int ent, char *buf, unsigned int size)
5888 {
5889         (void)ctx;
5890         (void)token;
5891         if (!buf)
5892                 return nb_rxq + 1;
5893         if (ent < nb_rxq)
5894                 return snprintf(buf, size, "%u", ent);
5895         if (ent == nb_rxq)
5896                 return snprintf(buf, size, "end");
5897         return -1;
5898 }
5899
5900 /** Complete index number for set raw_encap/raw_decap commands. */
5901 static int
5902 comp_set_raw_index(struct context *ctx, const struct token *token,
5903                    unsigned int ent, char *buf, unsigned int size)
5904 {
5905         uint16_t idx = 0;
5906         uint16_t nb = 0;
5907
5908         RTE_SET_USED(ctx);
5909         RTE_SET_USED(token);
5910         for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) {
5911                 if (buf && idx == ent)
5912                         return snprintf(buf, size, "%u", idx);
5913                 ++nb;
5914         }
5915         return nb;
5916 }
5917
5918 /** Internal context. */
5919 static struct context cmd_flow_context;
5920
5921 /** Global parser instance (cmdline API). */
5922 cmdline_parse_inst_t cmd_flow;
5923 cmdline_parse_inst_t cmd_set_raw;
5924
5925 /** Initialize context. */
5926 static void
5927 cmd_flow_context_init(struct context *ctx)
5928 {
5929         /* A full memset() is not necessary. */
5930         ctx->curr = ZERO;
5931         ctx->prev = ZERO;
5932         ctx->next_num = 0;
5933         ctx->args_num = 0;
5934         ctx->eol = 0;
5935         ctx->last = 0;
5936         ctx->port = 0;
5937         ctx->objdata = 0;
5938         ctx->object = NULL;
5939         ctx->objmask = NULL;
5940 }
5941
5942 /** Parse a token (cmdline API). */
5943 static int
5944 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result,
5945                unsigned int size)
5946 {
5947         struct context *ctx = &cmd_flow_context;
5948         const struct token *token;
5949         const enum index *list;
5950         int len;
5951         int i;
5952
5953         (void)hdr;
5954         token = &token_list[ctx->curr];
5955         /* Check argument length. */
5956         ctx->eol = 0;
5957         ctx->last = 1;
5958         for (len = 0; src[len]; ++len)
5959                 if (src[len] == '#' || isspace(src[len]))
5960                         break;
5961         if (!len)
5962                 return -1;
5963         /* Last argument and EOL detection. */
5964         for (i = len; src[i]; ++i)
5965                 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n')
5966                         break;
5967                 else if (!isspace(src[i])) {
5968                         ctx->last = 0;
5969                         break;
5970                 }
5971         for (; src[i]; ++i)
5972                 if (src[i] == '\r' || src[i] == '\n') {
5973                         ctx->eol = 1;
5974                         break;
5975                 }
5976         /* Initialize context if necessary. */
5977         if (!ctx->next_num) {
5978                 if (!token->next)
5979                         return 0;
5980                 ctx->next[ctx->next_num++] = token->next[0];
5981         }
5982         /* Process argument through candidates. */
5983         ctx->prev = ctx->curr;
5984         list = ctx->next[ctx->next_num - 1];
5985         for (i = 0; list[i]; ++i) {
5986                 const struct token *next = &token_list[list[i]];
5987                 int tmp;
5988
5989                 ctx->curr = list[i];
5990                 if (next->call)
5991                         tmp = next->call(ctx, next, src, len, result, size);
5992                 else
5993                         tmp = parse_default(ctx, next, src, len, result, size);
5994                 if (tmp == -1 || tmp != len)
5995                         continue;
5996                 token = next;
5997                 break;
5998         }
5999         if (!list[i])
6000                 return -1;
6001         --ctx->next_num;
6002         /* Push subsequent tokens if any. */
6003         if (token->next)
6004                 for (i = 0; token->next[i]; ++i) {
6005                         if (ctx->next_num == RTE_DIM(ctx->next))
6006                                 return -1;
6007                         ctx->next[ctx->next_num++] = token->next[i];
6008                 }
6009         /* Push arguments if any. */
6010         if (token->args)
6011                 for (i = 0; token->args[i]; ++i) {
6012                         if (ctx->args_num == RTE_DIM(ctx->args))
6013                                 return -1;
6014                         ctx->args[ctx->args_num++] = token->args[i];
6015                 }
6016         return len;
6017 }
6018
6019 /** Return number of completion entries (cmdline API). */
6020 static int
6021 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr)
6022 {
6023         struct context *ctx = &cmd_flow_context;
6024         const struct token *token = &token_list[ctx->curr];
6025         const enum index *list;
6026         int i;
6027
6028         (void)hdr;
6029         /* Count number of tokens in current list. */
6030         if (ctx->next_num)
6031                 list = ctx->next[ctx->next_num - 1];
6032         else
6033                 list = token->next[0];
6034         for (i = 0; list[i]; ++i)
6035                 ;
6036         if (!i)
6037                 return 0;
6038         /*
6039          * If there is a single token, use its completion callback, otherwise
6040          * return the number of entries.
6041          */
6042         token = &token_list[list[0]];
6043         if (i == 1 && token->comp) {
6044                 /* Save index for cmd_flow_get_help(). */
6045                 ctx->prev = list[0];
6046                 return token->comp(ctx, token, 0, NULL, 0);
6047         }
6048         return i;
6049 }
6050
6051 /** Return a completion entry (cmdline API). */
6052 static int
6053 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index,
6054                           char *dst, unsigned int size)
6055 {
6056         struct context *ctx = &cmd_flow_context;
6057         const struct token *token = &token_list[ctx->curr];
6058         const enum index *list;
6059         int i;
6060
6061         (void)hdr;
6062         /* Count number of tokens in current list. */
6063         if (ctx->next_num)
6064                 list = ctx->next[ctx->next_num - 1];
6065         else
6066                 list = token->next[0];
6067         for (i = 0; list[i]; ++i)
6068                 ;
6069         if (!i)
6070                 return -1;
6071         /* If there is a single token, use its completion callback. */
6072         token = &token_list[list[0]];
6073         if (i == 1 && token->comp) {
6074                 /* Save index for cmd_flow_get_help(). */
6075                 ctx->prev = list[0];
6076                 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0;
6077         }
6078         /* Otherwise make sure the index is valid and use defaults. */
6079         if (index >= i)
6080                 return -1;
6081         token = &token_list[list[index]];
6082         strlcpy(dst, token->name, size);
6083         /* Save index for cmd_flow_get_help(). */
6084         ctx->prev = list[index];
6085         return 0;
6086 }
6087
6088 /** Populate help strings for current token (cmdline API). */
6089 static int
6090 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size)
6091 {
6092         struct context *ctx = &cmd_flow_context;
6093         const struct token *token = &token_list[ctx->prev];
6094
6095         (void)hdr;
6096         if (!size)
6097                 return -1;
6098         /* Set token type and update global help with details. */
6099         strlcpy(dst, (token->type ? token->type : "TOKEN"), size);
6100         if (token->help)
6101                 cmd_flow.help_str = token->help;
6102         else
6103                 cmd_flow.help_str = token->name;
6104         return 0;
6105 }
6106
6107 /** Token definition template (cmdline API). */
6108 static struct cmdline_token_hdr cmd_flow_token_hdr = {
6109         .ops = &(struct cmdline_token_ops){
6110                 .parse = cmd_flow_parse,
6111                 .complete_get_nb = cmd_flow_complete_get_nb,
6112                 .complete_get_elt = cmd_flow_complete_get_elt,
6113                 .get_help = cmd_flow_get_help,
6114         },
6115         .offset = 0,
6116 };
6117
6118 /** Populate the next dynamic token. */
6119 static void
6120 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr,
6121              cmdline_parse_token_hdr_t **hdr_inst)
6122 {
6123         struct context *ctx = &cmd_flow_context;
6124
6125         /* Always reinitialize context before requesting the first token. */
6126         if (!(hdr_inst - cmd_flow.tokens))
6127                 cmd_flow_context_init(ctx);
6128         /* Return NULL when no more tokens are expected. */
6129         if (!ctx->next_num && ctx->curr) {
6130                 *hdr = NULL;
6131                 return;
6132         }
6133         /* Determine if command should end here. */
6134         if (ctx->eol && ctx->last && ctx->next_num) {
6135                 const enum index *list = ctx->next[ctx->next_num - 1];
6136                 int i;
6137
6138                 for (i = 0; list[i]; ++i) {
6139                         if (list[i] != END)
6140                                 continue;
6141                         *hdr = NULL;
6142                         return;
6143                 }
6144         }
6145         *hdr = &cmd_flow_token_hdr;
6146 }
6147
6148 /** Dispatch parsed buffer to function calls. */
6149 static void
6150 cmd_flow_parsed(const struct buffer *in)
6151 {
6152         switch (in->command) {
6153         case VALIDATE:
6154                 port_flow_validate(in->port, &in->args.vc.attr,
6155                                    in->args.vc.pattern, in->args.vc.actions);
6156                 break;
6157         case CREATE:
6158                 port_flow_create(in->port, &in->args.vc.attr,
6159                                  in->args.vc.pattern, in->args.vc.actions);
6160                 break;
6161         case DESTROY:
6162                 port_flow_destroy(in->port, in->args.destroy.rule_n,
6163                                   in->args.destroy.rule);
6164                 break;
6165         case FLUSH:
6166                 port_flow_flush(in->port);
6167                 break;
6168         case QUERY:
6169                 port_flow_query(in->port, in->args.query.rule,
6170                                 &in->args.query.action);
6171                 break;
6172         case LIST:
6173                 port_flow_list(in->port, in->args.list.group_n,
6174                                in->args.list.group);
6175                 break;
6176         case ISOLATE:
6177                 port_flow_isolate(in->port, in->args.isolate.set);
6178                 break;
6179         default:
6180                 break;
6181         }
6182 }
6183
6184 /** Token generator and output processing callback (cmdline API). */
6185 static void
6186 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2)
6187 {
6188         if (cl == NULL)
6189                 cmd_flow_tok(arg0, arg2);
6190         else
6191                 cmd_flow_parsed(arg0);
6192 }
6193
6194 /** Global parser instance (cmdline API). */
6195 cmdline_parse_inst_t cmd_flow = {
6196         .f = cmd_flow_cb,
6197         .data = NULL, /**< Unused. */
6198         .help_str = NULL, /**< Updated by cmd_flow_get_help(). */
6199         .tokens = {
6200                 NULL,
6201         }, /**< Tokens are returned by cmd_flow_tok(). */
6202 };
6203
6204 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */
6205
6206 static void
6207 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto)
6208 {
6209         struct rte_flow_item_ipv4 *ipv4;
6210         struct rte_flow_item_eth *eth;
6211         struct rte_flow_item_ipv6 *ipv6;
6212         struct rte_flow_item_vxlan *vxlan;
6213         struct rte_flow_item_vxlan_gpe *gpe;
6214         struct rte_flow_item_nvgre *nvgre;
6215         uint32_t ipv6_vtc_flow;
6216
6217         switch (item->type) {
6218         case RTE_FLOW_ITEM_TYPE_ETH:
6219                 eth = (struct rte_flow_item_eth *)buf;
6220                 if (next_proto)
6221                         eth->type = rte_cpu_to_be_16(next_proto);
6222                 break;
6223         case RTE_FLOW_ITEM_TYPE_IPV4:
6224                 ipv4 = (struct rte_flow_item_ipv4 *)buf;
6225                 ipv4->hdr.version_ihl = 0x45;
6226                 if (next_proto && ipv4->hdr.next_proto_id == 0)
6227                         ipv4->hdr.next_proto_id = (uint8_t)next_proto;
6228                 break;
6229         case RTE_FLOW_ITEM_TYPE_IPV6:
6230                 ipv6 = (struct rte_flow_item_ipv6 *)buf;
6231                 if (next_proto && ipv6->hdr.proto == 0)
6232                         ipv6->hdr.proto = (uint8_t)next_proto;
6233                 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->hdr.vtc_flow);
6234                 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */
6235                 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */
6236                 ipv6->hdr.vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow);
6237                 break;
6238         case RTE_FLOW_ITEM_TYPE_VXLAN:
6239                 vxlan = (struct rte_flow_item_vxlan *)buf;
6240                 vxlan->flags = 0x08;
6241                 break;
6242         case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
6243                 gpe = (struct rte_flow_item_vxlan_gpe *)buf;
6244                 gpe->flags = 0x0C;
6245                 break;
6246         case RTE_FLOW_ITEM_TYPE_NVGRE:
6247                 nvgre = (struct rte_flow_item_nvgre *)buf;
6248                 nvgre->protocol = rte_cpu_to_be_16(0x6558);
6249                 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000);
6250                 break;
6251         default:
6252                 break;
6253         }
6254 }
6255
6256 /** Helper of get item's default mask. */
6257 static const void *
6258 flow_item_default_mask(const struct rte_flow_item *item)
6259 {
6260         const void *mask = NULL;
6261         static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX);
6262
6263         switch (item->type) {
6264         case RTE_FLOW_ITEM_TYPE_ANY:
6265                 mask = &rte_flow_item_any_mask;
6266                 break;
6267         case RTE_FLOW_ITEM_TYPE_VF:
6268                 mask = &rte_flow_item_vf_mask;
6269                 break;
6270         case RTE_FLOW_ITEM_TYPE_PORT_ID:
6271                 mask = &rte_flow_item_port_id_mask;
6272                 break;
6273         case RTE_FLOW_ITEM_TYPE_RAW:
6274                 mask = &rte_flow_item_raw_mask;
6275                 break;
6276         case RTE_FLOW_ITEM_TYPE_ETH:
6277                 mask = &rte_flow_item_eth_mask;
6278                 break;
6279         case RTE_FLOW_ITEM_TYPE_VLAN:
6280                 mask = &rte_flow_item_vlan_mask;
6281                 break;
6282         case RTE_FLOW_ITEM_TYPE_IPV4:
6283                 mask = &rte_flow_item_ipv4_mask;
6284                 break;
6285         case RTE_FLOW_ITEM_TYPE_IPV6:
6286                 mask = &rte_flow_item_ipv6_mask;
6287                 break;
6288         case RTE_FLOW_ITEM_TYPE_ICMP:
6289                 mask = &rte_flow_item_icmp_mask;
6290                 break;
6291         case RTE_FLOW_ITEM_TYPE_UDP:
6292                 mask = &rte_flow_item_udp_mask;
6293                 break;
6294         case RTE_FLOW_ITEM_TYPE_TCP:
6295                 mask = &rte_flow_item_tcp_mask;
6296                 break;
6297         case RTE_FLOW_ITEM_TYPE_SCTP:
6298                 mask = &rte_flow_item_sctp_mask;
6299                 break;
6300         case RTE_FLOW_ITEM_TYPE_VXLAN:
6301                 mask = &rte_flow_item_vxlan_mask;
6302                 break;
6303         case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
6304                 mask = &rte_flow_item_vxlan_gpe_mask;
6305                 break;
6306         case RTE_FLOW_ITEM_TYPE_E_TAG:
6307                 mask = &rte_flow_item_e_tag_mask;
6308                 break;
6309         case RTE_FLOW_ITEM_TYPE_NVGRE:
6310                 mask = &rte_flow_item_nvgre_mask;
6311                 break;
6312         case RTE_FLOW_ITEM_TYPE_MPLS:
6313                 mask = &rte_flow_item_mpls_mask;
6314                 break;
6315         case RTE_FLOW_ITEM_TYPE_GRE:
6316                 mask = &rte_flow_item_gre_mask;
6317                 break;
6318         case RTE_FLOW_ITEM_TYPE_GRE_KEY:
6319                 mask = &gre_key_default_mask;
6320                 break;
6321         case RTE_FLOW_ITEM_TYPE_META:
6322                 mask = &rte_flow_item_meta_mask;
6323                 break;
6324         case RTE_FLOW_ITEM_TYPE_FUZZY:
6325                 mask = &rte_flow_item_fuzzy_mask;
6326                 break;
6327         case RTE_FLOW_ITEM_TYPE_GTP:
6328                 mask = &rte_flow_item_gtp_mask;
6329                 break;
6330         case RTE_FLOW_ITEM_TYPE_GTP_PSC:
6331                 mask = &rte_flow_item_gtp_psc_mask;
6332                 break;
6333         case RTE_FLOW_ITEM_TYPE_GENEVE:
6334                 mask = &rte_flow_item_geneve_mask;
6335                 break;
6336         case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID:
6337                 mask = &rte_flow_item_pppoe_proto_id_mask;
6338                 break;
6339         case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
6340                 mask = &rte_flow_item_l2tpv3oip_mask;
6341                 break;
6342         case RTE_FLOW_ITEM_TYPE_ESP:
6343                 mask = &rte_flow_item_esp_mask;
6344                 break;
6345         default:
6346                 break;
6347         }
6348         return mask;
6349 }
6350
6351
6352
6353 /** Dispatch parsed buffer to function calls. */
6354 static void
6355 cmd_set_raw_parsed(const struct buffer *in)
6356 {
6357         uint32_t n = in->args.vc.pattern_n;
6358         int i = 0;
6359         struct rte_flow_item *item = NULL;
6360         size_t size = 0;
6361         uint8_t *data = NULL;
6362         uint8_t *data_tail = NULL;
6363         size_t *total_size = NULL;
6364         uint16_t upper_layer = 0;
6365         uint16_t proto = 0;
6366         uint16_t idx = in->port; /* We borrow port field as index */
6367
6368         RTE_ASSERT(in->command == SET_RAW_ENCAP ||
6369                    in->command == SET_RAW_DECAP);
6370         if (in->command == SET_RAW_ENCAP) {
6371                 total_size = &raw_encap_confs[idx].size;
6372                 data = (uint8_t *)&raw_encap_confs[idx].data;
6373         } else {
6374                 total_size = &raw_decap_confs[idx].size;
6375                 data = (uint8_t *)&raw_decap_confs[idx].data;
6376         }
6377         *total_size = 0;
6378         memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA);
6379         /* process hdr from upper layer to low layer (L3/L4 -> L2). */
6380         data_tail = data + ACTION_RAW_ENCAP_MAX_DATA;
6381         for (i = n - 1 ; i >= 0; --i) {
6382                 item = in->args.vc.pattern + i;
6383                 if (item->spec == NULL)
6384                         item->spec = flow_item_default_mask(item);
6385                 switch (item->type) {
6386                 case RTE_FLOW_ITEM_TYPE_ETH:
6387                         size = sizeof(struct rte_flow_item_eth);
6388                         break;
6389                 case RTE_FLOW_ITEM_TYPE_VLAN:
6390                         size = sizeof(struct rte_flow_item_vlan);
6391                         proto = RTE_ETHER_TYPE_VLAN;
6392                         break;
6393                 case RTE_FLOW_ITEM_TYPE_IPV4:
6394                         size = sizeof(struct rte_flow_item_ipv4);
6395                         proto = RTE_ETHER_TYPE_IPV4;
6396                         break;
6397                 case RTE_FLOW_ITEM_TYPE_IPV6:
6398                         size = sizeof(struct rte_flow_item_ipv6);
6399                         proto = RTE_ETHER_TYPE_IPV6;
6400                         break;
6401                 case RTE_FLOW_ITEM_TYPE_UDP:
6402                         size = sizeof(struct rte_flow_item_udp);
6403                         proto = 0x11;
6404                         break;
6405                 case RTE_FLOW_ITEM_TYPE_TCP:
6406                         size = sizeof(struct rte_flow_item_tcp);
6407                         proto = 0x06;
6408                         break;
6409                 case RTE_FLOW_ITEM_TYPE_VXLAN:
6410                         size = sizeof(struct rte_flow_item_vxlan);
6411                         break;
6412                 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
6413                         size = sizeof(struct rte_flow_item_vxlan_gpe);
6414                         break;
6415                 case RTE_FLOW_ITEM_TYPE_GRE:
6416                         size = sizeof(struct rte_flow_item_gre);
6417                         proto = 0x2F;
6418                         break;
6419                 case RTE_FLOW_ITEM_TYPE_GRE_KEY:
6420                         size = sizeof(rte_be32_t);
6421                         proto = 0x0;
6422                         break;
6423                 case RTE_FLOW_ITEM_TYPE_MPLS:
6424                         size = sizeof(struct rte_flow_item_mpls);
6425                         proto = 0x0;
6426                         break;
6427                 case RTE_FLOW_ITEM_TYPE_NVGRE:
6428                         size = sizeof(struct rte_flow_item_nvgre);
6429                         proto = 0x2F;
6430                         break;
6431                 case RTE_FLOW_ITEM_TYPE_GENEVE:
6432                         size = sizeof(struct rte_flow_item_geneve);
6433                         break;
6434                 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
6435                         size = sizeof(struct rte_flow_item_l2tpv3oip);
6436                         proto = 0x73;
6437                         break;
6438                 case RTE_FLOW_ITEM_TYPE_ESP:
6439                         size = sizeof(struct rte_flow_item_esp);
6440                         proto = 0x32;
6441                         break;
6442                 default:
6443                         printf("Error - Not supported item\n");
6444                         *total_size = 0;
6445                         memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA);
6446                         return;
6447                 }
6448                 *total_size += size;
6449                 rte_memcpy(data_tail - (*total_size), item->spec, size);
6450                 /* update some fields which cannot be set by cmdline */
6451                 update_fields((data_tail - (*total_size)), item,
6452                               upper_layer);
6453                 upper_layer = proto;
6454         }
6455         if (verbose_level & 0x1)
6456                 printf("total data size is %zu\n", (*total_size));
6457         RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA);
6458         memmove(data, (data_tail - (*total_size)), *total_size);
6459 }
6460
6461 /** Populate help strings for current token (cmdline API). */
6462 static int
6463 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst,
6464                      unsigned int size)
6465 {
6466         struct context *ctx = &cmd_flow_context;
6467         const struct token *token = &token_list[ctx->prev];
6468
6469         (void)hdr;
6470         if (!size)
6471                 return -1;
6472         /* Set token type and update global help with details. */
6473         snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN"));
6474         if (token->help)
6475                 cmd_set_raw.help_str = token->help;
6476         else
6477                 cmd_set_raw.help_str = token->name;
6478         return 0;
6479 }
6480
6481 /** Token definition template (cmdline API). */
6482 static struct cmdline_token_hdr cmd_set_raw_token_hdr = {
6483         .ops = &(struct cmdline_token_ops){
6484                 .parse = cmd_flow_parse,
6485                 .complete_get_nb = cmd_flow_complete_get_nb,
6486                 .complete_get_elt = cmd_flow_complete_get_elt,
6487                 .get_help = cmd_set_raw_get_help,
6488         },
6489         .offset = 0,
6490 };
6491
6492 /** Populate the next dynamic token. */
6493 static void
6494 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr,
6495              cmdline_parse_token_hdr_t **hdr_inst)
6496 {
6497         struct context *ctx = &cmd_flow_context;
6498
6499         /* Always reinitialize context before requesting the first token. */
6500         if (!(hdr_inst - cmd_set_raw.tokens)) {
6501                 cmd_flow_context_init(ctx);
6502                 ctx->curr = START_SET;
6503         }
6504         /* Return NULL when no more tokens are expected. */
6505         if (!ctx->next_num && (ctx->curr != START_SET)) {
6506                 *hdr = NULL;
6507                 return;
6508         }
6509         /* Determine if command should end here. */
6510         if (ctx->eol && ctx->last && ctx->next_num) {
6511                 const enum index *list = ctx->next[ctx->next_num - 1];
6512                 int i;
6513
6514                 for (i = 0; list[i]; ++i) {
6515                         if (list[i] != END)
6516                                 continue;
6517                         *hdr = NULL;
6518                         return;
6519                 }
6520         }
6521         *hdr = &cmd_set_raw_token_hdr;
6522 }
6523
6524 /** Token generator and output processing callback (cmdline API). */
6525 static void
6526 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2)
6527 {
6528         if (cl == NULL)
6529                 cmd_set_raw_tok(arg0, arg2);
6530         else
6531                 cmd_set_raw_parsed(arg0);
6532 }
6533
6534 /** Global parser instance (cmdline API). */
6535 cmdline_parse_inst_t cmd_set_raw = {
6536         .f = cmd_set_raw_cb,
6537         .data = NULL, /**< Unused. */
6538         .help_str = NULL, /**< Updated by cmd_flow_get_help(). */
6539         .tokens = {
6540                 NULL,
6541         }, /**< Tokens are returned by cmd_flow_tok(). */
6542 };
6543
6544 /* *** display raw_encap/raw_decap buf */
6545 struct cmd_show_set_raw_result {
6546         cmdline_fixed_string_t cmd_show;
6547         cmdline_fixed_string_t cmd_what;
6548         cmdline_fixed_string_t cmd_all;
6549         uint16_t cmd_index;
6550 };
6551
6552 static void
6553 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data)
6554 {
6555         struct cmd_show_set_raw_result *res = parsed_result;
6556         uint16_t index = res->cmd_index;
6557         uint8_t all = 0;
6558         uint8_t *raw_data = NULL;
6559         size_t raw_size = 0;
6560         char title[16] = {0};
6561
6562         RTE_SET_USED(cl);
6563         RTE_SET_USED(data);
6564         if (!strcmp(res->cmd_all, "all")) {
6565                 all = 1;
6566                 index = 0;
6567         } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) {
6568                 printf("index should be 0-%u\n", RAW_ENCAP_CONFS_MAX_NUM - 1);
6569                 return;
6570         }
6571         do {
6572                 if (!strcmp(res->cmd_what, "raw_encap")) {
6573                         raw_data = (uint8_t *)&raw_encap_confs[index].data;
6574                         raw_size = raw_encap_confs[index].size;
6575                         snprintf(title, 16, "\nindex: %u", index);
6576                         rte_hexdump(stdout, title, raw_data, raw_size);
6577                 } else {
6578                         raw_data = (uint8_t *)&raw_decap_confs[index].data;
6579                         raw_size = raw_decap_confs[index].size;
6580                         snprintf(title, 16, "\nindex: %u", index);
6581                         rte_hexdump(stdout, title, raw_data, raw_size);
6582                 }
6583         } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM);
6584 }
6585
6586 cmdline_parse_token_string_t cmd_show_set_raw_cmd_show =
6587         TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
6588                         cmd_show, "show");
6589 cmdline_parse_token_string_t cmd_show_set_raw_cmd_what =
6590         TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
6591                         cmd_what, "raw_encap#raw_decap");
6592 cmdline_parse_token_num_t cmd_show_set_raw_cmd_index =
6593         TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result,
6594                         cmd_index, UINT16);
6595 cmdline_parse_token_string_t cmd_show_set_raw_cmd_all =
6596         TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
6597                         cmd_all, "all");
6598 cmdline_parse_inst_t cmd_show_set_raw = {
6599         .f = cmd_show_set_raw_parsed,
6600         .data = NULL,
6601         .help_str = "show <raw_encap|raw_decap> <index>",
6602         .tokens = {
6603                 (void *)&cmd_show_set_raw_cmd_show,
6604                 (void *)&cmd_show_set_raw_cmd_what,
6605                 (void *)&cmd_show_set_raw_cmd_index,
6606                 NULL,
6607         },
6608 };
6609 cmdline_parse_inst_t cmd_show_set_raw_all = {
6610         .f = cmd_show_set_raw_parsed,
6611         .data = NULL,
6612         .help_str = "show <raw_encap|raw_decap> all",
6613         .tokens = {
6614                 (void *)&cmd_show_set_raw_cmd_show,
6615                 (void *)&cmd_show_set_raw_cmd_what,
6616                 (void *)&cmd_show_set_raw_cmd_all,
6617                 NULL,
6618         },
6619 };