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