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