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