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