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