1aa32ea217cdfba48a2c2ca21f67df9d487c2623
[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
14 #include <rte_string_fns.h>
15 #include <rte_common.h>
16 #include <rte_ethdev.h>
17 #include <rte_byteorder.h>
18 #include <cmdline_parse.h>
19 #include <cmdline_parse_etheraddr.h>
20 #include <cmdline_parse_string.h>
21 #include <cmdline_parse_num.h>
22 #include <rte_flow.h>
23 #include <rte_hexdump.h>
24 #include <rte_vxlan.h>
25 #include <rte_gre.h>
26 #include <rte_mpls.h>
27 #include <rte_gtp.h>
28 #include <rte_geneve.h>
29
30 #include "testpmd.h"
31
32 /** Parser token indices. */
33 enum index {
34         /* Special tokens. */
35         ZERO = 0,
36         END,
37         START_SET,
38         END_SET,
39
40         /* Common tokens. */
41         COMMON_INTEGER,
42         COMMON_UNSIGNED,
43         COMMON_PREFIX,
44         COMMON_BOOLEAN,
45         COMMON_STRING,
46         COMMON_HEX,
47         COMMON_FILE_PATH,
48         COMMON_MAC_ADDR,
49         COMMON_IPV4_ADDR,
50         COMMON_IPV6_ADDR,
51         COMMON_RULE_ID,
52         COMMON_PORT_ID,
53         COMMON_GROUP_ID,
54         COMMON_PRIORITY_LEVEL,
55         COMMON_INDIRECT_ACTION_ID,
56         COMMON_POLICY_ID,
57         COMMON_FLEX_HANDLE,
58         COMMON_FLEX_TOKEN,
59         COMMON_PATTERN_TEMPLATE_ID,
60         COMMON_ACTIONS_TEMPLATE_ID,
61
62         /* TOP-level command. */
63         ADD,
64
65         /* Top-level command. */
66         SET,
67         /* Sub-leve commands. */
68         SET_RAW_ENCAP,
69         SET_RAW_DECAP,
70         SET_RAW_INDEX,
71         SET_SAMPLE_ACTIONS,
72         SET_SAMPLE_INDEX,
73
74         /* Top-level command. */
75         FLOW,
76         /* Sub-level commands. */
77         INFO,
78         CONFIGURE,
79         PATTERN_TEMPLATE,
80         ACTIONS_TEMPLATE,
81         INDIRECT_ACTION,
82         VALIDATE,
83         CREATE,
84         DESTROY,
85         FLUSH,
86         DUMP,
87         QUERY,
88         LIST,
89         AGED,
90         ISOLATE,
91         TUNNEL,
92         FLEX,
93
94         /* Flex arguments */
95         FLEX_ITEM_INIT,
96         FLEX_ITEM_CREATE,
97         FLEX_ITEM_DESTROY,
98
99         /* Pattern template arguments. */
100         PATTERN_TEMPLATE_CREATE,
101         PATTERN_TEMPLATE_DESTROY,
102         PATTERN_TEMPLATE_CREATE_ID,
103         PATTERN_TEMPLATE_DESTROY_ID,
104         PATTERN_TEMPLATE_RELAXED_MATCHING,
105         PATTERN_TEMPLATE_INGRESS,
106         PATTERN_TEMPLATE_EGRESS,
107         PATTERN_TEMPLATE_TRANSFER,
108         PATTERN_TEMPLATE_SPEC,
109
110         /* Actions template arguments. */
111         ACTIONS_TEMPLATE_CREATE,
112         ACTIONS_TEMPLATE_DESTROY,
113         ACTIONS_TEMPLATE_CREATE_ID,
114         ACTIONS_TEMPLATE_DESTROY_ID,
115         ACTIONS_TEMPLATE_INGRESS,
116         ACTIONS_TEMPLATE_EGRESS,
117         ACTIONS_TEMPLATE_TRANSFER,
118         ACTIONS_TEMPLATE_SPEC,
119         ACTIONS_TEMPLATE_MASK,
120
121         /* Tunnel arguments. */
122         TUNNEL_CREATE,
123         TUNNEL_CREATE_TYPE,
124         TUNNEL_LIST,
125         TUNNEL_DESTROY,
126         TUNNEL_DESTROY_ID,
127
128         /* Destroy arguments. */
129         DESTROY_RULE,
130
131         /* Query arguments. */
132         QUERY_ACTION,
133
134         /* List arguments. */
135         LIST_GROUP,
136
137         /* Destroy aged flow arguments. */
138         AGED_DESTROY,
139
140         /* Validate/create arguments. */
141         VC_GROUP,
142         VC_PRIORITY,
143         VC_INGRESS,
144         VC_EGRESS,
145         VC_TRANSFER,
146         VC_TUNNEL_SET,
147         VC_TUNNEL_MATCH,
148
149         /* Dump arguments */
150         DUMP_ALL,
151         DUMP_ONE,
152
153         /* Configure arguments */
154         CONFIG_QUEUES_NUMBER,
155         CONFIG_QUEUES_SIZE,
156         CONFIG_COUNTERS_NUMBER,
157         CONFIG_AGING_OBJECTS_NUMBER,
158         CONFIG_METERS_NUMBER,
159
160         /* Indirect action arguments */
161         INDIRECT_ACTION_CREATE,
162         INDIRECT_ACTION_UPDATE,
163         INDIRECT_ACTION_DESTROY,
164         INDIRECT_ACTION_QUERY,
165
166         /* Indirect action create arguments */
167         INDIRECT_ACTION_CREATE_ID,
168         INDIRECT_ACTION_INGRESS,
169         INDIRECT_ACTION_EGRESS,
170         INDIRECT_ACTION_TRANSFER,
171         INDIRECT_ACTION_SPEC,
172
173         /* Indirect action destroy arguments */
174         INDIRECT_ACTION_DESTROY_ID,
175
176         /* Validate/create pattern. */
177         ITEM_PATTERN,
178         ITEM_PARAM_IS,
179         ITEM_PARAM_SPEC,
180         ITEM_PARAM_LAST,
181         ITEM_PARAM_MASK,
182         ITEM_PARAM_PREFIX,
183         ITEM_NEXT,
184         ITEM_END,
185         ITEM_VOID,
186         ITEM_INVERT,
187         ITEM_ANY,
188         ITEM_ANY_NUM,
189         ITEM_PF,
190         ITEM_VF,
191         ITEM_VF_ID,
192         ITEM_PHY_PORT,
193         ITEM_PHY_PORT_INDEX,
194         ITEM_PORT_ID,
195         ITEM_PORT_ID_ID,
196         ITEM_MARK,
197         ITEM_MARK_ID,
198         ITEM_RAW,
199         ITEM_RAW_RELATIVE,
200         ITEM_RAW_SEARCH,
201         ITEM_RAW_OFFSET,
202         ITEM_RAW_LIMIT,
203         ITEM_RAW_PATTERN,
204         ITEM_RAW_PATTERN_HEX,
205         ITEM_ETH,
206         ITEM_ETH_DST,
207         ITEM_ETH_SRC,
208         ITEM_ETH_TYPE,
209         ITEM_ETH_HAS_VLAN,
210         ITEM_VLAN,
211         ITEM_VLAN_TCI,
212         ITEM_VLAN_PCP,
213         ITEM_VLAN_DEI,
214         ITEM_VLAN_VID,
215         ITEM_VLAN_INNER_TYPE,
216         ITEM_VLAN_HAS_MORE_VLAN,
217         ITEM_IPV4,
218         ITEM_IPV4_VER_IHL,
219         ITEM_IPV4_TOS,
220         ITEM_IPV4_ID,
221         ITEM_IPV4_FRAGMENT_OFFSET,
222         ITEM_IPV4_TTL,
223         ITEM_IPV4_PROTO,
224         ITEM_IPV4_SRC,
225         ITEM_IPV4_DST,
226         ITEM_IPV6,
227         ITEM_IPV6_TC,
228         ITEM_IPV6_FLOW,
229         ITEM_IPV6_PROTO,
230         ITEM_IPV6_HOP,
231         ITEM_IPV6_SRC,
232         ITEM_IPV6_DST,
233         ITEM_IPV6_HAS_FRAG_EXT,
234         ITEM_ICMP,
235         ITEM_ICMP_TYPE,
236         ITEM_ICMP_CODE,
237         ITEM_ICMP_IDENT,
238         ITEM_ICMP_SEQ,
239         ITEM_UDP,
240         ITEM_UDP_SRC,
241         ITEM_UDP_DST,
242         ITEM_TCP,
243         ITEM_TCP_SRC,
244         ITEM_TCP_DST,
245         ITEM_TCP_FLAGS,
246         ITEM_SCTP,
247         ITEM_SCTP_SRC,
248         ITEM_SCTP_DST,
249         ITEM_SCTP_TAG,
250         ITEM_SCTP_CKSUM,
251         ITEM_VXLAN,
252         ITEM_VXLAN_VNI,
253         ITEM_VXLAN_LAST_RSVD,
254         ITEM_E_TAG,
255         ITEM_E_TAG_GRP_ECID_B,
256         ITEM_NVGRE,
257         ITEM_NVGRE_TNI,
258         ITEM_MPLS,
259         ITEM_MPLS_LABEL,
260         ITEM_MPLS_TC,
261         ITEM_MPLS_S,
262         ITEM_GRE,
263         ITEM_GRE_PROTO,
264         ITEM_GRE_C_RSVD0_VER,
265         ITEM_GRE_C_BIT,
266         ITEM_GRE_K_BIT,
267         ITEM_GRE_S_BIT,
268         ITEM_FUZZY,
269         ITEM_FUZZY_THRESH,
270         ITEM_GTP,
271         ITEM_GTP_FLAGS,
272         ITEM_GTP_MSG_TYPE,
273         ITEM_GTP_TEID,
274         ITEM_GTPC,
275         ITEM_GTPU,
276         ITEM_GENEVE,
277         ITEM_GENEVE_VNI,
278         ITEM_GENEVE_PROTO,
279         ITEM_GENEVE_OPTLEN,
280         ITEM_VXLAN_GPE,
281         ITEM_VXLAN_GPE_VNI,
282         ITEM_ARP_ETH_IPV4,
283         ITEM_ARP_ETH_IPV4_SHA,
284         ITEM_ARP_ETH_IPV4_SPA,
285         ITEM_ARP_ETH_IPV4_THA,
286         ITEM_ARP_ETH_IPV4_TPA,
287         ITEM_IPV6_EXT,
288         ITEM_IPV6_EXT_NEXT_HDR,
289         ITEM_IPV6_FRAG_EXT,
290         ITEM_IPV6_FRAG_EXT_NEXT_HDR,
291         ITEM_IPV6_FRAG_EXT_FRAG_DATA,
292         ITEM_IPV6_FRAG_EXT_ID,
293         ITEM_ICMP6,
294         ITEM_ICMP6_TYPE,
295         ITEM_ICMP6_CODE,
296         ITEM_ICMP6_ND_NS,
297         ITEM_ICMP6_ND_NS_TARGET_ADDR,
298         ITEM_ICMP6_ND_NA,
299         ITEM_ICMP6_ND_NA_TARGET_ADDR,
300         ITEM_ICMP6_ND_OPT,
301         ITEM_ICMP6_ND_OPT_TYPE,
302         ITEM_ICMP6_ND_OPT_SLA_ETH,
303         ITEM_ICMP6_ND_OPT_SLA_ETH_SLA,
304         ITEM_ICMP6_ND_OPT_TLA_ETH,
305         ITEM_ICMP6_ND_OPT_TLA_ETH_TLA,
306         ITEM_META,
307         ITEM_META_DATA,
308         ITEM_GRE_KEY,
309         ITEM_GRE_KEY_VALUE,
310         ITEM_GRE_OPTION,
311         ITEM_GRE_OPTION_CHECKSUM,
312         ITEM_GRE_OPTION_KEY,
313         ITEM_GRE_OPTION_SEQUENCE,
314         ITEM_GTP_PSC,
315         ITEM_GTP_PSC_QFI,
316         ITEM_GTP_PSC_PDU_T,
317         ITEM_PPPOES,
318         ITEM_PPPOED,
319         ITEM_PPPOE_SEID,
320         ITEM_PPPOE_PROTO_ID,
321         ITEM_HIGIG2,
322         ITEM_HIGIG2_CLASSIFICATION,
323         ITEM_HIGIG2_VID,
324         ITEM_TAG,
325         ITEM_TAG_DATA,
326         ITEM_TAG_INDEX,
327         ITEM_L2TPV3OIP,
328         ITEM_L2TPV3OIP_SESSION_ID,
329         ITEM_ESP,
330         ITEM_ESP_SPI,
331         ITEM_AH,
332         ITEM_AH_SPI,
333         ITEM_PFCP,
334         ITEM_PFCP_S_FIELD,
335         ITEM_PFCP_SEID,
336         ITEM_ECPRI,
337         ITEM_ECPRI_COMMON,
338         ITEM_ECPRI_COMMON_TYPE,
339         ITEM_ECPRI_COMMON_TYPE_IQ_DATA,
340         ITEM_ECPRI_COMMON_TYPE_RTC_CTRL,
341         ITEM_ECPRI_COMMON_TYPE_DLY_MSR,
342         ITEM_ECPRI_MSG_IQ_DATA_PCID,
343         ITEM_ECPRI_MSG_RTC_CTRL_RTCID,
344         ITEM_ECPRI_MSG_DLY_MSR_MSRID,
345         ITEM_GENEVE_OPT,
346         ITEM_GENEVE_OPT_CLASS,
347         ITEM_GENEVE_OPT_TYPE,
348         ITEM_GENEVE_OPT_LENGTH,
349         ITEM_GENEVE_OPT_DATA,
350         ITEM_INTEGRITY,
351         ITEM_INTEGRITY_LEVEL,
352         ITEM_INTEGRITY_VALUE,
353         ITEM_CONNTRACK,
354         ITEM_POL_PORT,
355         ITEM_POL_METER,
356         ITEM_POL_POLICY,
357         ITEM_PORT_REPRESENTOR,
358         ITEM_PORT_REPRESENTOR_PORT_ID,
359         ITEM_REPRESENTED_PORT,
360         ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
361         ITEM_FLEX,
362         ITEM_FLEX_ITEM_HANDLE,
363         ITEM_FLEX_PATTERN_HANDLE,
364         ITEM_L2TPV2,
365         ITEM_L2TPV2_TYPE,
366         ITEM_L2TPV2_TYPE_DATA,
367         ITEM_L2TPV2_TYPE_DATA_L,
368         ITEM_L2TPV2_TYPE_DATA_S,
369         ITEM_L2TPV2_TYPE_DATA_O,
370         ITEM_L2TPV2_TYPE_DATA_L_S,
371         ITEM_L2TPV2_TYPE_CTRL,
372         ITEM_L2TPV2_MSG_DATA_TUNNEL_ID,
373         ITEM_L2TPV2_MSG_DATA_SESSION_ID,
374         ITEM_L2TPV2_MSG_DATA_L_LENGTH,
375         ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
376         ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
377         ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID,
378         ITEM_L2TPV2_MSG_DATA_S_SESSION_ID,
379         ITEM_L2TPV2_MSG_DATA_S_NS,
380         ITEM_L2TPV2_MSG_DATA_S_NR,
381         ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID,
382         ITEM_L2TPV2_MSG_DATA_O_SESSION_ID,
383         ITEM_L2TPV2_MSG_DATA_O_OFFSET,
384         ITEM_L2TPV2_MSG_DATA_L_S_LENGTH,
385         ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID,
386         ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID,
387         ITEM_L2TPV2_MSG_DATA_L_S_NS,
388         ITEM_L2TPV2_MSG_DATA_L_S_NR,
389         ITEM_L2TPV2_MSG_CTRL_LENGTH,
390         ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
391         ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
392         ITEM_L2TPV2_MSG_CTRL_NS,
393         ITEM_L2TPV2_MSG_CTRL_NR,
394         ITEM_PPP,
395         ITEM_PPP_ADDR,
396         ITEM_PPP_CTRL,
397         ITEM_PPP_PROTO_ID,
398
399         /* Validate/create actions. */
400         ACTIONS,
401         ACTION_NEXT,
402         ACTION_END,
403         ACTION_VOID,
404         ACTION_PASSTHRU,
405         ACTION_JUMP,
406         ACTION_JUMP_GROUP,
407         ACTION_MARK,
408         ACTION_MARK_ID,
409         ACTION_FLAG,
410         ACTION_QUEUE,
411         ACTION_QUEUE_INDEX,
412         ACTION_DROP,
413         ACTION_COUNT,
414         ACTION_COUNT_ID,
415         ACTION_RSS,
416         ACTION_RSS_FUNC,
417         ACTION_RSS_LEVEL,
418         ACTION_RSS_FUNC_DEFAULT,
419         ACTION_RSS_FUNC_TOEPLITZ,
420         ACTION_RSS_FUNC_SIMPLE_XOR,
421         ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ,
422         ACTION_RSS_TYPES,
423         ACTION_RSS_TYPE,
424         ACTION_RSS_KEY,
425         ACTION_RSS_KEY_LEN,
426         ACTION_RSS_QUEUES,
427         ACTION_RSS_QUEUE,
428         ACTION_PF,
429         ACTION_VF,
430         ACTION_VF_ORIGINAL,
431         ACTION_VF_ID,
432         ACTION_PHY_PORT,
433         ACTION_PHY_PORT_ORIGINAL,
434         ACTION_PHY_PORT_INDEX,
435         ACTION_PORT_ID,
436         ACTION_PORT_ID_ORIGINAL,
437         ACTION_PORT_ID_ID,
438         ACTION_METER,
439         ACTION_METER_COLOR,
440         ACTION_METER_COLOR_TYPE,
441         ACTION_METER_COLOR_GREEN,
442         ACTION_METER_COLOR_YELLOW,
443         ACTION_METER_COLOR_RED,
444         ACTION_METER_ID,
445         ACTION_OF_SET_MPLS_TTL,
446         ACTION_OF_SET_MPLS_TTL_MPLS_TTL,
447         ACTION_OF_DEC_MPLS_TTL,
448         ACTION_OF_SET_NW_TTL,
449         ACTION_OF_SET_NW_TTL_NW_TTL,
450         ACTION_OF_DEC_NW_TTL,
451         ACTION_OF_COPY_TTL_OUT,
452         ACTION_OF_COPY_TTL_IN,
453         ACTION_OF_POP_VLAN,
454         ACTION_OF_PUSH_VLAN,
455         ACTION_OF_PUSH_VLAN_ETHERTYPE,
456         ACTION_OF_SET_VLAN_VID,
457         ACTION_OF_SET_VLAN_VID_VLAN_VID,
458         ACTION_OF_SET_VLAN_PCP,
459         ACTION_OF_SET_VLAN_PCP_VLAN_PCP,
460         ACTION_OF_POP_MPLS,
461         ACTION_OF_POP_MPLS_ETHERTYPE,
462         ACTION_OF_PUSH_MPLS,
463         ACTION_OF_PUSH_MPLS_ETHERTYPE,
464         ACTION_VXLAN_ENCAP,
465         ACTION_VXLAN_DECAP,
466         ACTION_NVGRE_ENCAP,
467         ACTION_NVGRE_DECAP,
468         ACTION_L2_ENCAP,
469         ACTION_L2_DECAP,
470         ACTION_MPLSOGRE_ENCAP,
471         ACTION_MPLSOGRE_DECAP,
472         ACTION_MPLSOUDP_ENCAP,
473         ACTION_MPLSOUDP_DECAP,
474         ACTION_SET_IPV4_SRC,
475         ACTION_SET_IPV4_SRC_IPV4_SRC,
476         ACTION_SET_IPV4_DST,
477         ACTION_SET_IPV4_DST_IPV4_DST,
478         ACTION_SET_IPV6_SRC,
479         ACTION_SET_IPV6_SRC_IPV6_SRC,
480         ACTION_SET_IPV6_DST,
481         ACTION_SET_IPV6_DST_IPV6_DST,
482         ACTION_SET_TP_SRC,
483         ACTION_SET_TP_SRC_TP_SRC,
484         ACTION_SET_TP_DST,
485         ACTION_SET_TP_DST_TP_DST,
486         ACTION_MAC_SWAP,
487         ACTION_DEC_TTL,
488         ACTION_SET_TTL,
489         ACTION_SET_TTL_TTL,
490         ACTION_SET_MAC_SRC,
491         ACTION_SET_MAC_SRC_MAC_SRC,
492         ACTION_SET_MAC_DST,
493         ACTION_SET_MAC_DST_MAC_DST,
494         ACTION_INC_TCP_SEQ,
495         ACTION_INC_TCP_SEQ_VALUE,
496         ACTION_DEC_TCP_SEQ,
497         ACTION_DEC_TCP_SEQ_VALUE,
498         ACTION_INC_TCP_ACK,
499         ACTION_INC_TCP_ACK_VALUE,
500         ACTION_DEC_TCP_ACK,
501         ACTION_DEC_TCP_ACK_VALUE,
502         ACTION_RAW_ENCAP,
503         ACTION_RAW_DECAP,
504         ACTION_RAW_ENCAP_INDEX,
505         ACTION_RAW_ENCAP_INDEX_VALUE,
506         ACTION_RAW_DECAP_INDEX,
507         ACTION_RAW_DECAP_INDEX_VALUE,
508         ACTION_SET_TAG,
509         ACTION_SET_TAG_DATA,
510         ACTION_SET_TAG_INDEX,
511         ACTION_SET_TAG_MASK,
512         ACTION_SET_META,
513         ACTION_SET_META_DATA,
514         ACTION_SET_META_MASK,
515         ACTION_SET_IPV4_DSCP,
516         ACTION_SET_IPV4_DSCP_VALUE,
517         ACTION_SET_IPV6_DSCP,
518         ACTION_SET_IPV6_DSCP_VALUE,
519         ACTION_AGE,
520         ACTION_AGE_TIMEOUT,
521         ACTION_SAMPLE,
522         ACTION_SAMPLE_RATIO,
523         ACTION_SAMPLE_INDEX,
524         ACTION_SAMPLE_INDEX_VALUE,
525         ACTION_INDIRECT,
526         INDIRECT_ACTION_ID2PTR,
527         ACTION_MODIFY_FIELD,
528         ACTION_MODIFY_FIELD_OP,
529         ACTION_MODIFY_FIELD_OP_VALUE,
530         ACTION_MODIFY_FIELD_DST_TYPE,
531         ACTION_MODIFY_FIELD_DST_TYPE_VALUE,
532         ACTION_MODIFY_FIELD_DST_LEVEL,
533         ACTION_MODIFY_FIELD_DST_OFFSET,
534         ACTION_MODIFY_FIELD_SRC_TYPE,
535         ACTION_MODIFY_FIELD_SRC_TYPE_VALUE,
536         ACTION_MODIFY_FIELD_SRC_LEVEL,
537         ACTION_MODIFY_FIELD_SRC_OFFSET,
538         ACTION_MODIFY_FIELD_SRC_VALUE,
539         ACTION_MODIFY_FIELD_SRC_POINTER,
540         ACTION_MODIFY_FIELD_WIDTH,
541         ACTION_CONNTRACK,
542         ACTION_CONNTRACK_UPDATE,
543         ACTION_CONNTRACK_UPDATE_DIR,
544         ACTION_CONNTRACK_UPDATE_CTX,
545         ACTION_POL_G,
546         ACTION_POL_Y,
547         ACTION_POL_R,
548         ACTION_PORT_REPRESENTOR,
549         ACTION_PORT_REPRESENTOR_PORT_ID,
550         ACTION_REPRESENTED_PORT,
551         ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID,
552 };
553
554 /** Maximum size for pattern in struct rte_flow_item_raw. */
555 #define ITEM_RAW_PATTERN_SIZE 512
556
557 /** Maximum size for GENEVE option data pattern in bytes. */
558 #define ITEM_GENEVE_OPT_DATA_SIZE 124
559
560 /** Storage size for struct rte_flow_item_raw including pattern. */
561 #define ITEM_RAW_SIZE \
562         (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
563
564 /** Maximum size for external pattern in struct rte_flow_action_modify_data. */
565 #define ACTION_MODIFY_PATTERN_SIZE 32
566
567 /** Storage size for struct rte_flow_action_modify_field including pattern. */
568 #define ACTION_MODIFY_SIZE \
569         (sizeof(struct rte_flow_action_modify_field) + \
570         ACTION_MODIFY_PATTERN_SIZE)
571
572 /** Maximum number of queue indices in struct rte_flow_action_rss. */
573 #define ACTION_RSS_QUEUE_NUM 128
574
575 /** Storage for struct rte_flow_action_rss including external data. */
576 struct action_rss_data {
577         struct rte_flow_action_rss conf;
578         uint8_t key[RSS_HASH_KEY_LENGTH];
579         uint16_t queue[ACTION_RSS_QUEUE_NUM];
580 };
581
582 /** Maximum data size in struct rte_flow_action_raw_encap. */
583 #define ACTION_RAW_ENCAP_MAX_DATA 512
584 #define RAW_ENCAP_CONFS_MAX_NUM 8
585
586 /** Storage for struct rte_flow_action_raw_encap. */
587 struct raw_encap_conf {
588         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
589         uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA];
590         size_t size;
591 };
592
593 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM];
594
595 /** Storage for struct rte_flow_action_raw_encap including external data. */
596 struct action_raw_encap_data {
597         struct rte_flow_action_raw_encap conf;
598         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
599         uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA];
600         uint16_t idx;
601 };
602
603 /** Storage for struct rte_flow_action_raw_decap. */
604 struct raw_decap_conf {
605         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
606         size_t size;
607 };
608
609 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM];
610
611 /** Storage for struct rte_flow_action_raw_decap including external data. */
612 struct action_raw_decap_data {
613         struct rte_flow_action_raw_decap conf;
614         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
615         uint16_t idx;
616 };
617
618 struct vxlan_encap_conf vxlan_encap_conf = {
619         .select_ipv4 = 1,
620         .select_vlan = 0,
621         .select_tos_ttl = 0,
622         .vni = "\x00\x00\x00",
623         .udp_src = 0,
624         .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT),
625         .ipv4_src = RTE_IPV4(127, 0, 0, 1),
626         .ipv4_dst = RTE_IPV4(255, 255, 255, 255),
627         .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
628                 "\x00\x00\x00\x00\x00\x00\x00\x01",
629         .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
630                 "\x00\x00\x00\x00\x00\x00\x11\x11",
631         .vlan_tci = 0,
632         .ip_tos = 0,
633         .ip_ttl = 255,
634         .eth_src = "\x00\x00\x00\x00\x00\x00",
635         .eth_dst = "\xff\xff\xff\xff\xff\xff",
636 };
637
638 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */
639 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6
640
641 /** Storage for struct rte_flow_action_vxlan_encap including external data. */
642 struct action_vxlan_encap_data {
643         struct rte_flow_action_vxlan_encap conf;
644         struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM];
645         struct rte_flow_item_eth item_eth;
646         struct rte_flow_item_vlan item_vlan;
647         union {
648                 struct rte_flow_item_ipv4 item_ipv4;
649                 struct rte_flow_item_ipv6 item_ipv6;
650         };
651         struct rte_flow_item_udp item_udp;
652         struct rte_flow_item_vxlan item_vxlan;
653 };
654
655 struct nvgre_encap_conf nvgre_encap_conf = {
656         .select_ipv4 = 1,
657         .select_vlan = 0,
658         .tni = "\x00\x00\x00",
659         .ipv4_src = RTE_IPV4(127, 0, 0, 1),
660         .ipv4_dst = RTE_IPV4(255, 255, 255, 255),
661         .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
662                 "\x00\x00\x00\x00\x00\x00\x00\x01",
663         .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
664                 "\x00\x00\x00\x00\x00\x00\x11\x11",
665         .vlan_tci = 0,
666         .eth_src = "\x00\x00\x00\x00\x00\x00",
667         .eth_dst = "\xff\xff\xff\xff\xff\xff",
668 };
669
670 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */
671 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5
672
673 /** Storage for struct rte_flow_action_nvgre_encap including external data. */
674 struct action_nvgre_encap_data {
675         struct rte_flow_action_nvgre_encap conf;
676         struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM];
677         struct rte_flow_item_eth item_eth;
678         struct rte_flow_item_vlan item_vlan;
679         union {
680                 struct rte_flow_item_ipv4 item_ipv4;
681                 struct rte_flow_item_ipv6 item_ipv6;
682         };
683         struct rte_flow_item_nvgre item_nvgre;
684 };
685
686 struct l2_encap_conf l2_encap_conf;
687
688 struct l2_decap_conf l2_decap_conf;
689
690 struct mplsogre_encap_conf mplsogre_encap_conf;
691
692 struct mplsogre_decap_conf mplsogre_decap_conf;
693
694 struct mplsoudp_encap_conf mplsoudp_encap_conf;
695
696 struct mplsoudp_decap_conf mplsoudp_decap_conf;
697
698 struct rte_flow_action_conntrack conntrack_context;
699
700 #define ACTION_SAMPLE_ACTIONS_NUM 10
701 #define RAW_SAMPLE_CONFS_MAX_NUM 8
702 /** Storage for struct rte_flow_action_sample including external data. */
703 struct action_sample_data {
704         struct rte_flow_action_sample conf;
705         uint32_t idx;
706 };
707 /** Storage for struct rte_flow_action_sample. */
708 struct raw_sample_conf {
709         struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM];
710 };
711 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM];
712 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM];
713 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM];
714 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM];
715 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM];
716 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM];
717 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM];
718 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM];
719 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM];
720 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM];
721
722 static const char *const modify_field_ops[] = {
723         "set", "add", "sub", NULL
724 };
725
726 static const char *const modify_field_ids[] = {
727         "start", "mac_dst", "mac_src",
728         "vlan_type", "vlan_id", "mac_type",
729         "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst",
730         "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst",
731         "tcp_port_src", "tcp_port_dst",
732         "tcp_seq_num", "tcp_ack_num", "tcp_flags",
733         "udp_port_src", "udp_port_dst",
734         "vxlan_vni", "geneve_vni", "gtp_teid",
735         "tag", "mark", "meta", "pointer", "value", NULL
736 };
737
738 /** Maximum number of subsequent tokens and arguments on the stack. */
739 #define CTX_STACK_SIZE 16
740
741 /** Parser context. */
742 struct context {
743         /** Stack of subsequent token lists to process. */
744         const enum index *next[CTX_STACK_SIZE];
745         /** Arguments for stacked tokens. */
746         const void *args[CTX_STACK_SIZE];
747         enum index curr; /**< Current token index. */
748         enum index prev; /**< Index of the last token seen. */
749         int next_num; /**< Number of entries in next[]. */
750         int args_num; /**< Number of entries in args[]. */
751         uint32_t eol:1; /**< EOL has been detected. */
752         uint32_t last:1; /**< No more arguments. */
753         portid_t port; /**< Current port ID (for completions). */
754         uint32_t objdata; /**< Object-specific data. */
755         void *object; /**< Address of current object for relative offsets. */
756         void *objmask; /**< Object a full mask must be written to. */
757 };
758
759 /** Token argument. */
760 struct arg {
761         uint32_t hton:1; /**< Use network byte ordering. */
762         uint32_t sign:1; /**< Value is signed. */
763         uint32_t bounded:1; /**< Value is bounded. */
764         uintmax_t min; /**< Minimum value if bounded. */
765         uintmax_t max; /**< Maximum value if bounded. */
766         uint32_t offset; /**< Relative offset from ctx->object. */
767         uint32_t size; /**< Field size. */
768         const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */
769 };
770
771 /** Parser token definition. */
772 struct token {
773         /** Type displayed during completion (defaults to "TOKEN"). */
774         const char *type;
775         /** Help displayed during completion (defaults to token name). */
776         const char *help;
777         /** Private data used by parser functions. */
778         const void *priv;
779         /**
780          * Lists of subsequent tokens to push on the stack. Each call to the
781          * parser consumes the last entry of that stack.
782          */
783         const enum index *const *next;
784         /** Arguments stack for subsequent tokens that need them. */
785         const struct arg *const *args;
786         /**
787          * Token-processing callback, returns -1 in case of error, the
788          * length of the matched string otherwise. If NULL, attempts to
789          * match the token name.
790          *
791          * If buf is not NULL, the result should be stored in it according
792          * to context. An error is returned if not large enough.
793          */
794         int (*call)(struct context *ctx, const struct token *token,
795                     const char *str, unsigned int len,
796                     void *buf, unsigned int size);
797         /**
798          * Callback that provides possible values for this token, used for
799          * completion. Returns -1 in case of error, the number of possible
800          * values otherwise. If NULL, the token name is used.
801          *
802          * If buf is not NULL, entry index ent is written to buf and the
803          * full length of the entry is returned (same behavior as
804          * snprintf()).
805          */
806         int (*comp)(struct context *ctx, const struct token *token,
807                     unsigned int ent, char *buf, unsigned int size);
808         /** Mandatory token name, no default value. */
809         const char *name;
810 };
811
812 /** Static initializer for the next field. */
813 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, }
814
815 /** Static initializer for a NEXT() entry. */
816 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, }
817
818 /** Static initializer for the args field. */
819 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, }
820
821 /** Static initializer for ARGS() to target a field. */
822 #define ARGS_ENTRY(s, f) \
823         (&(const struct arg){ \
824                 .offset = offsetof(s, f), \
825                 .size = sizeof(((s *)0)->f), \
826         })
827
828 /** Static initializer for ARGS() to target a bit-field. */
829 #define ARGS_ENTRY_BF(s, f, b) \
830         (&(const struct arg){ \
831                 .size = sizeof(s), \
832                 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \
833         })
834
835 /** Static initializer for ARGS() to target a field with limits. */
836 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \
837         (&(const struct arg){ \
838                 .bounded = 1, \
839                 .min = (i), \
840                 .max = (a), \
841                 .offset = offsetof(s, f), \
842                 .size = sizeof(((s *)0)->f), \
843         })
844
845 /** Static initializer for ARGS() to target an arbitrary bit-mask. */
846 #define ARGS_ENTRY_MASK(s, f, m) \
847         (&(const struct arg){ \
848                 .offset = offsetof(s, f), \
849                 .size = sizeof(((s *)0)->f), \
850                 .mask = (const void *)(m), \
851         })
852
853 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */
854 #define ARGS_ENTRY_MASK_HTON(s, f, m) \
855         (&(const struct arg){ \
856                 .hton = 1, \
857                 .offset = offsetof(s, f), \
858                 .size = sizeof(((s *)0)->f), \
859                 .mask = (const void *)(m), \
860         })
861
862 /** Static initializer for ARGS() to target a pointer. */
863 #define ARGS_ENTRY_PTR(s, f) \
864         (&(const struct arg){ \
865                 .size = sizeof(*((s *)0)->f), \
866         })
867
868 /** Static initializer for ARGS() with arbitrary offset and size. */
869 #define ARGS_ENTRY_ARB(o, s) \
870         (&(const struct arg){ \
871                 .offset = (o), \
872                 .size = (s), \
873         })
874
875 /** Same as ARGS_ENTRY_ARB() with bounded values. */
876 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \
877         (&(const struct arg){ \
878                 .bounded = 1, \
879                 .min = (i), \
880                 .max = (a), \
881                 .offset = (o), \
882                 .size = (s), \
883         })
884
885 /** Same as ARGS_ENTRY() using network byte ordering. */
886 #define ARGS_ENTRY_HTON(s, f) \
887         (&(const struct arg){ \
888                 .hton = 1, \
889                 .offset = offsetof(s, f), \
890                 .size = sizeof(((s *)0)->f), \
891         })
892
893 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */
894 #define ARG_ENTRY_HTON(s) \
895         (&(const struct arg){ \
896                 .hton = 1, \
897                 .offset = 0, \
898                 .size = sizeof(s), \
899         })
900
901 /** Parser output buffer layout expected by cmd_flow_parsed(). */
902 struct buffer {
903         enum index command; /**< Flow command. */
904         portid_t port; /**< Affected port ID. */
905         union {
906                 struct {
907                         struct rte_flow_port_attr port_attr;
908                         uint32_t nb_queue;
909                         struct rte_flow_queue_attr queue_attr;
910                 } configure; /**< Configuration arguments. */
911                 struct {
912                         uint32_t *template_id;
913                         uint32_t template_id_n;
914                 } templ_destroy; /**< Template destroy arguments. */
915                 struct {
916                         uint32_t *action_id;
917                         uint32_t action_id_n;
918                 } ia_destroy; /**< Indirect action destroy arguments. */
919                 struct {
920                         uint32_t action_id;
921                 } ia; /* Indirect action query arguments */
922                 struct {
923                         uint32_t pat_templ_id;
924                         uint32_t act_templ_id;
925                         struct rte_flow_attr attr;
926                         struct tunnel_ops tunnel_ops;
927                         struct rte_flow_item *pattern;
928                         struct rte_flow_action *actions;
929                         struct rte_flow_action *masks;
930                         uint32_t pattern_n;
931                         uint32_t actions_n;
932                         uint8_t *data;
933                 } vc; /**< Validate/create arguments. */
934                 struct {
935                         uint32_t *rule;
936                         uint32_t rule_n;
937                 } destroy; /**< Destroy arguments. */
938                 struct {
939                         char file[128];
940                         bool mode;
941                         uint32_t rule;
942                 } dump; /**< Dump arguments. */
943                 struct {
944                         uint32_t rule;
945                         struct rte_flow_action action;
946                 } query; /**< Query arguments. */
947                 struct {
948                         uint32_t *group;
949                         uint32_t group_n;
950                 } list; /**< List arguments. */
951                 struct {
952                         int set;
953                 } isolate; /**< Isolated mode arguments. */
954                 struct {
955                         int destroy;
956                 } aged; /**< Aged arguments. */
957                 struct {
958                         uint32_t policy_id;
959                 } policy;/**< Policy arguments. */
960                 struct {
961                         uint16_t token;
962                         uintptr_t uintptr;
963                         char filename[128];
964                 } flex; /**< Flex arguments*/
965         } args; /**< Command arguments. */
966 };
967
968 /** Private data for pattern items. */
969 struct parse_item_priv {
970         enum rte_flow_item_type type; /**< Item type. */
971         uint32_t size; /**< Size of item specification structure. */
972 };
973
974 #define PRIV_ITEM(t, s) \
975         (&(const struct parse_item_priv){ \
976                 .type = RTE_FLOW_ITEM_TYPE_ ## t, \
977                 .size = s, \
978         })
979
980 /** Private data for actions. */
981 struct parse_action_priv {
982         enum rte_flow_action_type type; /**< Action type. */
983         uint32_t size; /**< Size of action configuration structure. */
984 };
985
986 #define PRIV_ACTION(t, s) \
987         (&(const struct parse_action_priv){ \
988                 .type = RTE_FLOW_ACTION_TYPE_ ## t, \
989                 .size = s, \
990         })
991
992 static const enum index next_flex_item[] = {
993         FLEX_ITEM_INIT,
994         FLEX_ITEM_CREATE,
995         FLEX_ITEM_DESTROY,
996         ZERO,
997 };
998
999 static const enum index next_config_attr[] = {
1000         CONFIG_QUEUES_NUMBER,
1001         CONFIG_QUEUES_SIZE,
1002         CONFIG_COUNTERS_NUMBER,
1003         CONFIG_AGING_OBJECTS_NUMBER,
1004         CONFIG_METERS_NUMBER,
1005         END,
1006         ZERO,
1007 };
1008
1009 static const enum index next_pt_subcmd[] = {
1010         PATTERN_TEMPLATE_CREATE,
1011         PATTERN_TEMPLATE_DESTROY,
1012         ZERO,
1013 };
1014
1015 static const enum index next_pt_attr[] = {
1016         PATTERN_TEMPLATE_CREATE_ID,
1017         PATTERN_TEMPLATE_RELAXED_MATCHING,
1018         PATTERN_TEMPLATE_INGRESS,
1019         PATTERN_TEMPLATE_EGRESS,
1020         PATTERN_TEMPLATE_TRANSFER,
1021         PATTERN_TEMPLATE_SPEC,
1022         ZERO,
1023 };
1024
1025 static const enum index next_pt_destroy_attr[] = {
1026         PATTERN_TEMPLATE_DESTROY_ID,
1027         END,
1028         ZERO,
1029 };
1030
1031 static const enum index next_at_subcmd[] = {
1032         ACTIONS_TEMPLATE_CREATE,
1033         ACTIONS_TEMPLATE_DESTROY,
1034         ZERO,
1035 };
1036
1037 static const enum index next_at_attr[] = {
1038         ACTIONS_TEMPLATE_CREATE_ID,
1039         ACTIONS_TEMPLATE_INGRESS,
1040         ACTIONS_TEMPLATE_EGRESS,
1041         ACTIONS_TEMPLATE_TRANSFER,
1042         ACTIONS_TEMPLATE_SPEC,
1043         ZERO,
1044 };
1045
1046 static const enum index next_at_destroy_attr[] = {
1047         ACTIONS_TEMPLATE_DESTROY_ID,
1048         END,
1049         ZERO,
1050 };
1051
1052 static const enum index next_ia_create_attr[] = {
1053         INDIRECT_ACTION_CREATE_ID,
1054         INDIRECT_ACTION_INGRESS,
1055         INDIRECT_ACTION_EGRESS,
1056         INDIRECT_ACTION_TRANSFER,
1057         INDIRECT_ACTION_SPEC,
1058         ZERO,
1059 };
1060
1061 static const enum index next_dump_subcmd[] = {
1062         DUMP_ALL,
1063         DUMP_ONE,
1064         ZERO,
1065 };
1066
1067 static const enum index next_ia_subcmd[] = {
1068         INDIRECT_ACTION_CREATE,
1069         INDIRECT_ACTION_UPDATE,
1070         INDIRECT_ACTION_DESTROY,
1071         INDIRECT_ACTION_QUERY,
1072         ZERO,
1073 };
1074
1075 static const enum index next_vc_attr[] = {
1076         VC_GROUP,
1077         VC_PRIORITY,
1078         VC_INGRESS,
1079         VC_EGRESS,
1080         VC_TRANSFER,
1081         VC_TUNNEL_SET,
1082         VC_TUNNEL_MATCH,
1083         ITEM_PATTERN,
1084         ZERO,
1085 };
1086
1087 static const enum index next_destroy_attr[] = {
1088         DESTROY_RULE,
1089         END,
1090         ZERO,
1091 };
1092
1093 static const enum index next_dump_attr[] = {
1094         COMMON_FILE_PATH,
1095         END,
1096         ZERO,
1097 };
1098
1099 static const enum index next_list_attr[] = {
1100         LIST_GROUP,
1101         END,
1102         ZERO,
1103 };
1104
1105 static const enum index next_aged_attr[] = {
1106         AGED_DESTROY,
1107         END,
1108         ZERO,
1109 };
1110
1111 static const enum index next_ia_destroy_attr[] = {
1112         INDIRECT_ACTION_DESTROY_ID,
1113         END,
1114         ZERO,
1115 };
1116
1117 static const enum index item_param[] = {
1118         ITEM_PARAM_IS,
1119         ITEM_PARAM_SPEC,
1120         ITEM_PARAM_LAST,
1121         ITEM_PARAM_MASK,
1122         ITEM_PARAM_PREFIX,
1123         ZERO,
1124 };
1125
1126 static const enum index next_item[] = {
1127         ITEM_END,
1128         ITEM_VOID,
1129         ITEM_INVERT,
1130         ITEM_ANY,
1131         ITEM_PF,
1132         ITEM_VF,
1133         ITEM_PHY_PORT,
1134         ITEM_PORT_ID,
1135         ITEM_MARK,
1136         ITEM_RAW,
1137         ITEM_ETH,
1138         ITEM_VLAN,
1139         ITEM_IPV4,
1140         ITEM_IPV6,
1141         ITEM_ICMP,
1142         ITEM_UDP,
1143         ITEM_TCP,
1144         ITEM_SCTP,
1145         ITEM_VXLAN,
1146         ITEM_E_TAG,
1147         ITEM_NVGRE,
1148         ITEM_MPLS,
1149         ITEM_GRE,
1150         ITEM_FUZZY,
1151         ITEM_GTP,
1152         ITEM_GTPC,
1153         ITEM_GTPU,
1154         ITEM_GENEVE,
1155         ITEM_VXLAN_GPE,
1156         ITEM_ARP_ETH_IPV4,
1157         ITEM_IPV6_EXT,
1158         ITEM_IPV6_FRAG_EXT,
1159         ITEM_ICMP6,
1160         ITEM_ICMP6_ND_NS,
1161         ITEM_ICMP6_ND_NA,
1162         ITEM_ICMP6_ND_OPT,
1163         ITEM_ICMP6_ND_OPT_SLA_ETH,
1164         ITEM_ICMP6_ND_OPT_TLA_ETH,
1165         ITEM_META,
1166         ITEM_GRE_KEY,
1167         ITEM_GRE_OPTION,
1168         ITEM_GTP_PSC,
1169         ITEM_PPPOES,
1170         ITEM_PPPOED,
1171         ITEM_PPPOE_PROTO_ID,
1172         ITEM_HIGIG2,
1173         ITEM_TAG,
1174         ITEM_L2TPV3OIP,
1175         ITEM_ESP,
1176         ITEM_AH,
1177         ITEM_PFCP,
1178         ITEM_ECPRI,
1179         ITEM_GENEVE_OPT,
1180         ITEM_INTEGRITY,
1181         ITEM_CONNTRACK,
1182         ITEM_PORT_REPRESENTOR,
1183         ITEM_REPRESENTED_PORT,
1184         ITEM_FLEX,
1185         ITEM_L2TPV2,
1186         ITEM_PPP,
1187         END_SET,
1188         ZERO,
1189 };
1190
1191 static const enum index item_fuzzy[] = {
1192         ITEM_FUZZY_THRESH,
1193         ITEM_NEXT,
1194         ZERO,
1195 };
1196
1197 static const enum index item_any[] = {
1198         ITEM_ANY_NUM,
1199         ITEM_NEXT,
1200         ZERO,
1201 };
1202
1203 static const enum index item_vf[] = {
1204         ITEM_VF_ID,
1205         ITEM_NEXT,
1206         ZERO,
1207 };
1208
1209 static const enum index item_phy_port[] = {
1210         ITEM_PHY_PORT_INDEX,
1211         ITEM_NEXT,
1212         ZERO,
1213 };
1214
1215 static const enum index item_port_id[] = {
1216         ITEM_PORT_ID_ID,
1217         ITEM_NEXT,
1218         ZERO,
1219 };
1220
1221 static const enum index item_mark[] = {
1222         ITEM_MARK_ID,
1223         ITEM_NEXT,
1224         ZERO,
1225 };
1226
1227 static const enum index item_raw[] = {
1228         ITEM_RAW_RELATIVE,
1229         ITEM_RAW_SEARCH,
1230         ITEM_RAW_OFFSET,
1231         ITEM_RAW_LIMIT,
1232         ITEM_RAW_PATTERN,
1233         ITEM_RAW_PATTERN_HEX,
1234         ITEM_NEXT,
1235         ZERO,
1236 };
1237
1238 static const enum index item_eth[] = {
1239         ITEM_ETH_DST,
1240         ITEM_ETH_SRC,
1241         ITEM_ETH_TYPE,
1242         ITEM_ETH_HAS_VLAN,
1243         ITEM_NEXT,
1244         ZERO,
1245 };
1246
1247 static const enum index item_vlan[] = {
1248         ITEM_VLAN_TCI,
1249         ITEM_VLAN_PCP,
1250         ITEM_VLAN_DEI,
1251         ITEM_VLAN_VID,
1252         ITEM_VLAN_INNER_TYPE,
1253         ITEM_VLAN_HAS_MORE_VLAN,
1254         ITEM_NEXT,
1255         ZERO,
1256 };
1257
1258 static const enum index item_ipv4[] = {
1259         ITEM_IPV4_VER_IHL,
1260         ITEM_IPV4_TOS,
1261         ITEM_IPV4_ID,
1262         ITEM_IPV4_FRAGMENT_OFFSET,
1263         ITEM_IPV4_TTL,
1264         ITEM_IPV4_PROTO,
1265         ITEM_IPV4_SRC,
1266         ITEM_IPV4_DST,
1267         ITEM_NEXT,
1268         ZERO,
1269 };
1270
1271 static const enum index item_ipv6[] = {
1272         ITEM_IPV6_TC,
1273         ITEM_IPV6_FLOW,
1274         ITEM_IPV6_PROTO,
1275         ITEM_IPV6_HOP,
1276         ITEM_IPV6_SRC,
1277         ITEM_IPV6_DST,
1278         ITEM_IPV6_HAS_FRAG_EXT,
1279         ITEM_NEXT,
1280         ZERO,
1281 };
1282
1283 static const enum index item_icmp[] = {
1284         ITEM_ICMP_TYPE,
1285         ITEM_ICMP_CODE,
1286         ITEM_ICMP_IDENT,
1287         ITEM_ICMP_SEQ,
1288         ITEM_NEXT,
1289         ZERO,
1290 };
1291
1292 static const enum index item_udp[] = {
1293         ITEM_UDP_SRC,
1294         ITEM_UDP_DST,
1295         ITEM_NEXT,
1296         ZERO,
1297 };
1298
1299 static const enum index item_tcp[] = {
1300         ITEM_TCP_SRC,
1301         ITEM_TCP_DST,
1302         ITEM_TCP_FLAGS,
1303         ITEM_NEXT,
1304         ZERO,
1305 };
1306
1307 static const enum index item_sctp[] = {
1308         ITEM_SCTP_SRC,
1309         ITEM_SCTP_DST,
1310         ITEM_SCTP_TAG,
1311         ITEM_SCTP_CKSUM,
1312         ITEM_NEXT,
1313         ZERO,
1314 };
1315
1316 static const enum index item_vxlan[] = {
1317         ITEM_VXLAN_VNI,
1318         ITEM_VXLAN_LAST_RSVD,
1319         ITEM_NEXT,
1320         ZERO,
1321 };
1322
1323 static const enum index item_e_tag[] = {
1324         ITEM_E_TAG_GRP_ECID_B,
1325         ITEM_NEXT,
1326         ZERO,
1327 };
1328
1329 static const enum index item_nvgre[] = {
1330         ITEM_NVGRE_TNI,
1331         ITEM_NEXT,
1332         ZERO,
1333 };
1334
1335 static const enum index item_mpls[] = {
1336         ITEM_MPLS_LABEL,
1337         ITEM_MPLS_TC,
1338         ITEM_MPLS_S,
1339         ITEM_NEXT,
1340         ZERO,
1341 };
1342
1343 static const enum index item_gre[] = {
1344         ITEM_GRE_PROTO,
1345         ITEM_GRE_C_RSVD0_VER,
1346         ITEM_GRE_C_BIT,
1347         ITEM_GRE_K_BIT,
1348         ITEM_GRE_S_BIT,
1349         ITEM_NEXT,
1350         ZERO,
1351 };
1352
1353 static const enum index item_gre_key[] = {
1354         ITEM_GRE_KEY_VALUE,
1355         ITEM_NEXT,
1356         ZERO,
1357 };
1358
1359 static const enum index item_gre_option[] = {
1360         ITEM_GRE_OPTION_CHECKSUM,
1361         ITEM_GRE_OPTION_KEY,
1362         ITEM_GRE_OPTION_SEQUENCE,
1363         ITEM_NEXT,
1364         ZERO,
1365 };
1366
1367 static const enum index item_gtp[] = {
1368         ITEM_GTP_FLAGS,
1369         ITEM_GTP_MSG_TYPE,
1370         ITEM_GTP_TEID,
1371         ITEM_NEXT,
1372         ZERO,
1373 };
1374
1375 static const enum index item_geneve[] = {
1376         ITEM_GENEVE_VNI,
1377         ITEM_GENEVE_PROTO,
1378         ITEM_GENEVE_OPTLEN,
1379         ITEM_NEXT,
1380         ZERO,
1381 };
1382
1383 static const enum index item_vxlan_gpe[] = {
1384         ITEM_VXLAN_GPE_VNI,
1385         ITEM_NEXT,
1386         ZERO,
1387 };
1388
1389 static const enum index item_arp_eth_ipv4[] = {
1390         ITEM_ARP_ETH_IPV4_SHA,
1391         ITEM_ARP_ETH_IPV4_SPA,
1392         ITEM_ARP_ETH_IPV4_THA,
1393         ITEM_ARP_ETH_IPV4_TPA,
1394         ITEM_NEXT,
1395         ZERO,
1396 };
1397
1398 static const enum index item_ipv6_ext[] = {
1399         ITEM_IPV6_EXT_NEXT_HDR,
1400         ITEM_NEXT,
1401         ZERO,
1402 };
1403
1404 static const enum index item_ipv6_frag_ext[] = {
1405         ITEM_IPV6_FRAG_EXT_NEXT_HDR,
1406         ITEM_IPV6_FRAG_EXT_FRAG_DATA,
1407         ITEM_IPV6_FRAG_EXT_ID,
1408         ITEM_NEXT,
1409         ZERO,
1410 };
1411
1412 static const enum index item_icmp6[] = {
1413         ITEM_ICMP6_TYPE,
1414         ITEM_ICMP6_CODE,
1415         ITEM_NEXT,
1416         ZERO,
1417 };
1418
1419 static const enum index item_icmp6_nd_ns[] = {
1420         ITEM_ICMP6_ND_NS_TARGET_ADDR,
1421         ITEM_NEXT,
1422         ZERO,
1423 };
1424
1425 static const enum index item_icmp6_nd_na[] = {
1426         ITEM_ICMP6_ND_NA_TARGET_ADDR,
1427         ITEM_NEXT,
1428         ZERO,
1429 };
1430
1431 static const enum index item_icmp6_nd_opt[] = {
1432         ITEM_ICMP6_ND_OPT_TYPE,
1433         ITEM_NEXT,
1434         ZERO,
1435 };
1436
1437 static const enum index item_icmp6_nd_opt_sla_eth[] = {
1438         ITEM_ICMP6_ND_OPT_SLA_ETH_SLA,
1439         ITEM_NEXT,
1440         ZERO,
1441 };
1442
1443 static const enum index item_icmp6_nd_opt_tla_eth[] = {
1444         ITEM_ICMP6_ND_OPT_TLA_ETH_TLA,
1445         ITEM_NEXT,
1446         ZERO,
1447 };
1448
1449 static const enum index item_meta[] = {
1450         ITEM_META_DATA,
1451         ITEM_NEXT,
1452         ZERO,
1453 };
1454
1455 static const enum index item_gtp_psc[] = {
1456         ITEM_GTP_PSC_QFI,
1457         ITEM_GTP_PSC_PDU_T,
1458         ITEM_NEXT,
1459         ZERO,
1460 };
1461
1462 static const enum index item_pppoed[] = {
1463         ITEM_PPPOE_SEID,
1464         ITEM_NEXT,
1465         ZERO,
1466 };
1467
1468 static const enum index item_pppoes[] = {
1469         ITEM_PPPOE_SEID,
1470         ITEM_NEXT,
1471         ZERO,
1472 };
1473
1474 static const enum index item_pppoe_proto_id[] = {
1475         ITEM_NEXT,
1476         ZERO,
1477 };
1478
1479 static const enum index item_higig2[] = {
1480         ITEM_HIGIG2_CLASSIFICATION,
1481         ITEM_HIGIG2_VID,
1482         ITEM_NEXT,
1483         ZERO,
1484 };
1485
1486 static const enum index item_esp[] = {
1487         ITEM_ESP_SPI,
1488         ITEM_NEXT,
1489         ZERO,
1490 };
1491
1492 static const enum index item_ah[] = {
1493         ITEM_AH_SPI,
1494         ITEM_NEXT,
1495         ZERO,
1496 };
1497
1498 static const enum index item_pfcp[] = {
1499         ITEM_PFCP_S_FIELD,
1500         ITEM_PFCP_SEID,
1501         ITEM_NEXT,
1502         ZERO,
1503 };
1504
1505 static const enum index next_set_raw[] = {
1506         SET_RAW_INDEX,
1507         ITEM_ETH,
1508         ZERO,
1509 };
1510
1511 static const enum index item_tag[] = {
1512         ITEM_TAG_DATA,
1513         ITEM_TAG_INDEX,
1514         ITEM_NEXT,
1515         ZERO,
1516 };
1517
1518 static const enum index item_l2tpv3oip[] = {
1519         ITEM_L2TPV3OIP_SESSION_ID,
1520         ITEM_NEXT,
1521         ZERO,
1522 };
1523
1524 static const enum index item_ecpri[] = {
1525         ITEM_ECPRI_COMMON,
1526         ITEM_NEXT,
1527         ZERO,
1528 };
1529
1530 static const enum index item_ecpri_common[] = {
1531         ITEM_ECPRI_COMMON_TYPE,
1532         ZERO,
1533 };
1534
1535 static const enum index item_ecpri_common_type[] = {
1536         ITEM_ECPRI_COMMON_TYPE_IQ_DATA,
1537         ITEM_ECPRI_COMMON_TYPE_RTC_CTRL,
1538         ITEM_ECPRI_COMMON_TYPE_DLY_MSR,
1539         ZERO,
1540 };
1541
1542 static const enum index item_geneve_opt[] = {
1543         ITEM_GENEVE_OPT_CLASS,
1544         ITEM_GENEVE_OPT_TYPE,
1545         ITEM_GENEVE_OPT_LENGTH,
1546         ITEM_GENEVE_OPT_DATA,
1547         ITEM_NEXT,
1548         ZERO,
1549 };
1550
1551 static const enum index item_integrity[] = {
1552         ITEM_INTEGRITY_LEVEL,
1553         ITEM_INTEGRITY_VALUE,
1554         ZERO,
1555 };
1556
1557 static const enum index item_integrity_lv[] = {
1558         ITEM_INTEGRITY_LEVEL,
1559         ITEM_INTEGRITY_VALUE,
1560         ITEM_NEXT,
1561         ZERO,
1562 };
1563
1564 static const enum index item_port_representor[] = {
1565         ITEM_PORT_REPRESENTOR_PORT_ID,
1566         ITEM_NEXT,
1567         ZERO,
1568 };
1569
1570 static const enum index item_represented_port[] = {
1571         ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
1572         ITEM_NEXT,
1573         ZERO,
1574 };
1575
1576 static const enum index item_flex[] = {
1577         ITEM_FLEX_PATTERN_HANDLE,
1578         ITEM_FLEX_ITEM_HANDLE,
1579         ITEM_NEXT,
1580         ZERO,
1581 };
1582
1583 static const enum index item_l2tpv2[] = {
1584         ITEM_L2TPV2_TYPE,
1585         ITEM_NEXT,
1586         ZERO,
1587 };
1588
1589 static const enum index item_l2tpv2_type[] = {
1590         ITEM_L2TPV2_TYPE_DATA,
1591         ITEM_L2TPV2_TYPE_DATA_L,
1592         ITEM_L2TPV2_TYPE_DATA_S,
1593         ITEM_L2TPV2_TYPE_DATA_O,
1594         ITEM_L2TPV2_TYPE_DATA_L_S,
1595         ITEM_L2TPV2_TYPE_CTRL,
1596         ZERO,
1597 };
1598
1599 static const enum index item_l2tpv2_type_data[] = {
1600         ITEM_L2TPV2_MSG_DATA_TUNNEL_ID,
1601         ITEM_L2TPV2_MSG_DATA_SESSION_ID,
1602         ITEM_NEXT,
1603         ZERO,
1604 };
1605
1606 static const enum index item_l2tpv2_type_data_l[] = {
1607         ITEM_L2TPV2_MSG_DATA_L_LENGTH,
1608         ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
1609         ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
1610         ITEM_NEXT,
1611         ZERO,
1612 };
1613
1614 static const enum index item_l2tpv2_type_data_s[] = {
1615         ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID,
1616         ITEM_L2TPV2_MSG_DATA_S_SESSION_ID,
1617         ITEM_L2TPV2_MSG_DATA_S_NS,
1618         ITEM_L2TPV2_MSG_DATA_S_NR,
1619         ITEM_NEXT,
1620         ZERO,
1621 };
1622
1623 static const enum index item_l2tpv2_type_data_o[] = {
1624         ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID,
1625         ITEM_L2TPV2_MSG_DATA_O_SESSION_ID,
1626         ITEM_L2TPV2_MSG_DATA_O_OFFSET,
1627         ITEM_NEXT,
1628         ZERO,
1629 };
1630
1631 static const enum index item_l2tpv2_type_data_l_s[] = {
1632         ITEM_L2TPV2_MSG_DATA_L_S_LENGTH,
1633         ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID,
1634         ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID,
1635         ITEM_L2TPV2_MSG_DATA_L_S_NS,
1636         ITEM_L2TPV2_MSG_DATA_L_S_NR,
1637         ITEM_NEXT,
1638         ZERO,
1639 };
1640
1641 static const enum index item_l2tpv2_type_ctrl[] = {
1642         ITEM_L2TPV2_MSG_CTRL_LENGTH,
1643         ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
1644         ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
1645         ITEM_L2TPV2_MSG_CTRL_NS,
1646         ITEM_L2TPV2_MSG_CTRL_NR,
1647         ITEM_NEXT,
1648         ZERO,
1649 };
1650
1651 static const enum index item_ppp[] = {
1652         ITEM_PPP_ADDR,
1653         ITEM_PPP_CTRL,
1654         ITEM_PPP_PROTO_ID,
1655         ITEM_NEXT,
1656         ZERO,
1657 };
1658
1659 static const enum index next_action[] = {
1660         ACTION_END,
1661         ACTION_VOID,
1662         ACTION_PASSTHRU,
1663         ACTION_JUMP,
1664         ACTION_MARK,
1665         ACTION_FLAG,
1666         ACTION_QUEUE,
1667         ACTION_DROP,
1668         ACTION_COUNT,
1669         ACTION_RSS,
1670         ACTION_PF,
1671         ACTION_VF,
1672         ACTION_PHY_PORT,
1673         ACTION_PORT_ID,
1674         ACTION_METER,
1675         ACTION_METER_COLOR,
1676         ACTION_OF_SET_MPLS_TTL,
1677         ACTION_OF_DEC_MPLS_TTL,
1678         ACTION_OF_SET_NW_TTL,
1679         ACTION_OF_DEC_NW_TTL,
1680         ACTION_OF_COPY_TTL_OUT,
1681         ACTION_OF_COPY_TTL_IN,
1682         ACTION_OF_POP_VLAN,
1683         ACTION_OF_PUSH_VLAN,
1684         ACTION_OF_SET_VLAN_VID,
1685         ACTION_OF_SET_VLAN_PCP,
1686         ACTION_OF_POP_MPLS,
1687         ACTION_OF_PUSH_MPLS,
1688         ACTION_VXLAN_ENCAP,
1689         ACTION_VXLAN_DECAP,
1690         ACTION_NVGRE_ENCAP,
1691         ACTION_NVGRE_DECAP,
1692         ACTION_L2_ENCAP,
1693         ACTION_L2_DECAP,
1694         ACTION_MPLSOGRE_ENCAP,
1695         ACTION_MPLSOGRE_DECAP,
1696         ACTION_MPLSOUDP_ENCAP,
1697         ACTION_MPLSOUDP_DECAP,
1698         ACTION_SET_IPV4_SRC,
1699         ACTION_SET_IPV4_DST,
1700         ACTION_SET_IPV6_SRC,
1701         ACTION_SET_IPV6_DST,
1702         ACTION_SET_TP_SRC,
1703         ACTION_SET_TP_DST,
1704         ACTION_MAC_SWAP,
1705         ACTION_DEC_TTL,
1706         ACTION_SET_TTL,
1707         ACTION_SET_MAC_SRC,
1708         ACTION_SET_MAC_DST,
1709         ACTION_INC_TCP_SEQ,
1710         ACTION_DEC_TCP_SEQ,
1711         ACTION_INC_TCP_ACK,
1712         ACTION_DEC_TCP_ACK,
1713         ACTION_RAW_ENCAP,
1714         ACTION_RAW_DECAP,
1715         ACTION_SET_TAG,
1716         ACTION_SET_META,
1717         ACTION_SET_IPV4_DSCP,
1718         ACTION_SET_IPV6_DSCP,
1719         ACTION_AGE,
1720         ACTION_SAMPLE,
1721         ACTION_INDIRECT,
1722         ACTION_MODIFY_FIELD,
1723         ACTION_CONNTRACK,
1724         ACTION_CONNTRACK_UPDATE,
1725         ACTION_PORT_REPRESENTOR,
1726         ACTION_REPRESENTED_PORT,
1727         ZERO,
1728 };
1729
1730 static const enum index action_mark[] = {
1731         ACTION_MARK_ID,
1732         ACTION_NEXT,
1733         ZERO,
1734 };
1735
1736 static const enum index action_queue[] = {
1737         ACTION_QUEUE_INDEX,
1738         ACTION_NEXT,
1739         ZERO,
1740 };
1741
1742 static const enum index action_count[] = {
1743         ACTION_COUNT_ID,
1744         ACTION_NEXT,
1745         ZERO,
1746 };
1747
1748 static const enum index action_rss[] = {
1749         ACTION_RSS_FUNC,
1750         ACTION_RSS_LEVEL,
1751         ACTION_RSS_TYPES,
1752         ACTION_RSS_KEY,
1753         ACTION_RSS_KEY_LEN,
1754         ACTION_RSS_QUEUES,
1755         ACTION_NEXT,
1756         ZERO,
1757 };
1758
1759 static const enum index action_vf[] = {
1760         ACTION_VF_ORIGINAL,
1761         ACTION_VF_ID,
1762         ACTION_NEXT,
1763         ZERO,
1764 };
1765
1766 static const enum index action_phy_port[] = {
1767         ACTION_PHY_PORT_ORIGINAL,
1768         ACTION_PHY_PORT_INDEX,
1769         ACTION_NEXT,
1770         ZERO,
1771 };
1772
1773 static const enum index action_port_id[] = {
1774         ACTION_PORT_ID_ORIGINAL,
1775         ACTION_PORT_ID_ID,
1776         ACTION_NEXT,
1777         ZERO,
1778 };
1779
1780 static const enum index action_meter[] = {
1781         ACTION_METER_ID,
1782         ACTION_NEXT,
1783         ZERO,
1784 };
1785
1786 static const enum index action_meter_color[] = {
1787         ACTION_METER_COLOR_TYPE,
1788         ACTION_NEXT,
1789         ZERO,
1790 };
1791
1792 static const enum index action_of_set_mpls_ttl[] = {
1793         ACTION_OF_SET_MPLS_TTL_MPLS_TTL,
1794         ACTION_NEXT,
1795         ZERO,
1796 };
1797
1798 static const enum index action_of_set_nw_ttl[] = {
1799         ACTION_OF_SET_NW_TTL_NW_TTL,
1800         ACTION_NEXT,
1801         ZERO,
1802 };
1803
1804 static const enum index action_of_push_vlan[] = {
1805         ACTION_OF_PUSH_VLAN_ETHERTYPE,
1806         ACTION_NEXT,
1807         ZERO,
1808 };
1809
1810 static const enum index action_of_set_vlan_vid[] = {
1811         ACTION_OF_SET_VLAN_VID_VLAN_VID,
1812         ACTION_NEXT,
1813         ZERO,
1814 };
1815
1816 static const enum index action_of_set_vlan_pcp[] = {
1817         ACTION_OF_SET_VLAN_PCP_VLAN_PCP,
1818         ACTION_NEXT,
1819         ZERO,
1820 };
1821
1822 static const enum index action_of_pop_mpls[] = {
1823         ACTION_OF_POP_MPLS_ETHERTYPE,
1824         ACTION_NEXT,
1825         ZERO,
1826 };
1827
1828 static const enum index action_of_push_mpls[] = {
1829         ACTION_OF_PUSH_MPLS_ETHERTYPE,
1830         ACTION_NEXT,
1831         ZERO,
1832 };
1833
1834 static const enum index action_set_ipv4_src[] = {
1835         ACTION_SET_IPV4_SRC_IPV4_SRC,
1836         ACTION_NEXT,
1837         ZERO,
1838 };
1839
1840 static const enum index action_set_mac_src[] = {
1841         ACTION_SET_MAC_SRC_MAC_SRC,
1842         ACTION_NEXT,
1843         ZERO,
1844 };
1845
1846 static const enum index action_set_ipv4_dst[] = {
1847         ACTION_SET_IPV4_DST_IPV4_DST,
1848         ACTION_NEXT,
1849         ZERO,
1850 };
1851
1852 static const enum index action_set_ipv6_src[] = {
1853         ACTION_SET_IPV6_SRC_IPV6_SRC,
1854         ACTION_NEXT,
1855         ZERO,
1856 };
1857
1858 static const enum index action_set_ipv6_dst[] = {
1859         ACTION_SET_IPV6_DST_IPV6_DST,
1860         ACTION_NEXT,
1861         ZERO,
1862 };
1863
1864 static const enum index action_set_tp_src[] = {
1865         ACTION_SET_TP_SRC_TP_SRC,
1866         ACTION_NEXT,
1867         ZERO,
1868 };
1869
1870 static const enum index action_set_tp_dst[] = {
1871         ACTION_SET_TP_DST_TP_DST,
1872         ACTION_NEXT,
1873         ZERO,
1874 };
1875
1876 static const enum index action_set_ttl[] = {
1877         ACTION_SET_TTL_TTL,
1878         ACTION_NEXT,
1879         ZERO,
1880 };
1881
1882 static const enum index action_jump[] = {
1883         ACTION_JUMP_GROUP,
1884         ACTION_NEXT,
1885         ZERO,
1886 };
1887
1888 static const enum index action_set_mac_dst[] = {
1889         ACTION_SET_MAC_DST_MAC_DST,
1890         ACTION_NEXT,
1891         ZERO,
1892 };
1893
1894 static const enum index action_inc_tcp_seq[] = {
1895         ACTION_INC_TCP_SEQ_VALUE,
1896         ACTION_NEXT,
1897         ZERO,
1898 };
1899
1900 static const enum index action_dec_tcp_seq[] = {
1901         ACTION_DEC_TCP_SEQ_VALUE,
1902         ACTION_NEXT,
1903         ZERO,
1904 };
1905
1906 static const enum index action_inc_tcp_ack[] = {
1907         ACTION_INC_TCP_ACK_VALUE,
1908         ACTION_NEXT,
1909         ZERO,
1910 };
1911
1912 static const enum index action_dec_tcp_ack[] = {
1913         ACTION_DEC_TCP_ACK_VALUE,
1914         ACTION_NEXT,
1915         ZERO,
1916 };
1917
1918 static const enum index action_raw_encap[] = {
1919         ACTION_RAW_ENCAP_INDEX,
1920         ACTION_NEXT,
1921         ZERO,
1922 };
1923
1924 static const enum index action_raw_decap[] = {
1925         ACTION_RAW_DECAP_INDEX,
1926         ACTION_NEXT,
1927         ZERO,
1928 };
1929
1930 static const enum index action_set_tag[] = {
1931         ACTION_SET_TAG_DATA,
1932         ACTION_SET_TAG_INDEX,
1933         ACTION_SET_TAG_MASK,
1934         ACTION_NEXT,
1935         ZERO,
1936 };
1937
1938 static const enum index action_set_meta[] = {
1939         ACTION_SET_META_DATA,
1940         ACTION_SET_META_MASK,
1941         ACTION_NEXT,
1942         ZERO,
1943 };
1944
1945 static const enum index action_set_ipv4_dscp[] = {
1946         ACTION_SET_IPV4_DSCP_VALUE,
1947         ACTION_NEXT,
1948         ZERO,
1949 };
1950
1951 static const enum index action_set_ipv6_dscp[] = {
1952         ACTION_SET_IPV6_DSCP_VALUE,
1953         ACTION_NEXT,
1954         ZERO,
1955 };
1956
1957 static const enum index action_age[] = {
1958         ACTION_AGE,
1959         ACTION_AGE_TIMEOUT,
1960         ACTION_NEXT,
1961         ZERO,
1962 };
1963
1964 static const enum index action_sample[] = {
1965         ACTION_SAMPLE,
1966         ACTION_SAMPLE_RATIO,
1967         ACTION_SAMPLE_INDEX,
1968         ACTION_NEXT,
1969         ZERO,
1970 };
1971
1972 static const enum index next_action_sample[] = {
1973         ACTION_QUEUE,
1974         ACTION_RSS,
1975         ACTION_MARK,
1976         ACTION_COUNT,
1977         ACTION_PORT_ID,
1978         ACTION_RAW_ENCAP,
1979         ACTION_VXLAN_ENCAP,
1980         ACTION_NVGRE_ENCAP,
1981         ACTION_NEXT,
1982         ZERO,
1983 };
1984
1985 static const enum index action_modify_field_dst[] = {
1986         ACTION_MODIFY_FIELD_DST_LEVEL,
1987         ACTION_MODIFY_FIELD_DST_OFFSET,
1988         ACTION_MODIFY_FIELD_SRC_TYPE,
1989         ZERO,
1990 };
1991
1992 static const enum index action_modify_field_src[] = {
1993         ACTION_MODIFY_FIELD_SRC_LEVEL,
1994         ACTION_MODIFY_FIELD_SRC_OFFSET,
1995         ACTION_MODIFY_FIELD_SRC_VALUE,
1996         ACTION_MODIFY_FIELD_SRC_POINTER,
1997         ACTION_MODIFY_FIELD_WIDTH,
1998         ZERO,
1999 };
2000
2001 static const enum index action_update_conntrack[] = {
2002         ACTION_CONNTRACK_UPDATE_DIR,
2003         ACTION_CONNTRACK_UPDATE_CTX,
2004         ACTION_NEXT,
2005         ZERO,
2006 };
2007
2008 static const enum index action_port_representor[] = {
2009         ACTION_PORT_REPRESENTOR_PORT_ID,
2010         ACTION_NEXT,
2011         ZERO,
2012 };
2013
2014 static const enum index action_represented_port[] = {
2015         ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID,
2016         ACTION_NEXT,
2017         ZERO,
2018 };
2019
2020 static int parse_set_raw_encap_decap(struct context *, const struct token *,
2021                                      const char *, unsigned int,
2022                                      void *, unsigned int);
2023 static int parse_set_sample_action(struct context *, const struct token *,
2024                                    const char *, unsigned int,
2025                                    void *, unsigned int);
2026 static int parse_set_init(struct context *, const struct token *,
2027                           const char *, unsigned int,
2028                           void *, unsigned int);
2029 static int
2030 parse_flex_handle(struct context *, const struct token *,
2031                   const char *, unsigned int, void *, unsigned int);
2032 static int parse_init(struct context *, const struct token *,
2033                       const char *, unsigned int,
2034                       void *, unsigned int);
2035 static int parse_vc(struct context *, const struct token *,
2036                     const char *, unsigned int,
2037                     void *, unsigned int);
2038 static int parse_vc_spec(struct context *, const struct token *,
2039                          const char *, unsigned int, void *, unsigned int);
2040 static int parse_vc_conf(struct context *, const struct token *,
2041                          const char *, unsigned int, void *, unsigned int);
2042 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
2043                                     const char *, unsigned int,
2044                                     void *, unsigned int);
2045 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *,
2046                                     const char *, unsigned int,
2047                                     void *, unsigned int);
2048 static int parse_vc_action_meter_color_type(struct context *,
2049                                         const struct token *,
2050                                         const char *, unsigned int, void *,
2051                                         unsigned int);
2052 static int parse_vc_action_rss(struct context *, const struct token *,
2053                                const char *, unsigned int, void *,
2054                                unsigned int);
2055 static int parse_vc_action_rss_func(struct context *, const struct token *,
2056                                     const char *, unsigned int, void *,
2057                                     unsigned int);
2058 static int parse_vc_action_rss_type(struct context *, const struct token *,
2059                                     const char *, unsigned int, void *,
2060                                     unsigned int);
2061 static int parse_vc_action_rss_queue(struct context *, const struct token *,
2062                                      const char *, unsigned int, void *,
2063                                      unsigned int);
2064 static int parse_vc_action_vxlan_encap(struct context *, const struct token *,
2065                                        const char *, unsigned int, void *,
2066                                        unsigned int);
2067 static int parse_vc_action_nvgre_encap(struct context *, const struct token *,
2068                                        const char *, unsigned int, void *,
2069                                        unsigned int);
2070 static int parse_vc_action_l2_encap(struct context *, const struct token *,
2071                                     const char *, unsigned int, void *,
2072                                     unsigned int);
2073 static int parse_vc_action_l2_decap(struct context *, const struct token *,
2074                                     const char *, unsigned int, void *,
2075                                     unsigned int);
2076 static int parse_vc_action_mplsogre_encap(struct context *,
2077                                           const struct token *, const char *,
2078                                           unsigned int, void *, unsigned int);
2079 static int parse_vc_action_mplsogre_decap(struct context *,
2080                                           const struct token *, const char *,
2081                                           unsigned int, void *, unsigned int);
2082 static int parse_vc_action_mplsoudp_encap(struct context *,
2083                                           const struct token *, const char *,
2084                                           unsigned int, void *, unsigned int);
2085 static int parse_vc_action_mplsoudp_decap(struct context *,
2086                                           const struct token *, const char *,
2087                                           unsigned int, void *, unsigned int);
2088 static int parse_vc_action_raw_encap(struct context *,
2089                                      const struct token *, const char *,
2090                                      unsigned int, void *, unsigned int);
2091 static int parse_vc_action_raw_decap(struct context *,
2092                                      const struct token *, const char *,
2093                                      unsigned int, void *, unsigned int);
2094 static int parse_vc_action_raw_encap_index(struct context *,
2095                                            const struct token *, const char *,
2096                                            unsigned int, void *, unsigned int);
2097 static int parse_vc_action_raw_decap_index(struct context *,
2098                                            const struct token *, const char *,
2099                                            unsigned int, void *, unsigned int);
2100 static int parse_vc_action_set_meta(struct context *ctx,
2101                                     const struct token *token, const char *str,
2102                                     unsigned int len, void *buf,
2103                                         unsigned int size);
2104 static int parse_vc_action_sample(struct context *ctx,
2105                                     const struct token *token, const char *str,
2106                                     unsigned int len, void *buf,
2107                                     unsigned int size);
2108 static int
2109 parse_vc_action_sample_index(struct context *ctx, const struct token *token,
2110                                 const char *str, unsigned int len, void *buf,
2111                                 unsigned int size);
2112 static int
2113 parse_vc_modify_field_op(struct context *ctx, const struct token *token,
2114                                 const char *str, unsigned int len, void *buf,
2115                                 unsigned int size);
2116 static int
2117 parse_vc_modify_field_id(struct context *ctx, const struct token *token,
2118                                 const char *str, unsigned int len, void *buf,
2119                                 unsigned int size);
2120 static int
2121 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token,
2122                          const char *str, unsigned int len, void *buf,
2123                          unsigned int size);
2124 static int parse_destroy(struct context *, const struct token *,
2125                          const char *, unsigned int,
2126                          void *, unsigned int);
2127 static int parse_flush(struct context *, const struct token *,
2128                        const char *, unsigned int,
2129                        void *, unsigned int);
2130 static int parse_dump(struct context *, const struct token *,
2131                       const char *, unsigned int,
2132                       void *, unsigned int);
2133 static int parse_query(struct context *, const struct token *,
2134                        const char *, unsigned int,
2135                        void *, unsigned int);
2136 static int parse_action(struct context *, const struct token *,
2137                         const char *, unsigned int,
2138                         void *, unsigned int);
2139 static int parse_list(struct context *, const struct token *,
2140                       const char *, unsigned int,
2141                       void *, unsigned int);
2142 static int parse_aged(struct context *, const struct token *,
2143                       const char *, unsigned int,
2144                       void *, unsigned int);
2145 static int parse_isolate(struct context *, const struct token *,
2146                          const char *, unsigned int,
2147                          void *, unsigned int);
2148 static int parse_configure(struct context *, const struct token *,
2149                            const char *, unsigned int,
2150                            void *, unsigned int);
2151 static int parse_template(struct context *, const struct token *,
2152                           const char *, unsigned int,
2153                           void *, unsigned int);
2154 static int parse_template_destroy(struct context *, const struct token *,
2155                                   const char *, unsigned int,
2156                                   void *, unsigned int);
2157 static int parse_tunnel(struct context *, const struct token *,
2158                         const char *, unsigned int,
2159                         void *, unsigned int);
2160 static int parse_flex(struct context *, const struct token *,
2161                       const char *, unsigned int, void *, unsigned int);
2162 static int parse_int(struct context *, const struct token *,
2163                      const char *, unsigned int,
2164                      void *, unsigned int);
2165 static int parse_prefix(struct context *, const struct token *,
2166                         const char *, unsigned int,
2167                         void *, unsigned int);
2168 static int parse_boolean(struct context *, const struct token *,
2169                          const char *, unsigned int,
2170                          void *, unsigned int);
2171 static int parse_string(struct context *, const struct token *,
2172                         const char *, unsigned int,
2173                         void *, unsigned int);
2174 static int parse_hex(struct context *ctx, const struct token *token,
2175                         const char *str, unsigned int len,
2176                         void *buf, unsigned int size);
2177 static int parse_string0(struct context *, const struct token *,
2178                         const char *, unsigned int,
2179                         void *, unsigned int);
2180 static int parse_mac_addr(struct context *, const struct token *,
2181                           const char *, unsigned int,
2182                           void *, unsigned int);
2183 static int parse_ipv4_addr(struct context *, const struct token *,
2184                            const char *, unsigned int,
2185                            void *, unsigned int);
2186 static int parse_ipv6_addr(struct context *, const struct token *,
2187                            const char *, unsigned int,
2188                            void *, unsigned int);
2189 static int parse_port(struct context *, const struct token *,
2190                       const char *, unsigned int,
2191                       void *, unsigned int);
2192 static int parse_ia(struct context *, const struct token *,
2193                     const char *, unsigned int,
2194                     void *, unsigned int);
2195 static int parse_ia_destroy(struct context *ctx, const struct token *token,
2196                             const char *str, unsigned int len,
2197                             void *buf, unsigned int size);
2198 static int parse_ia_id2ptr(struct context *ctx, const struct token *token,
2199                            const char *str, unsigned int len, void *buf,
2200                            unsigned int size);
2201 static int parse_mp(struct context *, const struct token *,
2202                     const char *, unsigned int,
2203                     void *, unsigned int);
2204 static int comp_none(struct context *, const struct token *,
2205                      unsigned int, char *, unsigned int);
2206 static int comp_boolean(struct context *, const struct token *,
2207                         unsigned int, char *, unsigned int);
2208 static int comp_action(struct context *, const struct token *,
2209                        unsigned int, char *, unsigned int);
2210 static int comp_port(struct context *, const struct token *,
2211                      unsigned int, char *, unsigned int);
2212 static int comp_rule_id(struct context *, const struct token *,
2213                         unsigned int, char *, unsigned int);
2214 static int comp_vc_action_rss_type(struct context *, const struct token *,
2215                                    unsigned int, char *, unsigned int);
2216 static int comp_vc_action_rss_queue(struct context *, const struct token *,
2217                                     unsigned int, char *, unsigned int);
2218 static int comp_set_raw_index(struct context *, const struct token *,
2219                               unsigned int, char *, unsigned int);
2220 static int comp_set_sample_index(struct context *, const struct token *,
2221                               unsigned int, char *, unsigned int);
2222 static int comp_set_modify_field_op(struct context *, const struct token *,
2223                               unsigned int, char *, unsigned int);
2224 static int comp_set_modify_field_id(struct context *, const struct token *,
2225                               unsigned int, char *, unsigned int);
2226 static int comp_pattern_template_id(struct context *, const struct token *,
2227                                     unsigned int, char *, unsigned int);
2228 static int comp_actions_template_id(struct context *, const struct token *,
2229                                     unsigned int, char *, unsigned int);
2230
2231 /** Token definitions. */
2232 static const struct token token_list[] = {
2233         /* Special tokens. */
2234         [ZERO] = {
2235                 .name = "ZERO",
2236                 .help = "null entry, abused as the entry point",
2237                 .next = NEXT(NEXT_ENTRY(FLOW, ADD)),
2238         },
2239         [END] = {
2240                 .name = "",
2241                 .type = "RETURN",
2242                 .help = "command may end here",
2243         },
2244         [START_SET] = {
2245                 .name = "START_SET",
2246                 .help = "null entry, abused as the entry point for set",
2247                 .next = NEXT(NEXT_ENTRY(SET)),
2248         },
2249         [END_SET] = {
2250                 .name = "end_set",
2251                 .type = "RETURN",
2252                 .help = "set command may end here",
2253         },
2254         /* Common tokens. */
2255         [COMMON_INTEGER] = {
2256                 .name = "{int}",
2257                 .type = "INTEGER",
2258                 .help = "integer value",
2259                 .call = parse_int,
2260                 .comp = comp_none,
2261         },
2262         [COMMON_UNSIGNED] = {
2263                 .name = "{unsigned}",
2264                 .type = "UNSIGNED",
2265                 .help = "unsigned integer value",
2266                 .call = parse_int,
2267                 .comp = comp_none,
2268         },
2269         [COMMON_PREFIX] = {
2270                 .name = "{prefix}",
2271                 .type = "PREFIX",
2272                 .help = "prefix length for bit-mask",
2273                 .call = parse_prefix,
2274                 .comp = comp_none,
2275         },
2276         [COMMON_BOOLEAN] = {
2277                 .name = "{boolean}",
2278                 .type = "BOOLEAN",
2279                 .help = "any boolean value",
2280                 .call = parse_boolean,
2281                 .comp = comp_boolean,
2282         },
2283         [COMMON_STRING] = {
2284                 .name = "{string}",
2285                 .type = "STRING",
2286                 .help = "fixed string",
2287                 .call = parse_string,
2288                 .comp = comp_none,
2289         },
2290         [COMMON_HEX] = {
2291                 .name = "{hex}",
2292                 .type = "HEX",
2293                 .help = "fixed string",
2294                 .call = parse_hex,
2295         },
2296         [COMMON_FILE_PATH] = {
2297                 .name = "{file path}",
2298                 .type = "STRING",
2299                 .help = "file path",
2300                 .call = parse_string0,
2301                 .comp = comp_none,
2302         },
2303         [COMMON_MAC_ADDR] = {
2304                 .name = "{MAC address}",
2305                 .type = "MAC-48",
2306                 .help = "standard MAC address notation",
2307                 .call = parse_mac_addr,
2308                 .comp = comp_none,
2309         },
2310         [COMMON_IPV4_ADDR] = {
2311                 .name = "{IPv4 address}",
2312                 .type = "IPV4 ADDRESS",
2313                 .help = "standard IPv4 address notation",
2314                 .call = parse_ipv4_addr,
2315                 .comp = comp_none,
2316         },
2317         [COMMON_IPV6_ADDR] = {
2318                 .name = "{IPv6 address}",
2319                 .type = "IPV6 ADDRESS",
2320                 .help = "standard IPv6 address notation",
2321                 .call = parse_ipv6_addr,
2322                 .comp = comp_none,
2323         },
2324         [COMMON_RULE_ID] = {
2325                 .name = "{rule id}",
2326                 .type = "RULE ID",
2327                 .help = "rule identifier",
2328                 .call = parse_int,
2329                 .comp = comp_rule_id,
2330         },
2331         [COMMON_PORT_ID] = {
2332                 .name = "{port_id}",
2333                 .type = "PORT ID",
2334                 .help = "port identifier",
2335                 .call = parse_port,
2336                 .comp = comp_port,
2337         },
2338         [COMMON_GROUP_ID] = {
2339                 .name = "{group_id}",
2340                 .type = "GROUP ID",
2341                 .help = "group identifier",
2342                 .call = parse_int,
2343                 .comp = comp_none,
2344         },
2345         [COMMON_PRIORITY_LEVEL] = {
2346                 .name = "{level}",
2347                 .type = "PRIORITY",
2348                 .help = "priority level",
2349                 .call = parse_int,
2350                 .comp = comp_none,
2351         },
2352         [COMMON_INDIRECT_ACTION_ID] = {
2353                 .name = "{indirect_action_id}",
2354                 .type = "INDIRECT_ACTION_ID",
2355                 .help = "indirect action id",
2356                 .call = parse_int,
2357                 .comp = comp_none,
2358         },
2359         [COMMON_POLICY_ID] = {
2360                 .name = "{policy_id}",
2361                 .type = "POLICY_ID",
2362                 .help = "policy id",
2363                 .call = parse_int,
2364                 .comp = comp_none,
2365         },
2366         [COMMON_FLEX_TOKEN] = {
2367                 .name = "{flex token}",
2368                 .type = "flex token",
2369                 .help = "flex token",
2370                 .call = parse_int,
2371                 .comp = comp_none,
2372         },
2373         [COMMON_FLEX_HANDLE] = {
2374                 .name = "{flex handle}",
2375                 .type = "FLEX HANDLE",
2376                 .help = "fill flex item data",
2377                 .call = parse_flex_handle,
2378                 .comp = comp_none,
2379         },
2380         [COMMON_PATTERN_TEMPLATE_ID] = {
2381                 .name = "{pattern_template_id}",
2382                 .type = "PATTERN_TEMPLATE_ID",
2383                 .help = "pattern template id",
2384                 .call = parse_int,
2385                 .comp = comp_pattern_template_id,
2386         },
2387         [COMMON_ACTIONS_TEMPLATE_ID] = {
2388                 .name = "{actions_template_id}",
2389                 .type = "ACTIONS_TEMPLATE_ID",
2390                 .help = "actions template id",
2391                 .call = parse_int,
2392                 .comp = comp_actions_template_id,
2393         },
2394         /* Top-level command. */
2395         [FLOW] = {
2396                 .name = "flow",
2397                 .type = "{command} {port_id} [{arg} [...]]",
2398                 .help = "manage ingress/egress flow rules",
2399                 .next = NEXT(NEXT_ENTRY
2400                              (INFO,
2401                               CONFIGURE,
2402                               PATTERN_TEMPLATE,
2403                               ACTIONS_TEMPLATE,
2404                               INDIRECT_ACTION,
2405                               VALIDATE,
2406                               CREATE,
2407                               DESTROY,
2408                               FLUSH,
2409                               DUMP,
2410                               LIST,
2411                               AGED,
2412                               QUERY,
2413                               ISOLATE,
2414                               TUNNEL,
2415                               FLEX)),
2416                 .call = parse_init,
2417         },
2418         /* Top-level command. */
2419         [INFO] = {
2420                 .name = "info",
2421                 .help = "get information about flow engine",
2422                 .next = NEXT(NEXT_ENTRY(END),
2423                              NEXT_ENTRY(COMMON_PORT_ID)),
2424                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2425                 .call = parse_configure,
2426         },
2427         /* Top-level command. */
2428         [CONFIGURE] = {
2429                 .name = "configure",
2430                 .help = "configure flow engine",
2431                 .next = NEXT(next_config_attr,
2432                              NEXT_ENTRY(COMMON_PORT_ID)),
2433                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2434                 .call = parse_configure,
2435         },
2436         /* Configure arguments. */
2437         [CONFIG_QUEUES_NUMBER] = {
2438                 .name = "queues_number",
2439                 .help = "number of queues",
2440                 .next = NEXT(next_config_attr,
2441                              NEXT_ENTRY(COMMON_UNSIGNED)),
2442                 .args = ARGS(ARGS_ENTRY(struct buffer,
2443                                         args.configure.nb_queue)),
2444         },
2445         [CONFIG_QUEUES_SIZE] = {
2446                 .name = "queues_size",
2447                 .help = "number of elements in queues",
2448                 .next = NEXT(next_config_attr,
2449                              NEXT_ENTRY(COMMON_UNSIGNED)),
2450                 .args = ARGS(ARGS_ENTRY(struct buffer,
2451                                         args.configure.queue_attr.size)),
2452         },
2453         [CONFIG_COUNTERS_NUMBER] = {
2454                 .name = "counters_number",
2455                 .help = "number of counters",
2456                 .next = NEXT(next_config_attr,
2457                              NEXT_ENTRY(COMMON_UNSIGNED)),
2458                 .args = ARGS(ARGS_ENTRY(struct buffer,
2459                                         args.configure.port_attr.nb_counters)),
2460         },
2461         [CONFIG_AGING_OBJECTS_NUMBER] = {
2462                 .name = "aging_counters_number",
2463                 .help = "number of aging objects",
2464                 .next = NEXT(next_config_attr,
2465                              NEXT_ENTRY(COMMON_UNSIGNED)),
2466                 .args = ARGS(ARGS_ENTRY(struct buffer,
2467                                         args.configure.port_attr.nb_aging_objects)),
2468         },
2469         [CONFIG_METERS_NUMBER] = {
2470                 .name = "meters_number",
2471                 .help = "number of meters",
2472                 .next = NEXT(next_config_attr,
2473                              NEXT_ENTRY(COMMON_UNSIGNED)),
2474                 .args = ARGS(ARGS_ENTRY(struct buffer,
2475                                         args.configure.port_attr.nb_meters)),
2476         },
2477         /* Top-level command. */
2478         [PATTERN_TEMPLATE] = {
2479                 .name = "pattern_template",
2480                 .type = "{command} {port_id} [{arg} [...]]",
2481                 .help = "manage pattern templates",
2482                 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)),
2483                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2484                 .call = parse_template,
2485         },
2486         /* Sub-level commands. */
2487         [PATTERN_TEMPLATE_CREATE] = {
2488                 .name = "create",
2489                 .help = "create pattern template",
2490                 .next = NEXT(next_pt_attr),
2491                 .call = parse_template,
2492         },
2493         [PATTERN_TEMPLATE_DESTROY] = {
2494                 .name = "destroy",
2495                 .help = "destroy pattern template",
2496                 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)),
2497                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2498                 .call = parse_template_destroy,
2499         },
2500         /* Pattern template arguments. */
2501         [PATTERN_TEMPLATE_CREATE_ID] = {
2502                 .name = "pattern_template_id",
2503                 .help = "specify a pattern template id to create",
2504                 .next = NEXT(next_pt_attr,
2505                              NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)),
2506                 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)),
2507         },
2508         [PATTERN_TEMPLATE_DESTROY_ID] = {
2509                 .name = "pattern_template",
2510                 .help = "specify a pattern template id to destroy",
2511                 .next = NEXT(next_pt_destroy_attr,
2512                              NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)),
2513                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer,
2514                                             args.templ_destroy.template_id)),
2515                 .call = parse_template_destroy,
2516         },
2517         [PATTERN_TEMPLATE_RELAXED_MATCHING] = {
2518                 .name = "relaxed",
2519                 .help = "is matching relaxed",
2520                 .next = NEXT(next_pt_attr,
2521                              NEXT_ENTRY(COMMON_BOOLEAN)),
2522                 .args = ARGS(ARGS_ENTRY_BF(struct buffer,
2523                              args.vc.attr.reserved, 1)),
2524         },
2525         [PATTERN_TEMPLATE_INGRESS] = {
2526                 .name = "ingress",
2527                 .help = "attribute pattern to ingress",
2528                 .next = NEXT(next_pt_attr),
2529                 .call = parse_template,
2530         },
2531         [PATTERN_TEMPLATE_EGRESS] = {
2532                 .name = "egress",
2533                 .help = "attribute pattern to egress",
2534                 .next = NEXT(next_pt_attr),
2535                 .call = parse_template,
2536         },
2537         [PATTERN_TEMPLATE_TRANSFER] = {
2538                 .name = "transfer",
2539                 .help = "attribute pattern to transfer",
2540                 .next = NEXT(next_pt_attr),
2541                 .call = parse_template,
2542         },
2543         [PATTERN_TEMPLATE_SPEC] = {
2544                 .name = "template",
2545                 .help = "specify item to create pattern template",
2546                 .next = NEXT(next_item),
2547         },
2548         /* Top-level command. */
2549         [ACTIONS_TEMPLATE] = {
2550                 .name = "actions_template",
2551                 .type = "{command} {port_id} [{arg} [...]]",
2552                 .help = "manage actions templates",
2553                 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)),
2554                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2555                 .call = parse_template,
2556         },
2557         /* Sub-level commands. */
2558         [ACTIONS_TEMPLATE_CREATE] = {
2559                 .name = "create",
2560                 .help = "create actions template",
2561                 .next = NEXT(next_at_attr),
2562                 .call = parse_template,
2563         },
2564         [ACTIONS_TEMPLATE_DESTROY] = {
2565                 .name = "destroy",
2566                 .help = "destroy actions template",
2567                 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)),
2568                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2569                 .call = parse_template_destroy,
2570         },
2571         /* Actions template arguments. */
2572         [ACTIONS_TEMPLATE_CREATE_ID] = {
2573                 .name = "actions_template_id",
2574                 .help = "specify an actions template id to create",
2575                 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK),
2576                              NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC),
2577                              NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)),
2578                 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)),
2579         },
2580         [ACTIONS_TEMPLATE_DESTROY_ID] = {
2581                 .name = "actions_template",
2582                 .help = "specify an actions template id to destroy",
2583                 .next = NEXT(next_at_destroy_attr,
2584                              NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)),
2585                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer,
2586                                             args.templ_destroy.template_id)),
2587                 .call = parse_template_destroy,
2588         },
2589         [ACTIONS_TEMPLATE_INGRESS] = {
2590                 .name = "ingress",
2591                 .help = "attribute actions to ingress",
2592                 .next = NEXT(next_at_attr),
2593                 .call = parse_template,
2594         },
2595         [ACTIONS_TEMPLATE_EGRESS] = {
2596                 .name = "egress",
2597                 .help = "attribute actions to egress",
2598                 .next = NEXT(next_at_attr),
2599                 .call = parse_template,
2600         },
2601         [ACTIONS_TEMPLATE_TRANSFER] = {
2602                 .name = "transfer",
2603                 .help = "attribute actions to transfer",
2604                 .next = NEXT(next_at_attr),
2605                 .call = parse_template,
2606         },
2607         [ACTIONS_TEMPLATE_SPEC] = {
2608                 .name = "template",
2609                 .help = "specify action to create actions template",
2610                 .next = NEXT(next_action),
2611                 .call = parse_template,
2612         },
2613         [ACTIONS_TEMPLATE_MASK] = {
2614                 .name = "mask",
2615                 .help = "specify action mask to create actions template",
2616                 .next = NEXT(next_action),
2617                 .call = parse_template,
2618         },
2619         /* Top-level command. */
2620         [INDIRECT_ACTION] = {
2621                 .name = "indirect_action",
2622                 .type = "{command} {port_id} [{arg} [...]]",
2623                 .help = "manage indirect actions",
2624                 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)),
2625                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2626                 .call = parse_ia,
2627         },
2628         /* Sub-level commands. */
2629         [INDIRECT_ACTION_CREATE] = {
2630                 .name = "create",
2631                 .help = "create indirect action",
2632                 .next = NEXT(next_ia_create_attr),
2633                 .call = parse_ia,
2634         },
2635         [INDIRECT_ACTION_UPDATE] = {
2636                 .name = "update",
2637                 .help = "update indirect action",
2638                 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC),
2639                              NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
2640                 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)),
2641                 .call = parse_ia,
2642         },
2643         [INDIRECT_ACTION_DESTROY] = {
2644                 .name = "destroy",
2645                 .help = "destroy indirect action",
2646                 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)),
2647                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2648                 .call = parse_ia_destroy,
2649         },
2650         [INDIRECT_ACTION_QUERY] = {
2651                 .name = "query",
2652                 .help = "query indirect action",
2653                 .next = NEXT(NEXT_ENTRY(END),
2654                              NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
2655                 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)),
2656                 .call = parse_ia,
2657         },
2658         [VALIDATE] = {
2659                 .name = "validate",
2660                 .help = "check whether a flow rule can be created",
2661                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)),
2662                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2663                 .call = parse_vc,
2664         },
2665         [CREATE] = {
2666                 .name = "create",
2667                 .help = "create a flow rule",
2668                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)),
2669                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2670                 .call = parse_vc,
2671         },
2672         [DESTROY] = {
2673                 .name = "destroy",
2674                 .help = "destroy specific flow rules",
2675                 .next = NEXT(NEXT_ENTRY(DESTROY_RULE),
2676                              NEXT_ENTRY(COMMON_PORT_ID)),
2677                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2678                 .call = parse_destroy,
2679         },
2680         [FLUSH] = {
2681                 .name = "flush",
2682                 .help = "destroy all flow rules",
2683                 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)),
2684                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2685                 .call = parse_flush,
2686         },
2687         [DUMP] = {
2688                 .name = "dump",
2689                 .help = "dump single/all flow rules to file",
2690                 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)),
2691                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2692                 .call = parse_dump,
2693         },
2694         [QUERY] = {
2695                 .name = "query",
2696                 .help = "query an existing flow rule",
2697                 .next = NEXT(NEXT_ENTRY(QUERY_ACTION),
2698                              NEXT_ENTRY(COMMON_RULE_ID),
2699                              NEXT_ENTRY(COMMON_PORT_ID)),
2700                 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type),
2701                              ARGS_ENTRY(struct buffer, args.query.rule),
2702                              ARGS_ENTRY(struct buffer, port)),
2703                 .call = parse_query,
2704         },
2705         [LIST] = {
2706                 .name = "list",
2707                 .help = "list existing flow rules",
2708                 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)),
2709                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2710                 .call = parse_list,
2711         },
2712         [AGED] = {
2713                 .name = "aged",
2714                 .help = "list and destroy aged flows",
2715                 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)),
2716                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2717                 .call = parse_aged,
2718         },
2719         [ISOLATE] = {
2720                 .name = "isolate",
2721                 .help = "restrict ingress traffic to the defined flow rules",
2722                 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN),
2723                              NEXT_ENTRY(COMMON_PORT_ID)),
2724                 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set),
2725                              ARGS_ENTRY(struct buffer, port)),
2726                 .call = parse_isolate,
2727         },
2728         [FLEX] = {
2729                 .name = "flex_item",
2730                 .help = "flex item API",
2731                 .next = NEXT(next_flex_item),
2732                 .call = parse_flex,
2733         },
2734         [FLEX_ITEM_INIT] = {
2735                 .name = "init",
2736                 .help = "flex item init",
2737                 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token),
2738                              ARGS_ENTRY(struct buffer, port)),
2739                 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN),
2740                              NEXT_ENTRY(COMMON_PORT_ID)),
2741                 .call = parse_flex
2742         },
2743         [FLEX_ITEM_CREATE] = {
2744                 .name = "create",
2745                 .help = "flex item create",
2746                 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename),
2747                              ARGS_ENTRY(struct buffer, args.flex.token),
2748                              ARGS_ENTRY(struct buffer, port)),
2749                 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH),
2750                              NEXT_ENTRY(COMMON_FLEX_TOKEN),
2751                              NEXT_ENTRY(COMMON_PORT_ID)),
2752                 .call = parse_flex
2753         },
2754         [FLEX_ITEM_DESTROY] = {
2755                 .name = "destroy",
2756                 .help = "flex item destroy",
2757                 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token),
2758                              ARGS_ENTRY(struct buffer, port)),
2759                 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN),
2760                              NEXT_ENTRY(COMMON_PORT_ID)),
2761                 .call = parse_flex
2762         },
2763         [TUNNEL] = {
2764                 .name = "tunnel",
2765                 .help = "new tunnel API",
2766                 .next = NEXT(NEXT_ENTRY
2767                              (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)),
2768                 .call = parse_tunnel,
2769         },
2770         /* Tunnel arguments. */
2771         [TUNNEL_CREATE] = {
2772                 .name = "create",
2773                 .help = "create new tunnel object",
2774                 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE),
2775                              NEXT_ENTRY(COMMON_PORT_ID)),
2776                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2777                 .call = parse_tunnel,
2778         },
2779         [TUNNEL_CREATE_TYPE] = {
2780                 .name = "type",
2781                 .help = "create new tunnel",
2782                 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)),
2783                 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)),
2784                 .call = parse_tunnel,
2785         },
2786         [TUNNEL_DESTROY] = {
2787                 .name = "destroy",
2788                 .help = "destroy tunnel",
2789                 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID),
2790                              NEXT_ENTRY(COMMON_PORT_ID)),
2791                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2792                 .call = parse_tunnel,
2793         },
2794         [TUNNEL_DESTROY_ID] = {
2795                 .name = "id",
2796                 .help = "tunnel identifier to destroy",
2797                 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)),
2798                 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)),
2799                 .call = parse_tunnel,
2800         },
2801         [TUNNEL_LIST] = {
2802                 .name = "list",
2803                 .help = "list existing tunnels",
2804                 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)),
2805                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2806                 .call = parse_tunnel,
2807         },
2808         /* Destroy arguments. */
2809         [DESTROY_RULE] = {
2810                 .name = "rule",
2811                 .help = "specify a rule identifier",
2812                 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)),
2813                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)),
2814                 .call = parse_destroy,
2815         },
2816         /* Dump arguments. */
2817         [DUMP_ALL] = {
2818                 .name = "all",
2819                 .help = "dump all",
2820                 .next = NEXT(next_dump_attr),
2821                 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)),
2822                 .call = parse_dump,
2823         },
2824         [DUMP_ONE] = {
2825                 .name = "rule",
2826                 .help = "dump one rule",
2827                 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)),
2828                 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file),
2829                                 ARGS_ENTRY(struct buffer, args.dump.rule)),
2830                 .call = parse_dump,
2831         },
2832         /* Query arguments. */
2833         [QUERY_ACTION] = {
2834                 .name = "{action}",
2835                 .type = "ACTION",
2836                 .help = "action to query, must be part of the rule",
2837                 .call = parse_action,
2838                 .comp = comp_action,
2839         },
2840         /* List arguments. */
2841         [LIST_GROUP] = {
2842                 .name = "group",
2843                 .help = "specify a group",
2844                 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)),
2845                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)),
2846                 .call = parse_list,
2847         },
2848         [AGED_DESTROY] = {
2849                 .name = "destroy",
2850                 .help = "specify aged flows need be destroyed",
2851                 .call = parse_aged,
2852                 .comp = comp_none,
2853         },
2854         /* Validate/create attributes. */
2855         [VC_GROUP] = {
2856                 .name = "group",
2857                 .help = "specify a group",
2858                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)),
2859                 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)),
2860                 .call = parse_vc,
2861         },
2862         [VC_PRIORITY] = {
2863                 .name = "priority",
2864                 .help = "specify a priority level",
2865                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)),
2866                 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)),
2867                 .call = parse_vc,
2868         },
2869         [VC_INGRESS] = {
2870                 .name = "ingress",
2871                 .help = "affect rule to ingress",
2872                 .next = NEXT(next_vc_attr),
2873                 .call = parse_vc,
2874         },
2875         [VC_EGRESS] = {
2876                 .name = "egress",
2877                 .help = "affect rule to egress",
2878                 .next = NEXT(next_vc_attr),
2879                 .call = parse_vc,
2880         },
2881         [VC_TRANSFER] = {
2882                 .name = "transfer",
2883                 .help = "apply rule directly to endpoints found in pattern",
2884                 .next = NEXT(next_vc_attr),
2885                 .call = parse_vc,
2886         },
2887         [VC_TUNNEL_SET] = {
2888                 .name = "tunnel_set",
2889                 .help = "tunnel steer rule",
2890                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)),
2891                 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)),
2892                 .call = parse_vc,
2893         },
2894         [VC_TUNNEL_MATCH] = {
2895                 .name = "tunnel_match",
2896                 .help = "tunnel match rule",
2897                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)),
2898                 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)),
2899                 .call = parse_vc,
2900         },
2901         /* Validate/create pattern. */
2902         [ITEM_PATTERN] = {
2903                 .name = "pattern",
2904                 .help = "submit a list of pattern items",
2905                 .next = NEXT(next_item),
2906                 .call = parse_vc,
2907         },
2908         [ITEM_PARAM_IS] = {
2909                 .name = "is",
2910                 .help = "match value perfectly (with full bit-mask)",
2911                 .call = parse_vc_spec,
2912         },
2913         [ITEM_PARAM_SPEC] = {
2914                 .name = "spec",
2915                 .help = "match value according to configured bit-mask",
2916                 .call = parse_vc_spec,
2917         },
2918         [ITEM_PARAM_LAST] = {
2919                 .name = "last",
2920                 .help = "specify upper bound to establish a range",
2921                 .call = parse_vc_spec,
2922         },
2923         [ITEM_PARAM_MASK] = {
2924                 .name = "mask",
2925                 .help = "specify bit-mask with relevant bits set to one",
2926                 .call = parse_vc_spec,
2927         },
2928         [ITEM_PARAM_PREFIX] = {
2929                 .name = "prefix",
2930                 .help = "generate bit-mask from a prefix length",
2931                 .call = parse_vc_spec,
2932         },
2933         [ITEM_NEXT] = {
2934                 .name = "/",
2935                 .help = "specify next pattern item",
2936                 .next = NEXT(next_item),
2937         },
2938         [ITEM_END] = {
2939                 .name = "end",
2940                 .help = "end list of pattern items",
2941                 .priv = PRIV_ITEM(END, 0),
2942                 .next = NEXT(NEXT_ENTRY(ACTIONS, END)),
2943                 .call = parse_vc,
2944         },
2945         [ITEM_VOID] = {
2946                 .name = "void",
2947                 .help = "no-op pattern item",
2948                 .priv = PRIV_ITEM(VOID, 0),
2949                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
2950                 .call = parse_vc,
2951         },
2952         [ITEM_INVERT] = {
2953                 .name = "invert",
2954                 .help = "perform actions when pattern does not match",
2955                 .priv = PRIV_ITEM(INVERT, 0),
2956                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
2957                 .call = parse_vc,
2958         },
2959         [ITEM_ANY] = {
2960                 .name = "any",
2961                 .help = "match any protocol for the current layer",
2962                 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)),
2963                 .next = NEXT(item_any),
2964                 .call = parse_vc,
2965         },
2966         [ITEM_ANY_NUM] = {
2967                 .name = "num",
2968                 .help = "number of layers covered",
2969                 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
2970                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)),
2971         },
2972         [ITEM_PF] = {
2973                 .name = "pf",
2974                 .help = "match traffic from/to the physical function",
2975                 .priv = PRIV_ITEM(PF, 0),
2976                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
2977                 .call = parse_vc,
2978         },
2979         [ITEM_VF] = {
2980                 .name = "vf",
2981                 .help = "match traffic from/to a virtual function ID",
2982                 .priv = PRIV_ITEM(VF, sizeof(struct rte_flow_item_vf)),
2983                 .next = NEXT(item_vf),
2984                 .call = parse_vc,
2985         },
2986         [ITEM_VF_ID] = {
2987                 .name = "id",
2988                 .help = "VF ID",
2989                 .next = NEXT(item_vf, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
2990                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_vf, id)),
2991         },
2992         [ITEM_PHY_PORT] = {
2993                 .name = "phy_port",
2994                 .help = "match traffic from/to a specific physical port",
2995                 .priv = PRIV_ITEM(PHY_PORT,
2996                                   sizeof(struct rte_flow_item_phy_port)),
2997                 .next = NEXT(item_phy_port),
2998                 .call = parse_vc,
2999         },
3000         [ITEM_PHY_PORT_INDEX] = {
3001                 .name = "index",
3002                 .help = "physical port index",
3003                 .next = NEXT(item_phy_port, NEXT_ENTRY(COMMON_UNSIGNED),
3004                              item_param),
3005                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_phy_port, index)),
3006         },
3007         [ITEM_PORT_ID] = {
3008                 .name = "port_id",
3009                 .help = "match traffic from/to a given DPDK port ID",
3010                 .priv = PRIV_ITEM(PORT_ID,
3011                                   sizeof(struct rte_flow_item_port_id)),
3012                 .next = NEXT(item_port_id),
3013                 .call = parse_vc,
3014         },
3015         [ITEM_PORT_ID_ID] = {
3016                 .name = "id",
3017                 .help = "DPDK port ID",
3018                 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED),
3019                              item_param),
3020                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)),
3021         },
3022         [ITEM_MARK] = {
3023                 .name = "mark",
3024                 .help = "match traffic against value set in previously matched rule",
3025                 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)),
3026                 .next = NEXT(item_mark),
3027                 .call = parse_vc,
3028         },
3029         [ITEM_MARK_ID] = {
3030                 .name = "id",
3031                 .help = "Integer value to match against",
3032                 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED),
3033                              item_param),
3034                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)),
3035         },
3036         [ITEM_RAW] = {
3037                 .name = "raw",
3038                 .help = "match an arbitrary byte string",
3039                 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE),
3040                 .next = NEXT(item_raw),
3041                 .call = parse_vc,
3042         },
3043         [ITEM_RAW_RELATIVE] = {
3044                 .name = "relative",
3045                 .help = "look for pattern after the previous item",
3046                 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param),
3047                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
3048                                            relative, 1)),
3049         },
3050         [ITEM_RAW_SEARCH] = {
3051                 .name = "search",
3052                 .help = "search pattern from offset (see also limit)",
3053                 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param),
3054                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
3055                                            search, 1)),
3056         },
3057         [ITEM_RAW_OFFSET] = {
3058                 .name = "offset",
3059                 .help = "absolute or relative offset for pattern",
3060                 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param),
3061                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)),
3062         },
3063         [ITEM_RAW_LIMIT] = {
3064                 .name = "limit",
3065                 .help = "search area limit for start of pattern",
3066                 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3067                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)),
3068         },
3069         [ITEM_RAW_PATTERN] = {
3070                 .name = "pattern",
3071                 .help = "byte string to look for",
3072                 .next = NEXT(item_raw,
3073                              NEXT_ENTRY(COMMON_STRING),
3074                              NEXT_ENTRY(ITEM_PARAM_IS,
3075                                         ITEM_PARAM_SPEC,
3076                                         ITEM_PARAM_MASK)),
3077                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern),
3078                              ARGS_ENTRY(struct rte_flow_item_raw, length),
3079                              ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw),
3080                                             ITEM_RAW_PATTERN_SIZE)),
3081         },
3082         [ITEM_RAW_PATTERN_HEX] = {
3083                 .name = "pattern_hex",
3084                 .help = "hex string to look for",
3085                 .next = NEXT(item_raw,
3086                              NEXT_ENTRY(COMMON_HEX),
3087                              NEXT_ENTRY(ITEM_PARAM_IS,
3088                                         ITEM_PARAM_SPEC,
3089                                         ITEM_PARAM_MASK)),
3090                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern),
3091                              ARGS_ENTRY(struct rte_flow_item_raw, length),
3092                              ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw),
3093                                             ITEM_RAW_PATTERN_SIZE)),
3094         },
3095         [ITEM_ETH] = {
3096                 .name = "eth",
3097                 .help = "match Ethernet header",
3098                 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
3099                 .next = NEXT(item_eth),
3100                 .call = parse_vc,
3101         },
3102         [ITEM_ETH_DST] = {
3103                 .name = "dst",
3104                 .help = "destination MAC",
3105                 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param),
3106                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, dst)),
3107         },
3108         [ITEM_ETH_SRC] = {
3109                 .name = "src",
3110                 .help = "source MAC",
3111                 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param),
3112                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, src)),
3113         },
3114         [ITEM_ETH_TYPE] = {
3115                 .name = "type",
3116                 .help = "EtherType",
3117                 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3118                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, type)),
3119         },
3120         [ITEM_ETH_HAS_VLAN] = {
3121                 .name = "has_vlan",
3122                 .help = "packet header contains VLAN",
3123                 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3124                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth,
3125                                            has_vlan, 1)),
3126         },
3127         [ITEM_VLAN] = {
3128                 .name = "vlan",
3129                 .help = "match 802.1Q/ad VLAN tag",
3130                 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
3131                 .next = NEXT(item_vlan),
3132                 .call = parse_vc,
3133         },
3134         [ITEM_VLAN_TCI] = {
3135                 .name = "tci",
3136                 .help = "tag control information",
3137                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
3138                              item_param),
3139                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)),
3140         },
3141         [ITEM_VLAN_PCP] = {
3142                 .name = "pcp",
3143                 .help = "priority code point",
3144                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
3145                              item_param),
3146                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
3147                                                   tci, "\xe0\x00")),
3148         },
3149         [ITEM_VLAN_DEI] = {
3150                 .name = "dei",
3151                 .help = "drop eligible indicator",
3152                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
3153                              item_param),
3154                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
3155                                                   tci, "\x10\x00")),
3156         },
3157         [ITEM_VLAN_VID] = {
3158                 .name = "vid",
3159                 .help = "VLAN identifier",
3160                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
3161                              item_param),
3162                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
3163                                                   tci, "\x0f\xff")),
3164         },
3165         [ITEM_VLAN_INNER_TYPE] = {
3166                 .name = "inner_type",
3167                 .help = "inner EtherType",
3168                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
3169                              item_param),
3170                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan,
3171                                              inner_type)),
3172         },
3173         [ITEM_VLAN_HAS_MORE_VLAN] = {
3174                 .name = "has_more_vlan",
3175                 .help = "packet header contains another VLAN",
3176                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
3177                              item_param),
3178                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan,
3179                                            has_more_vlan, 1)),
3180         },
3181         [ITEM_IPV4] = {
3182                 .name = "ipv4",
3183                 .help = "match IPv4 header",
3184                 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
3185                 .next = NEXT(item_ipv4),
3186                 .call = parse_vc,
3187         },
3188         [ITEM_IPV4_VER_IHL] = {
3189                 .name = "version_ihl",
3190                 .help = "match header length",
3191                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
3192                              item_param),
3193                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4,
3194                                      hdr.version_ihl)),
3195         },
3196         [ITEM_IPV4_TOS] = {
3197                 .name = "tos",
3198                 .help = "type of service",
3199                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
3200                              item_param),
3201                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
3202                                              hdr.type_of_service)),
3203         },
3204         [ITEM_IPV4_ID] = {
3205                 .name = "packet_id",
3206                 .help = "fragment packet id",
3207                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
3208                              item_param),
3209                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
3210                                              hdr.packet_id)),
3211         },
3212         [ITEM_IPV4_FRAGMENT_OFFSET] = {
3213                 .name = "fragment_offset",
3214                 .help = "fragmentation flags and fragment offset",
3215                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
3216                              item_param),
3217                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
3218                                              hdr.fragment_offset)),
3219         },
3220         [ITEM_IPV4_TTL] = {
3221                 .name = "ttl",
3222                 .help = "time to live",
3223                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
3224                              item_param),
3225                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
3226                                              hdr.time_to_live)),
3227         },
3228         [ITEM_IPV4_PROTO] = {
3229                 .name = "proto",
3230                 .help = "next protocol ID",
3231                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
3232                              item_param),
3233                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
3234                                              hdr.next_proto_id)),
3235         },
3236         [ITEM_IPV4_SRC] = {
3237                 .name = "src",
3238                 .help = "source address",
3239                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR),
3240                              item_param),
3241                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
3242                                              hdr.src_addr)),
3243         },
3244         [ITEM_IPV4_DST] = {
3245                 .name = "dst",
3246                 .help = "destination address",
3247                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR),
3248                              item_param),
3249                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
3250                                              hdr.dst_addr)),
3251         },
3252         [ITEM_IPV6] = {
3253                 .name = "ipv6",
3254                 .help = "match IPv6 header",
3255                 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
3256                 .next = NEXT(item_ipv6),
3257                 .call = parse_vc,
3258         },
3259         [ITEM_IPV6_TC] = {
3260                 .name = "tc",
3261                 .help = "traffic class",
3262                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
3263                              item_param),
3264                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
3265                                                   hdr.vtc_flow,
3266                                                   "\x0f\xf0\x00\x00")),
3267         },
3268         [ITEM_IPV6_FLOW] = {
3269                 .name = "flow",
3270                 .help = "flow label",
3271                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
3272                              item_param),
3273                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
3274                                                   hdr.vtc_flow,
3275                                                   "\x00\x0f\xff\xff")),
3276         },
3277         [ITEM_IPV6_PROTO] = {
3278                 .name = "proto",
3279                 .help = "protocol (next header)",
3280                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
3281                              item_param),
3282                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
3283                                              hdr.proto)),
3284         },
3285         [ITEM_IPV6_HOP] = {
3286                 .name = "hop",
3287                 .help = "hop limit",
3288                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
3289                              item_param),
3290                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
3291                                              hdr.hop_limits)),
3292         },
3293         [ITEM_IPV6_SRC] = {
3294                 .name = "src",
3295                 .help = "source address",
3296                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR),
3297                              item_param),
3298                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
3299                                              hdr.src_addr)),
3300         },
3301         [ITEM_IPV6_DST] = {
3302                 .name = "dst",
3303                 .help = "destination address",
3304                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR),
3305                              item_param),
3306                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
3307                                              hdr.dst_addr)),
3308         },
3309         [ITEM_IPV6_HAS_FRAG_EXT] = {
3310                 .name = "has_frag_ext",
3311                 .help = "fragment packet attribute",
3312                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
3313                              item_param),
3314                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
3315                                            has_frag_ext, 1)),
3316         },
3317         [ITEM_ICMP] = {
3318                 .name = "icmp",
3319                 .help = "match ICMP header",
3320                 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
3321                 .next = NEXT(item_icmp),
3322                 .call = parse_vc,
3323         },
3324         [ITEM_ICMP_TYPE] = {
3325                 .name = "type",
3326                 .help = "ICMP packet type",
3327                 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED),
3328                              item_param),
3329                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
3330                                              hdr.icmp_type)),
3331         },
3332         [ITEM_ICMP_CODE] = {
3333                 .name = "code",
3334                 .help = "ICMP packet code",
3335                 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED),
3336                              item_param),
3337                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
3338                                              hdr.icmp_code)),
3339         },
3340         [ITEM_ICMP_IDENT] = {
3341                 .name = "ident",
3342                 .help = "ICMP packet identifier",
3343                 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED),
3344                              item_param),
3345                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
3346                                              hdr.icmp_ident)),
3347         },
3348         [ITEM_ICMP_SEQ] = {
3349                 .name = "seq",
3350                 .help = "ICMP packet sequence number",
3351                 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED),
3352                              item_param),
3353                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
3354                                              hdr.icmp_seq_nb)),
3355         },
3356         [ITEM_UDP] = {
3357                 .name = "udp",
3358                 .help = "match UDP header",
3359                 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
3360                 .next = NEXT(item_udp),
3361                 .call = parse_vc,
3362         },
3363         [ITEM_UDP_SRC] = {
3364                 .name = "src",
3365                 .help = "UDP source port",
3366                 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED),
3367                              item_param),
3368                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
3369                                              hdr.src_port)),
3370         },
3371         [ITEM_UDP_DST] = {
3372                 .name = "dst",
3373                 .help = "UDP destination port",
3374                 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3375                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
3376                                              hdr.dst_port)),
3377         },
3378         [ITEM_TCP] = {
3379                 .name = "tcp",
3380                 .help = "match TCP header",
3381                 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
3382                 .next = NEXT(item_tcp),
3383                 .call = parse_vc,
3384         },
3385         [ITEM_TCP_SRC] = {
3386                 .name = "src",
3387                 .help = "TCP source port",
3388                 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3389                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
3390                                              hdr.src_port)),
3391         },
3392         [ITEM_TCP_DST] = {
3393                 .name = "dst",
3394                 .help = "TCP destination port",
3395                 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3396                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
3397                                              hdr.dst_port)),
3398         },
3399         [ITEM_TCP_FLAGS] = {
3400                 .name = "flags",
3401                 .help = "TCP flags",
3402                 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3403                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
3404                                              hdr.tcp_flags)),
3405         },
3406         [ITEM_SCTP] = {
3407                 .name = "sctp",
3408                 .help = "match SCTP header",
3409                 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
3410                 .next = NEXT(item_sctp),
3411                 .call = parse_vc,
3412         },
3413         [ITEM_SCTP_SRC] = {
3414                 .name = "src",
3415                 .help = "SCTP source port",
3416                 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED),
3417                              item_param),
3418                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
3419                                              hdr.src_port)),
3420         },
3421         [ITEM_SCTP_DST] = {
3422                 .name = "dst",
3423                 .help = "SCTP destination port",
3424                 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED),
3425                              item_param),
3426                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
3427                                              hdr.dst_port)),
3428         },
3429         [ITEM_SCTP_TAG] = {
3430                 .name = "tag",
3431                 .help = "validation tag",
3432                 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED),
3433                              item_param),
3434                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
3435                                              hdr.tag)),
3436         },
3437         [ITEM_SCTP_CKSUM] = {
3438                 .name = "cksum",
3439                 .help = "checksum",
3440                 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED),
3441                              item_param),
3442                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
3443                                              hdr.cksum)),
3444         },
3445         [ITEM_VXLAN] = {
3446                 .name = "vxlan",
3447                 .help = "match VXLAN header",
3448                 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
3449                 .next = NEXT(item_vxlan),
3450                 .call = parse_vc,
3451         },
3452         [ITEM_VXLAN_VNI] = {
3453                 .name = "vni",
3454                 .help = "VXLAN identifier",
3455                 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED),
3456                              item_param),
3457                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)),
3458         },
3459         [ITEM_VXLAN_LAST_RSVD] = {
3460                 .name = "last_rsvd",
3461                 .help = "VXLAN last reserved bits",
3462                 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED),
3463                              item_param),
3464                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan,
3465                                              rsvd1)),
3466         },
3467         [ITEM_E_TAG] = {
3468                 .name = "e_tag",
3469                 .help = "match E-Tag header",
3470                 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
3471                 .next = NEXT(item_e_tag),
3472                 .call = parse_vc,
3473         },
3474         [ITEM_E_TAG_GRP_ECID_B] = {
3475                 .name = "grp_ecid_b",
3476                 .help = "GRP and E-CID base",
3477                 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED),
3478                              item_param),
3479                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag,
3480                                                   rsvd_grp_ecid_b,
3481                                                   "\x3f\xff")),
3482         },
3483         [ITEM_NVGRE] = {
3484                 .name = "nvgre",
3485                 .help = "match NVGRE header",
3486                 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
3487                 .next = NEXT(item_nvgre),
3488                 .call = parse_vc,
3489         },
3490         [ITEM_NVGRE_TNI] = {
3491                 .name = "tni",
3492                 .help = "virtual subnet ID",
3493                 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED),
3494                              item_param),
3495                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)),
3496         },
3497         [ITEM_MPLS] = {
3498                 .name = "mpls",
3499                 .help = "match MPLS header",
3500                 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
3501                 .next = NEXT(item_mpls),
3502                 .call = parse_vc,
3503         },
3504         [ITEM_MPLS_LABEL] = {
3505                 .name = "label",
3506                 .help = "MPLS label",
3507                 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED),
3508                              item_param),
3509                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
3510                                                   label_tc_s,
3511                                                   "\xff\xff\xf0")),
3512         },
3513         [ITEM_MPLS_TC] = {
3514                 .name = "tc",
3515                 .help = "MPLS Traffic Class",
3516                 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED),
3517                              item_param),
3518                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
3519                                                   label_tc_s,
3520                                                   "\x00\x00\x0e")),
3521         },
3522         [ITEM_MPLS_S] = {
3523                 .name = "s",
3524                 .help = "MPLS Bottom-of-Stack",
3525                 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED),
3526                              item_param),
3527                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
3528                                                   label_tc_s,
3529                                                   "\x00\x00\x01")),
3530         },
3531         [ITEM_GRE] = {
3532                 .name = "gre",
3533                 .help = "match GRE header",
3534                 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
3535                 .next = NEXT(item_gre),
3536                 .call = parse_vc,
3537         },
3538         [ITEM_GRE_PROTO] = {
3539                 .name = "protocol",
3540                 .help = "GRE protocol type",
3541                 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED),
3542                              item_param),
3543                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
3544                                              protocol)),
3545         },
3546         [ITEM_GRE_C_RSVD0_VER] = {
3547                 .name = "c_rsvd0_ver",
3548                 .help =
3549                         "checksum (1b), undefined (1b), key bit (1b),"
3550                         " sequence number (1b), reserved 0 (9b),"
3551                         " version (3b)",
3552                 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED),
3553                              item_param),
3554                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
3555                                              c_rsvd0_ver)),
3556         },
3557         [ITEM_GRE_C_BIT] = {
3558                 .name = "c_bit",
3559                 .help = "checksum bit (C)",
3560                 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN),
3561                              item_param),
3562                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
3563                                                   c_rsvd0_ver,
3564                                                   "\x80\x00\x00\x00")),
3565         },
3566         [ITEM_GRE_S_BIT] = {
3567                 .name = "s_bit",
3568                 .help = "sequence number bit (S)",
3569                 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param),
3570                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
3571                                                   c_rsvd0_ver,
3572                                                   "\x10\x00\x00\x00")),
3573         },
3574         [ITEM_GRE_K_BIT] = {
3575                 .name = "k_bit",
3576                 .help = "key bit (K)",
3577                 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param),
3578                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
3579                                                   c_rsvd0_ver,
3580                                                   "\x20\x00\x00\x00")),
3581         },
3582         [ITEM_FUZZY] = {
3583                 .name = "fuzzy",
3584                 .help = "fuzzy pattern match, expect faster than default",
3585                 .priv = PRIV_ITEM(FUZZY,
3586                                 sizeof(struct rte_flow_item_fuzzy)),
3587                 .next = NEXT(item_fuzzy),
3588                 .call = parse_vc,
3589         },
3590         [ITEM_FUZZY_THRESH] = {
3591                 .name = "thresh",
3592                 .help = "match accuracy threshold",
3593                 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED),
3594                              item_param),
3595                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy,
3596                                         thresh)),
3597         },
3598         [ITEM_GTP] = {
3599                 .name = "gtp",
3600                 .help = "match GTP header",
3601                 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)),
3602                 .next = NEXT(item_gtp),
3603                 .call = parse_vc,
3604         },
3605         [ITEM_GTP_FLAGS] = {
3606                 .name = "v_pt_rsv_flags",
3607                 .help = "GTP flags",
3608                 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3609                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp,
3610                                         v_pt_rsv_flags)),
3611         },
3612         [ITEM_GTP_MSG_TYPE] = {
3613                 .name = "msg_type",
3614                 .help = "GTP message type",
3615                 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3616                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, msg_type)),
3617         },
3618         [ITEM_GTP_TEID] = {
3619                 .name = "teid",
3620                 .help = "tunnel endpoint identifier",
3621                 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3622                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, teid)),
3623         },
3624         [ITEM_GTPC] = {
3625                 .name = "gtpc",
3626                 .help = "match GTP header",
3627                 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
3628                 .next = NEXT(item_gtp),
3629                 .call = parse_vc,
3630         },
3631         [ITEM_GTPU] = {
3632                 .name = "gtpu",
3633                 .help = "match GTP header",
3634                 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)),
3635                 .next = NEXT(item_gtp),
3636                 .call = parse_vc,
3637         },
3638         [ITEM_GENEVE] = {
3639                 .name = "geneve",
3640                 .help = "match GENEVE header",
3641                 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
3642                 .next = NEXT(item_geneve),
3643                 .call = parse_vc,
3644         },
3645         [ITEM_GENEVE_VNI] = {
3646                 .name = "vni",
3647                 .help = "virtual network identifier",
3648                 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED),
3649                              item_param),
3650                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)),
3651         },
3652         [ITEM_GENEVE_PROTO] = {
3653                 .name = "protocol",
3654                 .help = "GENEVE protocol type",
3655                 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED),
3656                              item_param),
3657                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve,
3658                                              protocol)),
3659         },
3660         [ITEM_GENEVE_OPTLEN] = {
3661                 .name = "optlen",
3662                 .help = "GENEVE options length in dwords",
3663                 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED),
3664                              item_param),
3665                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve,
3666                                                   ver_opt_len_o_c_rsvd0,
3667                                                   "\x3f\x00")),
3668         },
3669         [ITEM_VXLAN_GPE] = {
3670                 .name = "vxlan-gpe",
3671                 .help = "match VXLAN-GPE header",
3672                 .priv = PRIV_ITEM(VXLAN_GPE,
3673                                   sizeof(struct rte_flow_item_vxlan_gpe)),
3674                 .next = NEXT(item_vxlan_gpe),
3675                 .call = parse_vc,
3676         },
3677         [ITEM_VXLAN_GPE_VNI] = {
3678                 .name = "vni",
3679                 .help = "VXLAN-GPE identifier",
3680                 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED),
3681                              item_param),
3682                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe,
3683                                              vni)),
3684         },
3685         [ITEM_ARP_ETH_IPV4] = {
3686                 .name = "arp_eth_ipv4",
3687                 .help = "match ARP header for Ethernet/IPv4",
3688                 .priv = PRIV_ITEM(ARP_ETH_IPV4,
3689                                   sizeof(struct rte_flow_item_arp_eth_ipv4)),
3690                 .next = NEXT(item_arp_eth_ipv4),
3691                 .call = parse_vc,
3692         },
3693         [ITEM_ARP_ETH_IPV4_SHA] = {
3694                 .name = "sha",
3695                 .help = "sender hardware address",
3696                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR),
3697                              item_param),
3698                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
3699                                              sha)),
3700         },
3701         [ITEM_ARP_ETH_IPV4_SPA] = {
3702                 .name = "spa",
3703                 .help = "sender IPv4 address",
3704                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR),
3705                              item_param),
3706                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
3707                                              spa)),
3708         },
3709         [ITEM_ARP_ETH_IPV4_THA] = {
3710                 .name = "tha",
3711                 .help = "target hardware address",
3712                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR),
3713                              item_param),
3714                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
3715                                              tha)),
3716         },
3717         [ITEM_ARP_ETH_IPV4_TPA] = {
3718                 .name = "tpa",
3719                 .help = "target IPv4 address",
3720                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR),
3721                              item_param),
3722                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
3723                                              tpa)),
3724         },
3725         [ITEM_IPV6_EXT] = {
3726                 .name = "ipv6_ext",
3727                 .help = "match presence of any IPv6 extension header",
3728                 .priv = PRIV_ITEM(IPV6_EXT,
3729                                   sizeof(struct rte_flow_item_ipv6_ext)),
3730                 .next = NEXT(item_ipv6_ext),
3731                 .call = parse_vc,
3732         },
3733         [ITEM_IPV6_EXT_NEXT_HDR] = {
3734                 .name = "next_hdr",
3735                 .help = "next header",
3736                 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED),
3737                              item_param),
3738                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext,
3739                                              next_hdr)),
3740         },
3741         [ITEM_IPV6_FRAG_EXT] = {
3742                 .name = "ipv6_frag_ext",
3743                 .help = "match presence of IPv6 fragment extension header",
3744                 .priv = PRIV_ITEM(IPV6_FRAG_EXT,
3745                                 sizeof(struct rte_flow_item_ipv6_frag_ext)),
3746                 .next = NEXT(item_ipv6_frag_ext),
3747                 .call = parse_vc,
3748         },
3749         [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = {
3750                 .name = "next_hdr",
3751                 .help = "next header",
3752                 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED),
3753                              item_param),
3754                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext,
3755                                         hdr.next_header)),
3756         },
3757         [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = {
3758                 .name = "frag_data",
3759                 .help = "fragment flags and offset",
3760                 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED),
3761                              item_param),
3762                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext,
3763                                              hdr.frag_data)),
3764         },
3765         [ITEM_IPV6_FRAG_EXT_ID] = {
3766                 .name = "packet_id",
3767                 .help = "fragment packet id",
3768                 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED),
3769                              item_param),
3770                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext,
3771                                              hdr.id)),
3772         },
3773         [ITEM_ICMP6] = {
3774                 .name = "icmp6",
3775                 .help = "match any ICMPv6 header",
3776                 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)),
3777                 .next = NEXT(item_icmp6),
3778                 .call = parse_vc,
3779         },
3780         [ITEM_ICMP6_TYPE] = {
3781                 .name = "type",
3782                 .help = "ICMPv6 type",
3783                 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED),
3784                              item_param),
3785                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6,
3786                                              type)),
3787         },
3788         [ITEM_ICMP6_CODE] = {
3789                 .name = "code",
3790                 .help = "ICMPv6 code",
3791                 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED),
3792                              item_param),
3793                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6,
3794                                              code)),
3795         },
3796         [ITEM_ICMP6_ND_NS] = {
3797                 .name = "icmp6_nd_ns",
3798                 .help = "match ICMPv6 neighbor discovery solicitation",
3799                 .priv = PRIV_ITEM(ICMP6_ND_NS,
3800                                   sizeof(struct rte_flow_item_icmp6_nd_ns)),
3801                 .next = NEXT(item_icmp6_nd_ns),
3802                 .call = parse_vc,
3803         },
3804         [ITEM_ICMP6_ND_NS_TARGET_ADDR] = {
3805                 .name = "target_addr",
3806                 .help = "target address",
3807                 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR),
3808                              item_param),
3809                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns,
3810                                              target_addr)),
3811         },
3812         [ITEM_ICMP6_ND_NA] = {
3813                 .name = "icmp6_nd_na",
3814                 .help = "match ICMPv6 neighbor discovery advertisement",
3815                 .priv = PRIV_ITEM(ICMP6_ND_NA,
3816                                   sizeof(struct rte_flow_item_icmp6_nd_na)),
3817                 .next = NEXT(item_icmp6_nd_na),
3818                 .call = parse_vc,
3819         },
3820         [ITEM_ICMP6_ND_NA_TARGET_ADDR] = {
3821                 .name = "target_addr",
3822                 .help = "target address",
3823                 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR),
3824                              item_param),
3825                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na,
3826                                              target_addr)),
3827         },
3828         [ITEM_ICMP6_ND_OPT] = {
3829                 .name = "icmp6_nd_opt",
3830                 .help = "match presence of any ICMPv6 neighbor discovery"
3831                         " option",
3832                 .priv = PRIV_ITEM(ICMP6_ND_OPT,
3833                                   sizeof(struct rte_flow_item_icmp6_nd_opt)),
3834                 .next = NEXT(item_icmp6_nd_opt),
3835                 .call = parse_vc,
3836         },
3837         [ITEM_ICMP6_ND_OPT_TYPE] = {
3838                 .name = "type",
3839                 .help = "ND option type",
3840                 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED),
3841                              item_param),
3842                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt,
3843                                              type)),
3844         },
3845         [ITEM_ICMP6_ND_OPT_SLA_ETH] = {
3846                 .name = "icmp6_nd_opt_sla_eth",
3847                 .help = "match ICMPv6 neighbor discovery source Ethernet"
3848                         " link-layer address option",
3849                 .priv = PRIV_ITEM
3850                         (ICMP6_ND_OPT_SLA_ETH,
3851                          sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)),
3852                 .next = NEXT(item_icmp6_nd_opt_sla_eth),
3853                 .call = parse_vc,
3854         },
3855         [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = {
3856                 .name = "sla",
3857                 .help = "source Ethernet LLA",
3858                 .next = NEXT(item_icmp6_nd_opt_sla_eth,
3859                              NEXT_ENTRY(COMMON_MAC_ADDR), item_param),
3860                 .args = ARGS(ARGS_ENTRY_HTON
3861                              (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)),
3862         },
3863         [ITEM_ICMP6_ND_OPT_TLA_ETH] = {
3864                 .name = "icmp6_nd_opt_tla_eth",
3865                 .help = "match ICMPv6 neighbor discovery target Ethernet"
3866                         " link-layer address option",
3867                 .priv = PRIV_ITEM
3868                         (ICMP6_ND_OPT_TLA_ETH,
3869                          sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)),
3870                 .next = NEXT(item_icmp6_nd_opt_tla_eth),
3871                 .call = parse_vc,
3872         },
3873         [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = {
3874                 .name = "tla",
3875                 .help = "target Ethernet LLA",
3876                 .next = NEXT(item_icmp6_nd_opt_tla_eth,
3877                              NEXT_ENTRY(COMMON_MAC_ADDR), item_param),
3878                 .args = ARGS(ARGS_ENTRY_HTON
3879                              (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)),
3880         },
3881         [ITEM_META] = {
3882                 .name = "meta",
3883                 .help = "match metadata header",
3884                 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)),
3885                 .next = NEXT(item_meta),
3886                 .call = parse_vc,
3887         },
3888         [ITEM_META_DATA] = {
3889                 .name = "data",
3890                 .help = "metadata value",
3891                 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED),
3892                              item_param),
3893                 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta,
3894                                              data, "\xff\xff\xff\xff")),
3895         },
3896         [ITEM_GRE_KEY] = {
3897                 .name = "gre_key",
3898                 .help = "match GRE key",
3899                 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)),
3900                 .next = NEXT(item_gre_key),
3901                 .call = parse_vc,
3902         },
3903         [ITEM_GRE_KEY_VALUE] = {
3904                 .name = "value",
3905                 .help = "key value",
3906                 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED),
3907                              item_param),
3908                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
3909         },
3910         [ITEM_GRE_OPTION] = {
3911                 .name = "gre_option",
3912                 .help = "match GRE optional fields",
3913                 .priv = PRIV_ITEM(GRE_OPTION,
3914                                   sizeof(struct rte_flow_item_gre_opt)),
3915                 .next = NEXT(item_gre_option),
3916                 .call = parse_vc,
3917         },
3918         [ITEM_GRE_OPTION_CHECKSUM] = {
3919                 .name = "checksum",
3920                 .help = "match GRE checksum",
3921                 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED),
3922                              item_param),
3923                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt,
3924                                              checksum_rsvd.checksum)),
3925         },
3926         [ITEM_GRE_OPTION_KEY] = {
3927                 .name = "key",
3928                 .help = "match GRE key",
3929                 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED),
3930                              item_param),
3931                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt,
3932                                              key.key)),
3933         },
3934         [ITEM_GRE_OPTION_SEQUENCE] = {
3935                 .name = "sequence",
3936                 .help = "match GRE sequence",
3937                 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED),
3938                              item_param),
3939                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt,
3940                                              sequence.sequence)),
3941         },
3942         [ITEM_GTP_PSC] = {
3943                 .name = "gtp_psc",
3944                 .help = "match GTP extension header with type 0x85",
3945                 .priv = PRIV_ITEM(GTP_PSC,
3946                                 sizeof(struct rte_flow_item_gtp_psc)),
3947                 .next = NEXT(item_gtp_psc),
3948                 .call = parse_vc,
3949         },
3950         [ITEM_GTP_PSC_QFI] = {
3951                 .name = "qfi",
3952                 .help = "QoS flow identifier",
3953                 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED),
3954                              item_param),
3955                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc,
3956                                         hdr.qfi, 6)),
3957         },
3958         [ITEM_GTP_PSC_PDU_T] = {
3959                 .name = "pdu_t",
3960                 .help = "PDU type",
3961                 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED),
3962                              item_param),
3963                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc,
3964                                         hdr.type, 4)),
3965         },
3966         [ITEM_PPPOES] = {
3967                 .name = "pppoes",
3968                 .help = "match PPPoE session header",
3969                 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)),
3970                 .next = NEXT(item_pppoes),
3971                 .call = parse_vc,
3972         },
3973         [ITEM_PPPOED] = {
3974                 .name = "pppoed",
3975                 .help = "match PPPoE discovery header",
3976                 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)),
3977                 .next = NEXT(item_pppoed),
3978                 .call = parse_vc,
3979         },
3980         [ITEM_PPPOE_SEID] = {
3981                 .name = "seid",
3982                 .help = "session identifier",
3983                 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED),
3984                              item_param),
3985                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe,
3986                                         session_id)),
3987         },
3988         [ITEM_PPPOE_PROTO_ID] = {
3989                 .name = "pppoe_proto_id",
3990                 .help = "match PPPoE session protocol identifier",
3991                 .priv = PRIV_ITEM(PPPOE_PROTO_ID,
3992                                 sizeof(struct rte_flow_item_pppoe_proto_id)),
3993                 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED),
3994                              item_param),
3995                 .args = ARGS(ARGS_ENTRY_HTON
3996                              (struct rte_flow_item_pppoe_proto_id, proto_id)),
3997                 .call = parse_vc,
3998         },
3999         [ITEM_HIGIG2] = {
4000                 .name = "higig2",
4001                 .help = "matches higig2 header",
4002                 .priv = PRIV_ITEM(HIGIG2,
4003                                 sizeof(struct rte_flow_item_higig2_hdr)),
4004                 .next = NEXT(item_higig2),
4005                 .call = parse_vc,
4006         },
4007         [ITEM_HIGIG2_CLASSIFICATION] = {
4008                 .name = "classification",
4009                 .help = "matches classification of higig2 header",
4010                 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED),
4011                              item_param),
4012                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr,
4013                                         hdr.ppt1.classification)),
4014         },
4015         [ITEM_HIGIG2_VID] = {
4016                 .name = "vid",
4017                 .help = "matches vid of higig2 header",
4018                 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED),
4019                              item_param),
4020                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr,
4021                                         hdr.ppt1.vid)),
4022         },
4023         [ITEM_TAG] = {
4024                 .name = "tag",
4025                 .help = "match tag value",
4026                 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)),
4027                 .next = NEXT(item_tag),
4028                 .call = parse_vc,
4029         },
4030         [ITEM_TAG_DATA] = {
4031                 .name = "data",
4032                 .help = "tag value to match",
4033                 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
4034                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)),
4035         },
4036         [ITEM_TAG_INDEX] = {
4037                 .name = "index",
4038                 .help = "index of tag array to match",
4039                 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED),
4040                              NEXT_ENTRY(ITEM_PARAM_IS)),
4041                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)),
4042         },
4043         [ITEM_L2TPV3OIP] = {
4044                 .name = "l2tpv3oip",
4045                 .help = "match L2TPv3 over IP header",
4046                 .priv = PRIV_ITEM(L2TPV3OIP,
4047                                   sizeof(struct rte_flow_item_l2tpv3oip)),
4048                 .next = NEXT(item_l2tpv3oip),
4049                 .call = parse_vc,
4050         },
4051         [ITEM_L2TPV3OIP_SESSION_ID] = {
4052                 .name = "session_id",
4053                 .help = "session identifier",
4054                 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED),
4055                              item_param),
4056                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip,
4057                                              session_id)),
4058         },
4059         [ITEM_ESP] = {
4060                 .name = "esp",
4061                 .help = "match ESP header",
4062                 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)),
4063                 .next = NEXT(item_esp),
4064                 .call = parse_vc,
4065         },
4066         [ITEM_ESP_SPI] = {
4067                 .name = "spi",
4068                 .help = "security policy index",
4069                 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
4070                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp,
4071                                 hdr.spi)),
4072         },
4073         [ITEM_AH] = {
4074                 .name = "ah",
4075                 .help = "match AH header",
4076                 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)),
4077                 .next = NEXT(item_ah),
4078                 .call = parse_vc,
4079         },
4080         [ITEM_AH_SPI] = {
4081                 .name = "spi",
4082                 .help = "security parameters index",
4083                 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
4084                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)),
4085         },
4086         [ITEM_PFCP] = {
4087                 .name = "pfcp",
4088                 .help = "match pfcp header",
4089                 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
4090                 .next = NEXT(item_pfcp),
4091                 .call = parse_vc,
4092         },
4093         [ITEM_PFCP_S_FIELD] = {
4094                 .name = "s_field",
4095                 .help = "S field",
4096                 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED),
4097                              item_param),
4098                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp,
4099                                 s_field)),
4100         },
4101         [ITEM_PFCP_SEID] = {
4102                 .name = "seid",
4103                 .help = "session endpoint identifier",
4104                 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED),
4105                              item_param),
4106                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)),
4107         },
4108         [ITEM_ECPRI] = {
4109                 .name = "ecpri",
4110                 .help = "match eCPRI header",
4111                 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
4112                 .next = NEXT(item_ecpri),
4113                 .call = parse_vc,
4114         },
4115         [ITEM_ECPRI_COMMON] = {
4116                 .name = "common",
4117                 .help = "eCPRI common header",
4118                 .next = NEXT(item_ecpri_common),
4119         },
4120         [ITEM_ECPRI_COMMON_TYPE] = {
4121                 .name = "type",
4122                 .help = "type of common header",
4123                 .next = NEXT(item_ecpri_common_type),
4124                 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)),
4125         },
4126         [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = {
4127                 .name = "iq_data",
4128                 .help = "Type #0: IQ Data",
4129                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID,
4130                                         ITEM_NEXT)),
4131                 .call = parse_vc_item_ecpri_type,
4132         },
4133         [ITEM_ECPRI_MSG_IQ_DATA_PCID] = {
4134                 .name = "pc_id",
4135                 .help = "Physical Channel ID",
4136                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID,
4137                                 ITEM_ECPRI_COMMON, ITEM_NEXT),
4138                                 NEXT_ENTRY(COMMON_UNSIGNED), item_param),
4139                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri,
4140                                 hdr.type0.pc_id)),
4141         },
4142         [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = {
4143                 .name = "rtc_ctrl",
4144                 .help = "Type #2: Real-Time Control Data",
4145                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID,
4146                                         ITEM_NEXT)),
4147                 .call = parse_vc_item_ecpri_type,
4148         },
4149         [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = {
4150                 .name = "rtc_id",
4151                 .help = "Real-Time Control Data ID",
4152                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID,
4153                                 ITEM_ECPRI_COMMON, ITEM_NEXT),
4154                                 NEXT_ENTRY(COMMON_UNSIGNED), item_param),
4155                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri,
4156                                 hdr.type2.rtc_id)),
4157         },
4158         [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = {
4159                 .name = "delay_measure",
4160                 .help = "Type #5: One-Way Delay Measurement",
4161                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID,
4162                                         ITEM_NEXT)),
4163                 .call = parse_vc_item_ecpri_type,
4164         },
4165         [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = {
4166                 .name = "msr_id",
4167                 .help = "Measurement ID",
4168                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID,
4169                                 ITEM_ECPRI_COMMON, ITEM_NEXT),
4170                                 NEXT_ENTRY(COMMON_UNSIGNED), item_param),
4171                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri,
4172                                 hdr.type5.msr_id)),
4173         },
4174         [ITEM_GENEVE_OPT] = {
4175                 .name = "geneve-opt",
4176                 .help = "GENEVE header option",
4177                 .priv = PRIV_ITEM(GENEVE_OPT,
4178                                   sizeof(struct rte_flow_item_geneve_opt) +
4179                                   ITEM_GENEVE_OPT_DATA_SIZE),
4180                 .next = NEXT(item_geneve_opt),
4181                 .call = parse_vc,
4182         },
4183         [ITEM_GENEVE_OPT_CLASS] = {
4184                 .name = "class",
4185                 .help = "GENEVE option class",
4186                 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED),
4187                              item_param),
4188                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt,
4189                                              option_class)),
4190         },
4191         [ITEM_GENEVE_OPT_TYPE] = {
4192                 .name = "type",
4193                 .help = "GENEVE option type",
4194                 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED),
4195                              item_param),
4196                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt,
4197                                         option_type)),
4198         },
4199         [ITEM_GENEVE_OPT_LENGTH] = {
4200                 .name = "length",
4201                 .help = "GENEVE option data length (in 32b words)",
4202                 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED),
4203                              item_param),
4204                 .args = ARGS(ARGS_ENTRY_BOUNDED(
4205                                 struct rte_flow_item_geneve_opt, option_len,
4206                                 0, 31)),
4207         },
4208         [ITEM_GENEVE_OPT_DATA] = {
4209                 .name = "data",
4210                 .help = "GENEVE option data pattern",
4211                 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX),
4212                              item_param),
4213                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data),
4214                              ARGS_ENTRY_ARB(0, 0),
4215                              ARGS_ENTRY_ARB
4216                                 (sizeof(struct rte_flow_item_geneve_opt),
4217                                 ITEM_GENEVE_OPT_DATA_SIZE)),
4218         },
4219         [ITEM_INTEGRITY] = {
4220                 .name = "integrity",
4221                 .help = "match packet integrity",
4222                 .priv = PRIV_ITEM(INTEGRITY,
4223                                   sizeof(struct rte_flow_item_integrity)),
4224                 .next = NEXT(item_integrity),
4225                 .call = parse_vc,
4226         },
4227         [ITEM_INTEGRITY_LEVEL] = {
4228                 .name = "level",
4229                 .help = "integrity level",
4230                 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED),
4231                              item_param),
4232                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)),
4233         },
4234         [ITEM_INTEGRITY_VALUE] = {
4235                 .name = "value",
4236                 .help = "integrity value",
4237                 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED),
4238                              item_param),
4239                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)),
4240         },
4241         [ITEM_CONNTRACK] = {
4242                 .name = "conntrack",
4243                 .help = "conntrack state",
4244                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED),
4245                              item_param),
4246                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)),
4247         },
4248         [ITEM_PORT_REPRESENTOR] = {
4249                 .name = "port_representor",
4250                 .help = "match traffic entering the embedded switch from the given ethdev",
4251                 .priv = PRIV_ITEM(PORT_REPRESENTOR,
4252                                   sizeof(struct rte_flow_item_ethdev)),
4253                 .next = NEXT(item_port_representor),
4254                 .call = parse_vc,
4255         },
4256         [ITEM_PORT_REPRESENTOR_PORT_ID] = {
4257                 .name = "port_id",
4258                 .help = "ethdev port ID",
4259                 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED),
4260                              item_param),
4261                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
4262         },
4263         [ITEM_REPRESENTED_PORT] = {
4264                 .name = "represented_port",
4265                 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev",
4266                 .priv = PRIV_ITEM(REPRESENTED_PORT,
4267                                   sizeof(struct rte_flow_item_ethdev)),
4268                 .next = NEXT(item_represented_port),
4269                 .call = parse_vc,
4270         },
4271         [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = {
4272                 .name = "ethdev_port_id",
4273                 .help = "ethdev port ID",
4274                 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED),
4275                              item_param),
4276                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
4277         },
4278         [ITEM_FLEX] = {
4279                 .name = "flex",
4280                 .help = "match flex header",
4281                 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)),
4282                 .next = NEXT(item_flex),
4283                 .call = parse_vc,
4284         },
4285         [ITEM_FLEX_ITEM_HANDLE] = {
4286                 .name = "item",
4287                 .help = "flex item handle",
4288                 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE),
4289                              NEXT_ENTRY(ITEM_PARAM_IS)),
4290                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)),
4291         },
4292         [ITEM_FLEX_PATTERN_HANDLE] = {
4293                 .name = "pattern",
4294                 .help = "flex pattern handle",
4295                 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE),
4296                              NEXT_ENTRY(ITEM_PARAM_IS)),
4297                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)),
4298         },
4299         [ITEM_L2TPV2] = {
4300                 .name = "l2tpv2",
4301                 .help = "match L2TPv2 header",
4302                 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
4303                 .next = NEXT(item_l2tpv2),
4304                 .call = parse_vc,
4305         },
4306         [ITEM_L2TPV2_TYPE] = {
4307                 .name = "type",
4308                 .help = "type of l2tpv2",
4309                 .next = NEXT(item_l2tpv2_type),
4310                 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
4311         },
4312         [ITEM_L2TPV2_TYPE_DATA] = {
4313                 .name = "data",
4314                 .help = "Type #7: data message without any options",
4315                 .next = NEXT(item_l2tpv2_type_data),
4316                 .call = parse_vc_item_l2tpv2_type,
4317         },
4318         [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = {
4319                 .name = "tunnel_id",
4320                 .help = "tunnel identifier",
4321                 .next = NEXT(item_l2tpv2_type_data,
4322                              NEXT_ENTRY(COMMON_UNSIGNED),
4323                              item_param),
4324                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4325                                              hdr.type7.tunnel_id)),
4326         },
4327         [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = {
4328                 .name = "session_id",
4329                 .help = "session identifier",
4330                 .next = NEXT(item_l2tpv2_type_data,
4331                              NEXT_ENTRY(COMMON_UNSIGNED),
4332                              item_param),
4333                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4334                                              hdr.type7.session_id)),
4335         },
4336         [ITEM_L2TPV2_TYPE_DATA_L] = {
4337                 .name = "data_l",
4338                 .help = "Type #6: data message with length option",
4339                 .next = NEXT(item_l2tpv2_type_data_l),
4340                 .call = parse_vc_item_l2tpv2_type,
4341         },
4342         [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
4343                 .name = "length",
4344                 .help = "message length",
4345                 .next = NEXT(item_l2tpv2_type_data_l,
4346                              NEXT_ENTRY(COMMON_UNSIGNED),
4347                              item_param),
4348                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4349                                              hdr.type6.length)),
4350         },
4351         [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
4352                 .name = "tunnel_id",
4353                 .help = "tunnel identifier",
4354                 .next = NEXT(item_l2tpv2_type_data_l,
4355                              NEXT_ENTRY(COMMON_UNSIGNED),
4356                              item_param),
4357                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4358                                              hdr.type6.tunnel_id)),
4359         },
4360         [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
4361                 .name = "session_id",
4362                 .help = "session identifier",
4363                 .next = NEXT(item_l2tpv2_type_data_l,
4364                              NEXT_ENTRY(COMMON_UNSIGNED),
4365                              item_param),
4366                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4367                                              hdr.type6.session_id)),
4368         },
4369         [ITEM_L2TPV2_TYPE_DATA_S] = {
4370                 .name = "data_s",
4371                 .help = "Type #5: data message with ns, nr option",
4372                 .next = NEXT(item_l2tpv2_type_data_s),
4373                 .call = parse_vc_item_l2tpv2_type,
4374         },
4375         [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = {
4376                 .name = "tunnel_id",
4377                 .help = "tunnel identifier",
4378                 .next = NEXT(item_l2tpv2_type_data_s,
4379                              NEXT_ENTRY(COMMON_UNSIGNED),
4380                              item_param),
4381                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4382                                              hdr.type5.tunnel_id)),
4383         },
4384         [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = {
4385                 .name = "session_id",
4386                 .help = "session identifier",
4387                 .next = NEXT(item_l2tpv2_type_data_s,
4388                              NEXT_ENTRY(COMMON_UNSIGNED),
4389                              item_param),
4390                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4391                                              hdr.type5.session_id)),
4392         },
4393         [ITEM_L2TPV2_MSG_DATA_S_NS] = {
4394                 .name = "ns",
4395                 .help = "sequence number for message",
4396                 .next = NEXT(item_l2tpv2_type_data_s,
4397                              NEXT_ENTRY(COMMON_UNSIGNED),
4398                              item_param),
4399                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4400                                              hdr.type5.ns)),
4401         },
4402         [ITEM_L2TPV2_MSG_DATA_S_NR] = {
4403                 .name = "nr",
4404                 .help = "sequence number for next receive message",
4405                 .next = NEXT(item_l2tpv2_type_data_s,
4406                              NEXT_ENTRY(COMMON_UNSIGNED),
4407                              item_param),
4408                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4409                                              hdr.type5.nr)),
4410         },
4411         [ITEM_L2TPV2_TYPE_DATA_O] = {
4412                 .name = "data_o",
4413                 .help = "Type #4: data message with offset option",
4414                 .next = NEXT(item_l2tpv2_type_data_o),
4415                 .call = parse_vc_item_l2tpv2_type,
4416         },
4417         [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = {
4418                 .name = "tunnel_id",
4419                 .help = "tunnel identifier",
4420                 .next = NEXT(item_l2tpv2_type_data_o,
4421                              NEXT_ENTRY(COMMON_UNSIGNED),
4422                              item_param),
4423                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4424                                              hdr.type4.tunnel_id)),
4425         },
4426         [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = {
4427                 .name = "session_id",
4428                 .help = "session identifier",
4429                 .next = NEXT(item_l2tpv2_type_data_o,
4430                              NEXT_ENTRY(COMMON_UNSIGNED),
4431                              item_param),
4432                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4433                                              hdr.type5.session_id)),
4434         },
4435         [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = {
4436                 .name = "offset_size",
4437                 .help = "the size of offset padding",
4438                 .next = NEXT(item_l2tpv2_type_data_o,
4439                              NEXT_ENTRY(COMMON_UNSIGNED),
4440                              item_param),
4441                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4442                                              hdr.type4.offset_size)),
4443         },
4444         [ITEM_L2TPV2_TYPE_DATA_L_S] = {
4445                 .name = "data_l_s",
4446                 .help = "Type #3: data message contains length, ns, nr "
4447                         "options",
4448                 .next = NEXT(item_l2tpv2_type_data_l_s),
4449                 .call = parse_vc_item_l2tpv2_type,
4450         },
4451         [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = {
4452                 .name = "length",
4453                 .help = "message length",
4454                 .next = NEXT(item_l2tpv2_type_data_l_s,
4455                              NEXT_ENTRY(COMMON_UNSIGNED),
4456                              item_param),
4457                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4458                                              hdr.type3.length)),
4459         },
4460         [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = {
4461                 .name = "tunnel_id",
4462                 .help = "tunnel identifier",
4463                 .next = NEXT(item_l2tpv2_type_data_l_s,
4464                              NEXT_ENTRY(COMMON_UNSIGNED),
4465                              item_param),
4466                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4467                                              hdr.type3.tunnel_id)),
4468         },
4469         [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = {
4470                 .name = "session_id",
4471                 .help = "session identifier",
4472                 .next = NEXT(item_l2tpv2_type_data_l_s,
4473                              NEXT_ENTRY(COMMON_UNSIGNED),
4474                              item_param),
4475                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4476                                              hdr.type3.session_id)),
4477         },
4478         [ITEM_L2TPV2_MSG_DATA_L_S_NS] = {
4479                 .name = "ns",
4480                 .help = "sequence number for message",
4481                 .next = NEXT(item_l2tpv2_type_data_l_s,
4482                              NEXT_ENTRY(COMMON_UNSIGNED),
4483                              item_param),
4484                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4485                                              hdr.type3.ns)),
4486         },
4487         [ITEM_L2TPV2_MSG_DATA_L_S_NR] = {
4488                 .name = "nr",
4489                 .help = "sequence number for next receive message",
4490                 .next = NEXT(item_l2tpv2_type_data_l_s,
4491                              NEXT_ENTRY(COMMON_UNSIGNED),
4492                              item_param),
4493                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4494                                              hdr.type3.nr)),
4495         },
4496         [ITEM_L2TPV2_TYPE_CTRL] = {
4497                 .name = "control",
4498                 .help = "Type #3: conrtol message contains length, ns, nr "
4499                         "options",
4500                 .next = NEXT(item_l2tpv2_type_ctrl),
4501                 .call = parse_vc_item_l2tpv2_type,
4502         },
4503         [ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
4504                 .name = "length",
4505                 .help = "message length",
4506                 .next = NEXT(item_l2tpv2_type_ctrl,
4507                              NEXT_ENTRY(COMMON_UNSIGNED),
4508                              item_param),
4509                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4510                                              hdr.type3.length)),
4511         },
4512         [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
4513                 .name = "tunnel_id",
4514                 .help = "tunnel identifier",
4515                 .next = NEXT(item_l2tpv2_type_ctrl,
4516                              NEXT_ENTRY(COMMON_UNSIGNED),
4517                              item_param),
4518                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4519                                              hdr.type3.tunnel_id)),
4520         },
4521         [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
4522                 .name = "session_id",
4523                 .help = "session identifier",
4524                 .next = NEXT(item_l2tpv2_type_ctrl,
4525                              NEXT_ENTRY(COMMON_UNSIGNED),
4526                              item_param),
4527                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4528                                              hdr.type3.session_id)),
4529         },
4530         [ITEM_L2TPV2_MSG_CTRL_NS] = {
4531                 .name = "ns",
4532                 .help = "sequence number for message",
4533                 .next = NEXT(item_l2tpv2_type_ctrl,
4534                              NEXT_ENTRY(COMMON_UNSIGNED),
4535                              item_param),
4536                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4537                                              hdr.type3.ns)),
4538         },
4539         [ITEM_L2TPV2_MSG_CTRL_NR] = {
4540                 .name = "nr",
4541                 .help = "sequence number for next receive message",
4542                 .next = NEXT(item_l2tpv2_type_ctrl,
4543                              NEXT_ENTRY(COMMON_UNSIGNED),
4544                              item_param),
4545                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
4546                                              hdr.type3.nr)),
4547         },
4548         [ITEM_PPP] = {
4549                 .name = "ppp",
4550                 .help = "match PPP header",
4551                 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
4552                 .next = NEXT(item_ppp),
4553                 .call = parse_vc,
4554         },
4555         [ITEM_PPP_ADDR] = {
4556                 .name = "addr",
4557                 .help = "PPP address",
4558                 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
4559                              item_param),
4560                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)),
4561         },
4562         [ITEM_PPP_CTRL] = {
4563                 .name = "ctrl",
4564                 .help = "PPP control",
4565                 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
4566                              item_param),
4567                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)),
4568         },
4569         [ITEM_PPP_PROTO_ID] = {
4570                 .name = "proto_id",
4571                 .help = "PPP protocol identifier",
4572                 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
4573                              item_param),
4574                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp,
4575                                         hdr.proto_id)),
4576         },
4577         /* Validate/create actions. */
4578         [ACTIONS] = {
4579                 .name = "actions",
4580                 .help = "submit a list of associated actions",
4581                 .next = NEXT(next_action),
4582                 .call = parse_vc,
4583         },
4584         [ACTION_NEXT] = {
4585                 .name = "/",
4586                 .help = "specify next action",
4587                 .next = NEXT(next_action),
4588         },
4589         [ACTION_END] = {
4590                 .name = "end",
4591                 .help = "end list of actions",
4592                 .priv = PRIV_ACTION(END, 0),
4593                 .call = parse_vc,
4594         },
4595         [ACTION_VOID] = {
4596                 .name = "void",
4597                 .help = "no-op action",
4598                 .priv = PRIV_ACTION(VOID, 0),
4599                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4600                 .call = parse_vc,
4601         },
4602         [ACTION_PASSTHRU] = {
4603                 .name = "passthru",
4604                 .help = "let subsequent rule process matched packets",
4605                 .priv = PRIV_ACTION(PASSTHRU, 0),
4606                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4607                 .call = parse_vc,
4608         },
4609         [ACTION_JUMP] = {
4610                 .name = "jump",
4611                 .help = "redirect traffic to a given group",
4612                 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)),
4613                 .next = NEXT(action_jump),
4614                 .call = parse_vc,
4615         },
4616         [ACTION_JUMP_GROUP] = {
4617                 .name = "group",
4618                 .help = "group to redirect traffic to",
4619                 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)),
4620                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)),
4621                 .call = parse_vc_conf,
4622         },
4623         [ACTION_MARK] = {
4624                 .name = "mark",
4625                 .help = "attach 32 bit value to packets",
4626                 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
4627                 .next = NEXT(action_mark),
4628                 .call = parse_vc,
4629         },
4630         [ACTION_MARK_ID] = {
4631                 .name = "id",
4632                 .help = "32 bit value to return with packets",
4633                 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)),
4634                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)),
4635                 .call = parse_vc_conf,
4636         },
4637         [ACTION_FLAG] = {
4638                 .name = "flag",
4639                 .help = "flag packets",
4640                 .priv = PRIV_ACTION(FLAG, 0),
4641                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4642                 .call = parse_vc,
4643         },
4644         [ACTION_QUEUE] = {
4645                 .name = "queue",
4646                 .help = "assign packets to a given queue index",
4647                 .priv = PRIV_ACTION(QUEUE,
4648                                     sizeof(struct rte_flow_action_queue)),
4649                 .next = NEXT(action_queue),
4650                 .call = parse_vc,
4651         },
4652         [ACTION_QUEUE_INDEX] = {
4653                 .name = "index",
4654                 .help = "queue index to use",
4655                 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)),
4656                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
4657                 .call = parse_vc_conf,
4658         },
4659         [ACTION_DROP] = {
4660                 .name = "drop",
4661                 .help = "drop packets (note: passthru has priority)",
4662                 .priv = PRIV_ACTION(DROP, 0),
4663                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4664                 .call = parse_vc,
4665         },
4666         [ACTION_COUNT] = {
4667                 .name = "count",
4668                 .help = "enable counters for this rule",
4669                 .priv = PRIV_ACTION(COUNT,
4670                                     sizeof(struct rte_flow_action_count)),
4671                 .next = NEXT(action_count),
4672                 .call = parse_vc,
4673         },
4674         [ACTION_COUNT_ID] = {
4675                 .name = "identifier",
4676                 .help = "counter identifier to use",
4677                 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)),
4678                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)),
4679                 .call = parse_vc_conf,
4680         },
4681         [ACTION_RSS] = {
4682                 .name = "rss",
4683                 .help = "spread packets among several queues",
4684                 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)),
4685                 .next = NEXT(action_rss),
4686                 .call = parse_vc_action_rss,
4687         },
4688         [ACTION_RSS_FUNC] = {
4689                 .name = "func",
4690                 .help = "RSS hash function to apply",
4691                 .next = NEXT(action_rss,
4692                              NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT,
4693                                         ACTION_RSS_FUNC_TOEPLITZ,
4694                                         ACTION_RSS_FUNC_SIMPLE_XOR,
4695                                         ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)),
4696         },
4697         [ACTION_RSS_FUNC_DEFAULT] = {
4698                 .name = "default",
4699                 .help = "default hash function",
4700                 .call = parse_vc_action_rss_func,
4701         },
4702         [ACTION_RSS_FUNC_TOEPLITZ] = {
4703                 .name = "toeplitz",
4704                 .help = "Toeplitz hash function",
4705                 .call = parse_vc_action_rss_func,
4706         },
4707         [ACTION_RSS_FUNC_SIMPLE_XOR] = {
4708                 .name = "simple_xor",
4709                 .help = "simple XOR hash function",
4710                 .call = parse_vc_action_rss_func,
4711         },
4712         [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = {
4713                 .name = "symmetric_toeplitz",
4714                 .help = "Symmetric Toeplitz hash function",
4715                 .call = parse_vc_action_rss_func,
4716         },
4717         [ACTION_RSS_LEVEL] = {
4718                 .name = "level",
4719                 .help = "encapsulation level for \"types\"",
4720                 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)),
4721                 .args = ARGS(ARGS_ENTRY_ARB
4722                              (offsetof(struct action_rss_data, conf) +
4723                               offsetof(struct rte_flow_action_rss, level),
4724                               sizeof(((struct rte_flow_action_rss *)0)->
4725                                      level))),
4726         },
4727         [ACTION_RSS_TYPES] = {
4728                 .name = "types",
4729                 .help = "specific RSS hash types",
4730                 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)),
4731         },
4732         [ACTION_RSS_TYPE] = {
4733                 .name = "{type}",
4734                 .help = "RSS hash type",
4735                 .call = parse_vc_action_rss_type,
4736                 .comp = comp_vc_action_rss_type,
4737         },
4738         [ACTION_RSS_KEY] = {
4739                 .name = "key",
4740                 .help = "RSS hash key",
4741                 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)),
4742                 .args = ARGS(ARGS_ENTRY_ARB
4743                              (offsetof(struct action_rss_data, conf) +
4744                               offsetof(struct rte_flow_action_rss, key),
4745                               sizeof(((struct rte_flow_action_rss *)0)->key)),
4746                              ARGS_ENTRY_ARB
4747                              (offsetof(struct action_rss_data, conf) +
4748                               offsetof(struct rte_flow_action_rss, key_len),
4749                               sizeof(((struct rte_flow_action_rss *)0)->
4750                                      key_len)),
4751                              ARGS_ENTRY(struct action_rss_data, key)),
4752         },
4753         [ACTION_RSS_KEY_LEN] = {
4754                 .name = "key_len",
4755                 .help = "RSS hash key length in bytes",
4756                 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)),
4757                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
4758                              (offsetof(struct action_rss_data, conf) +
4759                               offsetof(struct rte_flow_action_rss, key_len),
4760                               sizeof(((struct rte_flow_action_rss *)0)->
4761                                      key_len),
4762                               0,
4763                               RSS_HASH_KEY_LENGTH)),
4764         },
4765         [ACTION_RSS_QUEUES] = {
4766                 .name = "queues",
4767                 .help = "queue indices to use",
4768                 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)),
4769                 .call = parse_vc_conf,
4770         },
4771         [ACTION_RSS_QUEUE] = {
4772                 .name = "{queue}",
4773                 .help = "queue index",
4774                 .call = parse_vc_action_rss_queue,
4775                 .comp = comp_vc_action_rss_queue,
4776         },
4777         [ACTION_PF] = {
4778                 .name = "pf",
4779                 .help = "direct traffic to physical function",
4780                 .priv = PRIV_ACTION(PF, 0),
4781                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4782                 .call = parse_vc,
4783         },
4784         [ACTION_VF] = {
4785                 .name = "vf",
4786                 .help = "direct traffic to a virtual function ID",
4787                 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)),
4788                 .next = NEXT(action_vf),
4789                 .call = parse_vc,
4790         },
4791         [ACTION_VF_ORIGINAL] = {
4792                 .name = "original",
4793                 .help = "use original VF ID if possible",
4794                 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)),
4795                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf,
4796                                            original, 1)),
4797                 .call = parse_vc_conf,
4798         },
4799         [ACTION_VF_ID] = {
4800                 .name = "id",
4801                 .help = "VF ID",
4802                 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)),
4803                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)),
4804                 .call = parse_vc_conf,
4805         },
4806         [ACTION_PHY_PORT] = {
4807                 .name = "phy_port",
4808                 .help = "direct packets to physical port index",
4809                 .priv = PRIV_ACTION(PHY_PORT,
4810                                     sizeof(struct rte_flow_action_phy_port)),
4811                 .next = NEXT(action_phy_port),
4812                 .call = parse_vc,
4813         },
4814         [ACTION_PHY_PORT_ORIGINAL] = {
4815                 .name = "original",
4816                 .help = "use original port index if possible",
4817                 .next = NEXT(action_phy_port, NEXT_ENTRY(COMMON_BOOLEAN)),
4818                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_phy_port,
4819                                            original, 1)),
4820                 .call = parse_vc_conf,
4821         },
4822         [ACTION_PHY_PORT_INDEX] = {
4823                 .name = "index",
4824                 .help = "physical port index",
4825                 .next = NEXT(action_phy_port, NEXT_ENTRY(COMMON_UNSIGNED)),
4826                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_phy_port,
4827                                         index)),
4828                 .call = parse_vc_conf,
4829         },
4830         [ACTION_PORT_ID] = {
4831                 .name = "port_id",
4832                 .help = "direct matching traffic to a given DPDK port ID",
4833                 .priv = PRIV_ACTION(PORT_ID,
4834                                     sizeof(struct rte_flow_action_port_id)),
4835                 .next = NEXT(action_port_id),
4836                 .call = parse_vc,
4837         },
4838         [ACTION_PORT_ID_ORIGINAL] = {
4839                 .name = "original",
4840                 .help = "use original DPDK port ID if possible",
4841                 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)),
4842                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id,
4843                                            original, 1)),
4844                 .call = parse_vc_conf,
4845         },
4846         [ACTION_PORT_ID_ID] = {
4847                 .name = "id",
4848                 .help = "DPDK port ID",
4849                 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)),
4850                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)),
4851                 .call = parse_vc_conf,
4852         },
4853         [ACTION_METER] = {
4854                 .name = "meter",
4855                 .help = "meter the directed packets at given id",
4856                 .priv = PRIV_ACTION(METER,
4857                                     sizeof(struct rte_flow_action_meter)),
4858                 .next = NEXT(action_meter),
4859                 .call = parse_vc,
4860         },
4861         [ACTION_METER_COLOR] = {
4862                 .name = "color",
4863                 .help = "meter color for the packets",
4864                 .priv = PRIV_ACTION(METER_COLOR,
4865                                 sizeof(struct rte_flow_action_meter_color)),
4866                 .next = NEXT(action_meter_color),
4867                 .call = parse_vc,
4868         },
4869         [ACTION_METER_COLOR_TYPE] = {
4870                 .name = "type",
4871                 .help = "specific meter color",
4872                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT),
4873                                 NEXT_ENTRY(ACTION_METER_COLOR_GREEN,
4874                                         ACTION_METER_COLOR_YELLOW,
4875                                         ACTION_METER_COLOR_RED)),
4876         },
4877         [ACTION_METER_COLOR_GREEN] = {
4878                 .name = "green",
4879                 .help = "meter color green",
4880                 .call = parse_vc_action_meter_color_type,
4881         },
4882         [ACTION_METER_COLOR_YELLOW] = {
4883                 .name = "yellow",
4884                 .help = "meter color yellow",
4885                 .call = parse_vc_action_meter_color_type,
4886         },
4887         [ACTION_METER_COLOR_RED] = {
4888                 .name = "red",
4889                 .help = "meter color red",
4890                 .call = parse_vc_action_meter_color_type,
4891         },
4892         [ACTION_METER_ID] = {
4893                 .name = "mtr_id",
4894                 .help = "meter id to use",
4895                 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)),
4896                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)),
4897                 .call = parse_vc_conf,
4898         },
4899         [ACTION_OF_SET_MPLS_TTL] = {
4900                 .name = "of_set_mpls_ttl",
4901                 .help = "OpenFlow's OFPAT_SET_MPLS_TTL",
4902                 .priv = PRIV_ACTION
4903                         (OF_SET_MPLS_TTL,
4904                          sizeof(struct rte_flow_action_of_set_mpls_ttl)),
4905                 .next = NEXT(action_of_set_mpls_ttl),
4906                 .call = parse_vc,
4907         },
4908         [ACTION_OF_SET_MPLS_TTL_MPLS_TTL] = {
4909                 .name = "mpls_ttl",
4910                 .help = "MPLS TTL",
4911                 .next = NEXT(action_of_set_mpls_ttl,
4912                              NEXT_ENTRY(COMMON_UNSIGNED)),
4913                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_set_mpls_ttl,
4914                                         mpls_ttl)),
4915                 .call = parse_vc_conf,
4916         },
4917         [ACTION_OF_DEC_MPLS_TTL] = {
4918                 .name = "of_dec_mpls_ttl",
4919                 .help = "OpenFlow's OFPAT_DEC_MPLS_TTL",
4920                 .priv = PRIV_ACTION(OF_DEC_MPLS_TTL, 0),
4921                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4922                 .call = parse_vc,
4923         },
4924         [ACTION_OF_SET_NW_TTL] = {
4925                 .name = "of_set_nw_ttl",
4926                 .help = "OpenFlow's OFPAT_SET_NW_TTL",
4927                 .priv = PRIV_ACTION
4928                         (OF_SET_NW_TTL,
4929                          sizeof(struct rte_flow_action_of_set_nw_ttl)),
4930                 .next = NEXT(action_of_set_nw_ttl),
4931                 .call = parse_vc,
4932         },
4933         [ACTION_OF_SET_NW_TTL_NW_TTL] = {
4934                 .name = "nw_ttl",
4935                 .help = "IP TTL",
4936                 .next = NEXT(action_of_set_nw_ttl, NEXT_ENTRY(COMMON_UNSIGNED)),
4937                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_set_nw_ttl,
4938                                         nw_ttl)),
4939                 .call = parse_vc_conf,
4940         },
4941         [ACTION_OF_DEC_NW_TTL] = {
4942                 .name = "of_dec_nw_ttl",
4943                 .help = "OpenFlow's OFPAT_DEC_NW_TTL",
4944                 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0),
4945                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4946                 .call = parse_vc,
4947         },
4948         [ACTION_OF_COPY_TTL_OUT] = {
4949                 .name = "of_copy_ttl_out",
4950                 .help = "OpenFlow's OFPAT_COPY_TTL_OUT",
4951                 .priv = PRIV_ACTION(OF_COPY_TTL_OUT, 0),
4952                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4953                 .call = parse_vc,
4954         },
4955         [ACTION_OF_COPY_TTL_IN] = {
4956                 .name = "of_copy_ttl_in",
4957                 .help = "OpenFlow's OFPAT_COPY_TTL_IN",
4958                 .priv = PRIV_ACTION(OF_COPY_TTL_IN, 0),
4959                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4960                 .call = parse_vc,
4961         },
4962         [ACTION_OF_POP_VLAN] = {
4963                 .name = "of_pop_vlan",
4964                 .help = "OpenFlow's OFPAT_POP_VLAN",
4965                 .priv = PRIV_ACTION(OF_POP_VLAN, 0),
4966                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4967                 .call = parse_vc,
4968         },
4969         [ACTION_OF_PUSH_VLAN] = {
4970                 .name = "of_push_vlan",
4971                 .help = "OpenFlow's OFPAT_PUSH_VLAN",
4972                 .priv = PRIV_ACTION
4973                         (OF_PUSH_VLAN,
4974                          sizeof(struct rte_flow_action_of_push_vlan)),
4975                 .next = NEXT(action_of_push_vlan),
4976                 .call = parse_vc,
4977         },
4978         [ACTION_OF_PUSH_VLAN_ETHERTYPE] = {
4979                 .name = "ethertype",
4980                 .help = "EtherType",
4981                 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)),
4982                 .args = ARGS(ARGS_ENTRY_HTON
4983                              (struct rte_flow_action_of_push_vlan,
4984                               ethertype)),
4985                 .call = parse_vc_conf,
4986         },
4987         [ACTION_OF_SET_VLAN_VID] = {
4988                 .name = "of_set_vlan_vid",
4989                 .help = "OpenFlow's OFPAT_SET_VLAN_VID",
4990                 .priv = PRIV_ACTION
4991                         (OF_SET_VLAN_VID,
4992                          sizeof(struct rte_flow_action_of_set_vlan_vid)),
4993                 .next = NEXT(action_of_set_vlan_vid),
4994                 .call = parse_vc,
4995         },
4996         [ACTION_OF_SET_VLAN_VID_VLAN_VID] = {
4997                 .name = "vlan_vid",
4998                 .help = "VLAN id",
4999                 .next = NEXT(action_of_set_vlan_vid,
5000                              NEXT_ENTRY(COMMON_UNSIGNED)),
5001                 .args = ARGS(ARGS_ENTRY_HTON
5002                              (struct rte_flow_action_of_set_vlan_vid,
5003                               vlan_vid)),
5004                 .call = parse_vc_conf,
5005         },
5006         [ACTION_OF_SET_VLAN_PCP] = {
5007                 .name = "of_set_vlan_pcp",
5008                 .help = "OpenFlow's OFPAT_SET_VLAN_PCP",
5009                 .priv = PRIV_ACTION
5010                         (OF_SET_VLAN_PCP,
5011                          sizeof(struct rte_flow_action_of_set_vlan_pcp)),
5012                 .next = NEXT(action_of_set_vlan_pcp),
5013                 .call = parse_vc,
5014         },
5015         [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = {
5016                 .name = "vlan_pcp",
5017                 .help = "VLAN priority",
5018                 .next = NEXT(action_of_set_vlan_pcp,
5019                              NEXT_ENTRY(COMMON_UNSIGNED)),
5020                 .args = ARGS(ARGS_ENTRY_HTON
5021                              (struct rte_flow_action_of_set_vlan_pcp,
5022                               vlan_pcp)),
5023                 .call = parse_vc_conf,
5024         },
5025         [ACTION_OF_POP_MPLS] = {
5026                 .name = "of_pop_mpls",
5027                 .help = "OpenFlow's OFPAT_POP_MPLS",
5028                 .priv = PRIV_ACTION(OF_POP_MPLS,
5029                                     sizeof(struct rte_flow_action_of_pop_mpls)),
5030                 .next = NEXT(action_of_pop_mpls),
5031                 .call = parse_vc,
5032         },
5033         [ACTION_OF_POP_MPLS_ETHERTYPE] = {
5034                 .name = "ethertype",
5035                 .help = "EtherType",
5036                 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)),
5037                 .args = ARGS(ARGS_ENTRY_HTON
5038                              (struct rte_flow_action_of_pop_mpls,
5039                               ethertype)),
5040                 .call = parse_vc_conf,
5041         },
5042         [ACTION_OF_PUSH_MPLS] = {
5043                 .name = "of_push_mpls",
5044                 .help = "OpenFlow's OFPAT_PUSH_MPLS",
5045                 .priv = PRIV_ACTION
5046                         (OF_PUSH_MPLS,
5047                          sizeof(struct rte_flow_action_of_push_mpls)),
5048                 .next = NEXT(action_of_push_mpls),
5049                 .call = parse_vc,
5050         },
5051         [ACTION_OF_PUSH_MPLS_ETHERTYPE] = {
5052                 .name = "ethertype",
5053                 .help = "EtherType",
5054                 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)),
5055                 .args = ARGS(ARGS_ENTRY_HTON
5056                              (struct rte_flow_action_of_push_mpls,
5057                               ethertype)),
5058                 .call = parse_vc_conf,
5059         },
5060         [ACTION_VXLAN_ENCAP] = {
5061                 .name = "vxlan_encap",
5062                 .help = "VXLAN encapsulation, uses configuration set by \"set"
5063                         " vxlan\"",
5064                 .priv = PRIV_ACTION(VXLAN_ENCAP,
5065                                     sizeof(struct action_vxlan_encap_data)),
5066                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5067                 .call = parse_vc_action_vxlan_encap,
5068         },
5069         [ACTION_VXLAN_DECAP] = {
5070                 .name = "vxlan_decap",
5071                 .help = "Performs a decapsulation action by stripping all"
5072                         " headers of the VXLAN tunnel network overlay from the"
5073                         " matched flow.",
5074                 .priv = PRIV_ACTION(VXLAN_DECAP, 0),
5075                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5076                 .call = parse_vc,
5077         },
5078         [ACTION_NVGRE_ENCAP] = {
5079                 .name = "nvgre_encap",
5080                 .help = "NVGRE encapsulation, uses configuration set by \"set"
5081                         " nvgre\"",
5082                 .priv = PRIV_ACTION(NVGRE_ENCAP,
5083                                     sizeof(struct action_nvgre_encap_data)),
5084                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5085                 .call = parse_vc_action_nvgre_encap,
5086         },
5087         [ACTION_NVGRE_DECAP] = {
5088                 .name = "nvgre_decap",
5089                 .help = "Performs a decapsulation action by stripping all"
5090                         " headers of the NVGRE tunnel network overlay from the"
5091                         " matched flow.",
5092                 .priv = PRIV_ACTION(NVGRE_DECAP, 0),
5093                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5094                 .call = parse_vc,
5095         },
5096         [ACTION_L2_ENCAP] = {
5097                 .name = "l2_encap",
5098                 .help = "l2 encap, uses configuration set by"
5099                         " \"set l2_encap\"",
5100                 .priv = PRIV_ACTION(RAW_ENCAP,
5101                                     sizeof(struct action_raw_encap_data)),
5102                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5103                 .call = parse_vc_action_l2_encap,
5104         },
5105         [ACTION_L2_DECAP] = {
5106                 .name = "l2_decap",
5107                 .help = "l2 decap, uses configuration set by"
5108                         " \"set l2_decap\"",
5109                 .priv = PRIV_ACTION(RAW_DECAP,
5110                                     sizeof(struct action_raw_decap_data)),
5111                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5112                 .call = parse_vc_action_l2_decap,
5113         },
5114         [ACTION_MPLSOGRE_ENCAP] = {
5115                 .name = "mplsogre_encap",
5116                 .help = "mplsogre encapsulation, uses configuration set by"
5117                         " \"set mplsogre_encap\"",
5118                 .priv = PRIV_ACTION(RAW_ENCAP,
5119                                     sizeof(struct action_raw_encap_data)),
5120                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5121                 .call = parse_vc_action_mplsogre_encap,
5122         },
5123         [ACTION_MPLSOGRE_DECAP] = {
5124                 .name = "mplsogre_decap",
5125                 .help = "mplsogre decapsulation, uses configuration set by"
5126                         " \"set mplsogre_decap\"",
5127                 .priv = PRIV_ACTION(RAW_DECAP,
5128                                     sizeof(struct action_raw_decap_data)),
5129                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5130                 .call = parse_vc_action_mplsogre_decap,
5131         },
5132         [ACTION_MPLSOUDP_ENCAP] = {
5133                 .name = "mplsoudp_encap",
5134                 .help = "mplsoudp encapsulation, uses configuration set by"
5135                         " \"set mplsoudp_encap\"",
5136                 .priv = PRIV_ACTION(RAW_ENCAP,
5137                                     sizeof(struct action_raw_encap_data)),
5138                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5139                 .call = parse_vc_action_mplsoudp_encap,
5140         },
5141         [ACTION_MPLSOUDP_DECAP] = {
5142                 .name = "mplsoudp_decap",
5143                 .help = "mplsoudp decapsulation, uses configuration set by"
5144                         " \"set mplsoudp_decap\"",
5145                 .priv = PRIV_ACTION(RAW_DECAP,
5146                                     sizeof(struct action_raw_decap_data)),
5147                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5148                 .call = parse_vc_action_mplsoudp_decap,
5149         },
5150         [ACTION_SET_IPV4_SRC] = {
5151                 .name = "set_ipv4_src",
5152                 .help = "Set a new IPv4 source address in the outermost"
5153                         " IPv4 header",
5154                 .priv = PRIV_ACTION(SET_IPV4_SRC,
5155                         sizeof(struct rte_flow_action_set_ipv4)),
5156                 .next = NEXT(action_set_ipv4_src),
5157                 .call = parse_vc,
5158         },
5159         [ACTION_SET_IPV4_SRC_IPV4_SRC] = {
5160                 .name = "ipv4_addr",
5161                 .help = "new IPv4 source address to set",
5162                 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)),
5163                 .args = ARGS(ARGS_ENTRY_HTON
5164                         (struct rte_flow_action_set_ipv4, ipv4_addr)),
5165                 .call = parse_vc_conf,
5166         },
5167         [ACTION_SET_IPV4_DST] = {
5168                 .name = "set_ipv4_dst",
5169                 .help = "Set a new IPv4 destination address in the outermost"
5170                         " IPv4 header",
5171                 .priv = PRIV_ACTION(SET_IPV4_DST,
5172                         sizeof(struct rte_flow_action_set_ipv4)),
5173                 .next = NEXT(action_set_ipv4_dst),
5174                 .call = parse_vc,
5175         },
5176         [ACTION_SET_IPV4_DST_IPV4_DST] = {
5177                 .name = "ipv4_addr",
5178                 .help = "new IPv4 destination address to set",
5179                 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)),
5180                 .args = ARGS(ARGS_ENTRY_HTON
5181                         (struct rte_flow_action_set_ipv4, ipv4_addr)),
5182                 .call = parse_vc_conf,
5183         },
5184         [ACTION_SET_IPV6_SRC] = {
5185                 .name = "set_ipv6_src",
5186                 .help = "Set a new IPv6 source address in the outermost"
5187                         " IPv6 header",
5188                 .priv = PRIV_ACTION(SET_IPV6_SRC,
5189                         sizeof(struct rte_flow_action_set_ipv6)),
5190                 .next = NEXT(action_set_ipv6_src),
5191                 .call = parse_vc,
5192         },
5193         [ACTION_SET_IPV6_SRC_IPV6_SRC] = {
5194                 .name = "ipv6_addr",
5195                 .help = "new IPv6 source address to set",
5196                 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)),
5197                 .args = ARGS(ARGS_ENTRY_HTON
5198                         (struct rte_flow_action_set_ipv6, ipv6_addr)),
5199                 .call = parse_vc_conf,
5200         },
5201         [ACTION_SET_IPV6_DST] = {
5202                 .name = "set_ipv6_dst",
5203                 .help = "Set a new IPv6 destination address in the outermost"
5204                         " IPv6 header",
5205                 .priv = PRIV_ACTION(SET_IPV6_DST,
5206                         sizeof(struct rte_flow_action_set_ipv6)),
5207                 .next = NEXT(action_set_ipv6_dst),
5208                 .call = parse_vc,
5209         },
5210         [ACTION_SET_IPV6_DST_IPV6_DST] = {
5211                 .name = "ipv6_addr",
5212                 .help = "new IPv6 destination address to set",
5213                 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)),
5214                 .args = ARGS(ARGS_ENTRY_HTON
5215                         (struct rte_flow_action_set_ipv6, ipv6_addr)),
5216                 .call = parse_vc_conf,
5217         },
5218         [ACTION_SET_TP_SRC] = {
5219                 .name = "set_tp_src",
5220                 .help = "set a new source port number in the outermost"
5221                         " TCP/UDP header",
5222                 .priv = PRIV_ACTION(SET_TP_SRC,
5223                         sizeof(struct rte_flow_action_set_tp)),
5224                 .next = NEXT(action_set_tp_src),
5225                 .call = parse_vc,
5226         },
5227         [ACTION_SET_TP_SRC_TP_SRC] = {
5228                 .name = "port",
5229                 .help = "new source port number to set",
5230                 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)),
5231                 .args = ARGS(ARGS_ENTRY_HTON
5232                              (struct rte_flow_action_set_tp, port)),
5233                 .call = parse_vc_conf,
5234         },
5235         [ACTION_SET_TP_DST] = {
5236                 .name = "set_tp_dst",
5237                 .help = "set a new destination port number in the outermost"
5238                         " TCP/UDP header",
5239                 .priv = PRIV_ACTION(SET_TP_DST,
5240                         sizeof(struct rte_flow_action_set_tp)),
5241                 .next = NEXT(action_set_tp_dst),
5242                 .call = parse_vc,
5243         },
5244         [ACTION_SET_TP_DST_TP_DST] = {
5245                 .name = "port",
5246                 .help = "new destination port number to set",
5247                 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)),
5248                 .args = ARGS(ARGS_ENTRY_HTON
5249                              (struct rte_flow_action_set_tp, port)),
5250                 .call = parse_vc_conf,
5251         },
5252         [ACTION_MAC_SWAP] = {
5253                 .name = "mac_swap",
5254                 .help = "Swap the source and destination MAC addresses"
5255                         " in the outermost Ethernet header",
5256                 .priv = PRIV_ACTION(MAC_SWAP, 0),
5257                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5258                 .call = parse_vc,
5259         },
5260         [ACTION_DEC_TTL] = {
5261                 .name = "dec_ttl",
5262                 .help = "decrease network TTL if available",
5263                 .priv = PRIV_ACTION(DEC_TTL, 0),
5264                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5265                 .call = parse_vc,
5266         },
5267         [ACTION_SET_TTL] = {
5268                 .name = "set_ttl",
5269                 .help = "set ttl value",
5270                 .priv = PRIV_ACTION(SET_TTL,
5271                         sizeof(struct rte_flow_action_set_ttl)),
5272                 .next = NEXT(action_set_ttl),
5273                 .call = parse_vc,
5274         },
5275         [ACTION_SET_TTL_TTL] = {
5276                 .name = "ttl_value",
5277                 .help = "new ttl value to set",
5278                 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)),
5279                 .args = ARGS(ARGS_ENTRY_HTON
5280                              (struct rte_flow_action_set_ttl, ttl_value)),
5281                 .call = parse_vc_conf,
5282         },
5283         [ACTION_SET_MAC_SRC] = {
5284                 .name = "set_mac_src",
5285                 .help = "set source mac address",
5286                 .priv = PRIV_ACTION(SET_MAC_SRC,
5287                         sizeof(struct rte_flow_action_set_mac)),
5288                 .next = NEXT(action_set_mac_src),
5289                 .call = parse_vc,
5290         },
5291         [ACTION_SET_MAC_SRC_MAC_SRC] = {
5292                 .name = "mac_addr",
5293                 .help = "new source mac address",
5294                 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)),
5295                 .args = ARGS(ARGS_ENTRY_HTON
5296                              (struct rte_flow_action_set_mac, mac_addr)),
5297                 .call = parse_vc_conf,
5298         },
5299         [ACTION_SET_MAC_DST] = {
5300                 .name = "set_mac_dst",
5301                 .help = "set destination mac address",
5302                 .priv = PRIV_ACTION(SET_MAC_DST,
5303                         sizeof(struct rte_flow_action_set_mac)),
5304                 .next = NEXT(action_set_mac_dst),
5305                 .call = parse_vc,
5306         },
5307         [ACTION_SET_MAC_DST_MAC_DST] = {
5308                 .name = "mac_addr",
5309                 .help = "new destination mac address to set",
5310                 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)),
5311                 .args = ARGS(ARGS_ENTRY_HTON
5312                              (struct rte_flow_action_set_mac, mac_addr)),
5313                 .call = parse_vc_conf,
5314         },
5315         [ACTION_INC_TCP_SEQ] = {
5316                 .name = "inc_tcp_seq",
5317                 .help = "increase TCP sequence number",
5318                 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)),
5319                 .next = NEXT(action_inc_tcp_seq),
5320                 .call = parse_vc,
5321         },
5322         [ACTION_INC_TCP_SEQ_VALUE] = {
5323                 .name = "value",
5324                 .help = "the value to increase TCP sequence number by",
5325                 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)),
5326                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
5327                 .call = parse_vc_conf,
5328         },
5329         [ACTION_DEC_TCP_SEQ] = {
5330                 .name = "dec_tcp_seq",
5331                 .help = "decrease TCP sequence number",
5332                 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)),
5333                 .next = NEXT(action_dec_tcp_seq),
5334                 .call = parse_vc,
5335         },
5336         [ACTION_DEC_TCP_SEQ_VALUE] = {
5337                 .name = "value",
5338                 .help = "the value to decrease TCP sequence number by",
5339                 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)),
5340                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
5341                 .call = parse_vc_conf,
5342         },
5343         [ACTION_INC_TCP_ACK] = {
5344                 .name = "inc_tcp_ack",
5345                 .help = "increase TCP acknowledgment number",
5346                 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)),
5347                 .next = NEXT(action_inc_tcp_ack),
5348                 .call = parse_vc,
5349         },
5350         [ACTION_INC_TCP_ACK_VALUE] = {
5351                 .name = "value",
5352                 .help = "the value to increase TCP acknowledgment number by",
5353                 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)),
5354                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
5355                 .call = parse_vc_conf,
5356         },
5357         [ACTION_DEC_TCP_ACK] = {
5358                 .name = "dec_tcp_ack",
5359                 .help = "decrease TCP acknowledgment number",
5360                 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
5361                 .next = NEXT(action_dec_tcp_ack),
5362                 .call = parse_vc,
5363         },
5364         [ACTION_DEC_TCP_ACK_VALUE] = {
5365                 .name = "value",
5366                 .help = "the value to decrease TCP acknowledgment number by",
5367                 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)),
5368                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
5369                 .call = parse_vc_conf,
5370         },
5371         [ACTION_RAW_ENCAP] = {
5372                 .name = "raw_encap",
5373                 .help = "encapsulation data, defined by set raw_encap",
5374                 .priv = PRIV_ACTION(RAW_ENCAP,
5375                         sizeof(struct action_raw_encap_data)),
5376                 .next = NEXT(action_raw_encap),
5377                 .call = parse_vc_action_raw_encap,
5378         },
5379         [ACTION_RAW_ENCAP_INDEX] = {
5380                 .name = "index",
5381                 .help = "the index of raw_encap_confs",
5382                 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)),
5383         },
5384         [ACTION_RAW_ENCAP_INDEX_VALUE] = {
5385                 .name = "{index}",
5386                 .type = "UNSIGNED",
5387                 .help = "unsigned integer value",
5388                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5389                 .call = parse_vc_action_raw_encap_index,
5390                 .comp = comp_set_raw_index,
5391         },
5392         [ACTION_RAW_DECAP] = {
5393                 .name = "raw_decap",
5394                 .help = "decapsulation data, defined by set raw_encap",
5395                 .priv = PRIV_ACTION(RAW_DECAP,
5396                         sizeof(struct action_raw_decap_data)),
5397                 .next = NEXT(action_raw_decap),
5398                 .call = parse_vc_action_raw_decap,
5399         },
5400         [ACTION_RAW_DECAP_INDEX] = {
5401                 .name = "index",
5402                 .help = "the index of raw_encap_confs",
5403                 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)),
5404         },
5405         [ACTION_RAW_DECAP_INDEX_VALUE] = {
5406                 .name = "{index}",
5407                 .type = "UNSIGNED",
5408                 .help = "unsigned integer value",
5409                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5410                 .call = parse_vc_action_raw_decap_index,
5411                 .comp = comp_set_raw_index,
5412         },
5413         [ACTION_MODIFY_FIELD] = {
5414                 .name = "modify_field",
5415                 .help = "modify destination field with data from source field",
5416                 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE),
5417                 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)),
5418                 .call = parse_vc,
5419         },
5420         [ACTION_MODIFY_FIELD_OP] = {
5421                 .name = "op",
5422                 .help = "operation type",
5423                 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE),
5424                         NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)),
5425                 .call = parse_vc_conf,
5426         },
5427         [ACTION_MODIFY_FIELD_OP_VALUE] = {
5428                 .name = "{operation}",
5429                 .help = "operation type value",
5430                 .call = parse_vc_modify_field_op,
5431                 .comp = comp_set_modify_field_op,
5432         },
5433         [ACTION_MODIFY_FIELD_DST_TYPE] = {
5434                 .name = "dst_type",
5435                 .help = "destination field type",
5436                 .next = NEXT(action_modify_field_dst,
5437                         NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)),
5438                 .call = parse_vc_conf,
5439         },
5440         [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = {
5441                 .name = "{dst_type}",
5442                 .help = "destination field type value",
5443                 .call = parse_vc_modify_field_id,
5444                 .comp = comp_set_modify_field_id,
5445         },
5446         [ACTION_MODIFY_FIELD_DST_LEVEL] = {
5447                 .name = "dst_level",
5448                 .help = "destination field level",
5449                 .next = NEXT(action_modify_field_dst,
5450                              NEXT_ENTRY(COMMON_UNSIGNED)),
5451                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
5452                                         dst.level)),
5453                 .call = parse_vc_conf,
5454         },
5455         [ACTION_MODIFY_FIELD_DST_OFFSET] = {
5456                 .name = "dst_offset",
5457                 .help = "destination field bit offset",
5458                 .next = NEXT(action_modify_field_dst,
5459                              NEXT_ENTRY(COMMON_UNSIGNED)),
5460                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
5461                                         dst.offset)),
5462                 .call = parse_vc_conf,
5463         },
5464         [ACTION_MODIFY_FIELD_SRC_TYPE] = {
5465                 .name = "src_type",
5466                 .help = "source field type",
5467                 .next = NEXT(action_modify_field_src,
5468                         NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)),
5469                 .call = parse_vc_conf,
5470         },
5471         [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = {
5472                 .name = "{src_type}",
5473                 .help = "source field type value",
5474                 .call = parse_vc_modify_field_id,
5475                 .comp = comp_set_modify_field_id,
5476         },
5477         [ACTION_MODIFY_FIELD_SRC_LEVEL] = {
5478                 .name = "src_level",
5479                 .help = "source field level",
5480                 .next = NEXT(action_modify_field_src,
5481                              NEXT_ENTRY(COMMON_UNSIGNED)),
5482                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
5483                                         src.level)),
5484                 .call = parse_vc_conf,
5485         },
5486         [ACTION_MODIFY_FIELD_SRC_OFFSET] = {
5487                 .name = "src_offset",
5488                 .help = "source field bit offset",
5489                 .next = NEXT(action_modify_field_src,
5490                              NEXT_ENTRY(COMMON_UNSIGNED)),
5491                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
5492                                         src.offset)),
5493                 .call = parse_vc_conf,
5494         },
5495         [ACTION_MODIFY_FIELD_SRC_VALUE] = {
5496                 .name = "src_value",
5497                 .help = "source immediate value",
5498                 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH),
5499                              NEXT_ENTRY(COMMON_HEX)),
5500                 .args = ARGS(ARGS_ENTRY_ARB(0, 0),
5501                              ARGS_ENTRY_ARB(0, 0),
5502                              ARGS_ENTRY(struct rte_flow_action_modify_field,
5503                                         src.value)),
5504                 .call = parse_vc_conf,
5505         },
5506         [ACTION_MODIFY_FIELD_SRC_POINTER] = {
5507                 .name = "src_ptr",
5508                 .help = "pointer to source immediate value",
5509                 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH),
5510                              NEXT_ENTRY(COMMON_HEX)),
5511                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
5512                                         src.pvalue),
5513                              ARGS_ENTRY_ARB(0, 0),
5514                              ARGS_ENTRY_ARB
5515                                 (sizeof(struct rte_flow_action_modify_field),
5516                                  ACTION_MODIFY_PATTERN_SIZE)),
5517                 .call = parse_vc_conf,
5518         },
5519         [ACTION_MODIFY_FIELD_WIDTH] = {
5520                 .name = "width",
5521                 .help = "number of bits to copy",
5522                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT),
5523                         NEXT_ENTRY(COMMON_UNSIGNED)),
5524                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
5525                                         width)),
5526                 .call = parse_vc_conf,
5527         },
5528         /* Top level command. */
5529         [SET] = {
5530                 .name = "set",
5531                 .help = "set raw encap/decap/sample data",
5532                 .type = "set raw_encap|raw_decap <index> <pattern>"
5533                                 " or set sample_actions <index> <action>",
5534                 .next = NEXT(NEXT_ENTRY
5535                              (SET_RAW_ENCAP,
5536                               SET_RAW_DECAP,
5537                               SET_SAMPLE_ACTIONS)),
5538                 .call = parse_set_init,
5539         },
5540         /* Sub-level commands. */
5541         [SET_RAW_ENCAP] = {
5542                 .name = "raw_encap",
5543                 .help = "set raw encap data",
5544                 .next = NEXT(next_set_raw),
5545                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
5546                                 (offsetof(struct buffer, port),
5547                                  sizeof(((struct buffer *)0)->port),
5548                                  0, RAW_ENCAP_CONFS_MAX_NUM - 1)),
5549                 .call = parse_set_raw_encap_decap,
5550         },
5551         [SET_RAW_DECAP] = {
5552                 .name = "raw_decap",
5553                 .help = "set raw decap data",
5554                 .next = NEXT(next_set_raw),
5555                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
5556                                 (offsetof(struct buffer, port),
5557                                  sizeof(((struct buffer *)0)->port),
5558                                  0, RAW_ENCAP_CONFS_MAX_NUM - 1)),
5559                 .call = parse_set_raw_encap_decap,
5560         },
5561         [SET_RAW_INDEX] = {
5562                 .name = "{index}",
5563                 .type = "COMMON_UNSIGNED",
5564                 .help = "index of raw_encap/raw_decap data",
5565                 .next = NEXT(next_item),
5566                 .call = parse_port,
5567         },
5568         [SET_SAMPLE_INDEX] = {
5569                 .name = "{index}",
5570                 .type = "UNSIGNED",
5571                 .help = "index of sample actions",
5572                 .next = NEXT(next_action_sample),
5573                 .call = parse_port,
5574         },
5575         [SET_SAMPLE_ACTIONS] = {
5576                 .name = "sample_actions",
5577                 .help = "set sample actions list",
5578                 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)),
5579                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
5580                                 (offsetof(struct buffer, port),
5581                                  sizeof(((struct buffer *)0)->port),
5582                                  0, RAW_SAMPLE_CONFS_MAX_NUM - 1)),
5583                 .call = parse_set_sample_action,
5584         },
5585         [ACTION_SET_TAG] = {
5586                 .name = "set_tag",
5587                 .help = "set tag",
5588                 .priv = PRIV_ACTION(SET_TAG,
5589                         sizeof(struct rte_flow_action_set_tag)),
5590                 .next = NEXT(action_set_tag),
5591                 .call = parse_vc,
5592         },
5593         [ACTION_SET_TAG_INDEX] = {
5594                 .name = "index",
5595                 .help = "index of tag array",
5596                 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)),
5597                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)),
5598                 .call = parse_vc_conf,
5599         },
5600         [ACTION_SET_TAG_DATA] = {
5601                 .name = "data",
5602                 .help = "tag value",
5603                 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)),
5604                 .args = ARGS(ARGS_ENTRY
5605                              (struct rte_flow_action_set_tag, data)),
5606                 .call = parse_vc_conf,
5607         },
5608         [ACTION_SET_TAG_MASK] = {
5609                 .name = "mask",
5610                 .help = "mask for tag value",
5611                 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)),
5612                 .args = ARGS(ARGS_ENTRY
5613                              (struct rte_flow_action_set_tag, mask)),
5614                 .call = parse_vc_conf,
5615         },
5616         [ACTION_SET_META] = {
5617                 .name = "set_meta",
5618                 .help = "set metadata",
5619                 .priv = PRIV_ACTION(SET_META,
5620                         sizeof(struct rte_flow_action_set_meta)),
5621                 .next = NEXT(action_set_meta),
5622                 .call = parse_vc_action_set_meta,
5623         },
5624         [ACTION_SET_META_DATA] = {
5625                 .name = "data",
5626                 .help = "metadata value",
5627                 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)),
5628                 .args = ARGS(ARGS_ENTRY
5629                              (struct rte_flow_action_set_meta, data)),
5630                 .call = parse_vc_conf,
5631         },
5632         [ACTION_SET_META_MASK] = {
5633                 .name = "mask",
5634                 .help = "mask for metadata value",
5635                 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)),
5636                 .args = ARGS(ARGS_ENTRY
5637                              (struct rte_flow_action_set_meta, mask)),
5638                 .call = parse_vc_conf,
5639         },
5640         [ACTION_SET_IPV4_DSCP] = {
5641                 .name = "set_ipv4_dscp",
5642                 .help = "set DSCP value",
5643                 .priv = PRIV_ACTION(SET_IPV4_DSCP,
5644                         sizeof(struct rte_flow_action_set_dscp)),
5645                 .next = NEXT(action_set_ipv4_dscp),
5646                 .call = parse_vc,
5647         },
5648         [ACTION_SET_IPV4_DSCP_VALUE] = {
5649                 .name = "dscp_value",
5650                 .help = "new IPv4 DSCP value to set",
5651                 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)),
5652                 .args = ARGS(ARGS_ENTRY
5653                              (struct rte_flow_action_set_dscp, dscp)),
5654                 .call = parse_vc_conf,
5655         },
5656         [ACTION_SET_IPV6_DSCP] = {
5657                 .name = "set_ipv6_dscp",
5658                 .help = "set DSCP value",
5659                 .priv = PRIV_ACTION(SET_IPV6_DSCP,
5660                         sizeof(struct rte_flow_action_set_dscp)),
5661                 .next = NEXT(action_set_ipv6_dscp),
5662                 .call = parse_vc,
5663         },
5664         [ACTION_SET_IPV6_DSCP_VALUE] = {
5665                 .name = "dscp_value",
5666                 .help = "new IPv6 DSCP value to set",
5667                 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)),
5668                 .args = ARGS(ARGS_ENTRY
5669                              (struct rte_flow_action_set_dscp, dscp)),
5670                 .call = parse_vc_conf,
5671         },
5672         [ACTION_AGE] = {
5673                 .name = "age",
5674                 .help = "set a specific metadata header",
5675                 .next = NEXT(action_age),
5676                 .priv = PRIV_ACTION(AGE,
5677                         sizeof(struct rte_flow_action_age)),
5678                 .call = parse_vc,
5679         },
5680         [ACTION_AGE_TIMEOUT] = {
5681                 .name = "timeout",
5682                 .help = "flow age timeout value",
5683                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age,
5684                                            timeout, 24)),
5685                 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)),
5686                 .call = parse_vc_conf,
5687         },
5688         [ACTION_SAMPLE] = {
5689                 .name = "sample",
5690                 .help = "set a sample action",
5691                 .next = NEXT(action_sample),
5692                 .priv = PRIV_ACTION(SAMPLE,
5693                         sizeof(struct action_sample_data)),
5694                 .call = parse_vc_action_sample,
5695         },
5696         [ACTION_SAMPLE_RATIO] = {
5697                 .name = "ratio",
5698                 .help = "flow sample ratio value",
5699                 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)),
5700                 .args = ARGS(ARGS_ENTRY_ARB
5701                              (offsetof(struct action_sample_data, conf) +
5702                               offsetof(struct rte_flow_action_sample, ratio),
5703                               sizeof(((struct rte_flow_action_sample *)0)->
5704                                      ratio))),
5705         },
5706         [ACTION_SAMPLE_INDEX] = {
5707                 .name = "index",
5708                 .help = "the index of sample actions list",
5709                 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)),
5710         },
5711         [ACTION_SAMPLE_INDEX_VALUE] = {
5712                 .name = "{index}",
5713                 .type = "COMMON_UNSIGNED",
5714                 .help = "unsigned integer value",
5715                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5716                 .call = parse_vc_action_sample_index,
5717                 .comp = comp_set_sample_index,
5718         },
5719         [ACTION_CONNTRACK] = {
5720                 .name = "conntrack",
5721                 .help = "create a conntrack object",
5722                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5723                 .priv = PRIV_ACTION(CONNTRACK,
5724                                     sizeof(struct rte_flow_action_conntrack)),
5725                 .call = parse_vc,
5726         },
5727         [ACTION_CONNTRACK_UPDATE] = {
5728                 .name = "conntrack_update",
5729                 .help = "update a conntrack object",
5730                 .next = NEXT(action_update_conntrack),
5731                 .priv = PRIV_ACTION(CONNTRACK,
5732                                     sizeof(struct rte_flow_modify_conntrack)),
5733                 .call = parse_vc,
5734         },
5735         [ACTION_CONNTRACK_UPDATE_DIR] = {
5736                 .name = "dir",
5737                 .help = "update a conntrack object direction",
5738                 .next = NEXT(action_update_conntrack),
5739                 .call = parse_vc_action_conntrack_update,
5740         },
5741         [ACTION_CONNTRACK_UPDATE_CTX] = {
5742                 .name = "ctx",
5743                 .help = "update a conntrack object context",
5744                 .next = NEXT(action_update_conntrack),
5745                 .call = parse_vc_action_conntrack_update,
5746         },
5747         [ACTION_PORT_REPRESENTOR] = {
5748                 .name = "port_representor",
5749                 .help = "at embedded switch level, send matching traffic to the given ethdev",
5750                 .priv = PRIV_ACTION(PORT_REPRESENTOR,
5751                                     sizeof(struct rte_flow_action_ethdev)),
5752                 .next = NEXT(action_port_representor),
5753                 .call = parse_vc,
5754         },
5755         [ACTION_PORT_REPRESENTOR_PORT_ID] = {
5756                 .name = "port_id",
5757                 .help = "ethdev port ID",
5758                 .next = NEXT(action_port_representor,
5759                              NEXT_ENTRY(COMMON_UNSIGNED)),
5760                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev,
5761                                         port_id)),
5762                 .call = parse_vc_conf,
5763         },
5764         [ACTION_REPRESENTED_PORT] = {
5765                 .name = "represented_port",
5766                 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev",
5767                 .priv = PRIV_ACTION(REPRESENTED_PORT,
5768                                 sizeof(struct rte_flow_action_ethdev)),
5769                 .next = NEXT(action_represented_port),
5770                 .call = parse_vc,
5771         },
5772         [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = {
5773                 .name = "ethdev_port_id",
5774                 .help = "ethdev port ID",
5775                 .next = NEXT(action_represented_port,
5776                              NEXT_ENTRY(COMMON_UNSIGNED)),
5777                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev,
5778                                         port_id)),
5779                 .call = parse_vc_conf,
5780         },
5781         /* Indirect action destroy arguments. */
5782         [INDIRECT_ACTION_DESTROY_ID] = {
5783                 .name = "action_id",
5784                 .help = "specify a indirect action id to destroy",
5785                 .next = NEXT(next_ia_destroy_attr,
5786                              NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
5787                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer,
5788                                             args.ia_destroy.action_id)),
5789                 .call = parse_ia_destroy,
5790         },
5791         /* Indirect action create arguments. */
5792         [INDIRECT_ACTION_CREATE_ID] = {
5793                 .name = "action_id",
5794                 .help = "specify a indirect action id to create",
5795                 .next = NEXT(next_ia_create_attr,
5796                              NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
5797                 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)),
5798         },
5799         [ACTION_INDIRECT] = {
5800                 .name = "indirect",
5801                 .help = "apply indirect action by id",
5802                 .priv = PRIV_ACTION(INDIRECT, 0),
5803                 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)),
5804                 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))),
5805                 .call = parse_vc,
5806         },
5807         [INDIRECT_ACTION_ID2PTR] = {
5808                 .name = "{action_id}",
5809                 .type = "INDIRECT_ACTION_ID",
5810                 .help = "indirect action id",
5811                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
5812                 .call = parse_ia_id2ptr,
5813                 .comp = comp_none,
5814         },
5815         [INDIRECT_ACTION_INGRESS] = {
5816                 .name = "ingress",
5817                 .help = "affect rule to ingress",
5818                 .next = NEXT(next_ia_create_attr),
5819                 .call = parse_ia,
5820         },
5821         [INDIRECT_ACTION_EGRESS] = {
5822                 .name = "egress",
5823                 .help = "affect rule to egress",
5824                 .next = NEXT(next_ia_create_attr),
5825                 .call = parse_ia,
5826         },
5827         [INDIRECT_ACTION_TRANSFER] = {
5828                 .name = "transfer",
5829                 .help = "affect rule to transfer",
5830                 .next = NEXT(next_ia_create_attr),
5831                 .call = parse_ia,
5832         },
5833         [INDIRECT_ACTION_SPEC] = {
5834                 .name = "action",
5835                 .help = "specify action to create indirect handle",
5836                 .next = NEXT(next_action),
5837         },
5838         [ACTION_POL_G] = {
5839                 .name = "g_actions",
5840                 .help = "submit a list of associated actions for green",
5841                 .next = NEXT(next_action),
5842                 .call = parse_mp,
5843         },
5844         [ACTION_POL_Y] = {
5845                 .name = "y_actions",
5846                 .help = "submit a list of associated actions for yellow",
5847                 .next = NEXT(next_action),
5848         },
5849         [ACTION_POL_R] = {
5850                 .name = "r_actions",
5851                 .help = "submit a list of associated actions for red",
5852                 .next = NEXT(next_action),
5853         },
5854
5855         /* Top-level command. */
5856         [ADD] = {
5857                 .name = "add",
5858                 .type = "port meter policy {port_id} {arg}",
5859                 .help = "add port meter policy",
5860                 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)),
5861                 .call = parse_init,
5862         },
5863         /* Sub-level commands. */
5864         [ITEM_POL_PORT] = {
5865                 .name = "port",
5866                 .help = "add port meter policy",
5867                 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)),
5868         },
5869         [ITEM_POL_METER] = {
5870                 .name = "meter",
5871                 .help = "add port meter policy",
5872                 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)),
5873         },
5874         [ITEM_POL_POLICY] = {
5875                 .name = "policy",
5876                 .help = "add port meter policy",
5877                 .next = NEXT(NEXT_ENTRY(ACTION_POL_R),
5878                                 NEXT_ENTRY(ACTION_POL_Y),
5879                                 NEXT_ENTRY(ACTION_POL_G),
5880                                 NEXT_ENTRY(COMMON_POLICY_ID),
5881                                 NEXT_ENTRY(COMMON_PORT_ID)),
5882                 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id),
5883                                 ARGS_ENTRY(struct buffer, port)),
5884                 .call = parse_mp,
5885         },
5886 };
5887
5888 /** Remove and return last entry from argument stack. */
5889 static const struct arg *
5890 pop_args(struct context *ctx)
5891 {
5892         return ctx->args_num ? ctx->args[--ctx->args_num] : NULL;
5893 }
5894
5895 /** Add entry on top of the argument stack. */
5896 static int
5897 push_args(struct context *ctx, const struct arg *arg)
5898 {
5899         if (ctx->args_num == CTX_STACK_SIZE)
5900                 return -1;
5901         ctx->args[ctx->args_num++] = arg;
5902         return 0;
5903 }
5904
5905 /** Spread value into buffer according to bit-mask. */
5906 static size_t
5907 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg)
5908 {
5909         uint32_t i = arg->size;
5910         uint32_t end = 0;
5911         int sub = 1;
5912         int add = 0;
5913         size_t len = 0;
5914
5915         if (!arg->mask)
5916                 return 0;
5917 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
5918         if (!arg->hton) {
5919                 i = 0;
5920                 end = arg->size;
5921                 sub = 0;
5922                 add = 1;
5923         }
5924 #endif
5925         while (i != end) {
5926                 unsigned int shift = 0;
5927                 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub);
5928
5929                 for (shift = 0; arg->mask[i] >> shift; ++shift) {
5930                         if (!(arg->mask[i] & (1 << shift)))
5931                                 continue;
5932                         ++len;
5933                         if (!dst)
5934                                 continue;
5935                         *buf &= ~(1 << shift);
5936                         *buf |= (val & 1) << shift;
5937                         val >>= 1;
5938                 }
5939                 i += add;
5940         }
5941         return len;
5942 }
5943
5944 /** Compare a string with a partial one of a given length. */
5945 static int
5946 strcmp_partial(const char *full, const char *partial, size_t partial_len)
5947 {
5948         int r = strncmp(full, partial, partial_len);
5949
5950         if (r)
5951                 return r;
5952         if (strlen(full) <= partial_len)
5953                 return 0;
5954         return full[partial_len];
5955 }
5956
5957 /**
5958  * Parse a prefix length and generate a bit-mask.
5959  *
5960  * Last argument (ctx->args) is retrieved to determine mask size, storage
5961  * location and whether the result must use network byte ordering.
5962  */
5963 static int
5964 parse_prefix(struct context *ctx, const struct token *token,
5965              const char *str, unsigned int len,
5966              void *buf, unsigned int size)
5967 {
5968         const struct arg *arg = pop_args(ctx);
5969         static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff";
5970         char *end;
5971         uintmax_t u;
5972         unsigned int bytes;
5973         unsigned int extra;
5974
5975         (void)token;
5976         /* Argument is expected. */
5977         if (!arg)
5978                 return -1;
5979         errno = 0;
5980         u = strtoumax(str, &end, 0);
5981         if (errno || (size_t)(end - str) != len)
5982                 goto error;
5983         if (arg->mask) {
5984                 uintmax_t v = 0;
5985
5986                 extra = arg_entry_bf_fill(NULL, 0, arg);
5987                 if (u > extra)
5988                         goto error;
5989                 if (!ctx->object)
5990                         return len;
5991                 extra -= u;
5992                 while (u--)
5993                         (v <<= 1, v |= 1);
5994                 v <<= extra;
5995                 if (!arg_entry_bf_fill(ctx->object, v, arg) ||
5996                     !arg_entry_bf_fill(ctx->objmask, -1, arg))
5997                         goto error;
5998                 return len;
5999         }
6000         bytes = u / 8;
6001         extra = u % 8;
6002         size = arg->size;
6003         if (bytes > size || bytes + !!extra > size)
6004                 goto error;
6005         if (!ctx->object)
6006                 return len;
6007         buf = (uint8_t *)ctx->object + arg->offset;
6008 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
6009         if (!arg->hton) {
6010                 memset((uint8_t *)buf + size - bytes, 0xff, bytes);
6011                 memset(buf, 0x00, size - bytes);
6012                 if (extra)
6013                         ((uint8_t *)buf)[size - bytes - 1] = conv[extra];
6014         } else
6015 #endif
6016         {
6017                 memset(buf, 0xff, bytes);
6018                 memset((uint8_t *)buf + bytes, 0x00, size - bytes);
6019                 if (extra)
6020                         ((uint8_t *)buf)[bytes] = conv[extra];
6021         }
6022         if (ctx->objmask)
6023                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
6024         return len;
6025 error:
6026         push_args(ctx, arg);
6027         return -1;
6028 }
6029
6030 /** Default parsing function for token name matching. */
6031 static int
6032 parse_default(struct context *ctx, const struct token *token,
6033               const char *str, unsigned int len,
6034               void *buf, unsigned int size)
6035 {
6036         (void)ctx;
6037         (void)buf;
6038         (void)size;
6039         if (strcmp_partial(token->name, str, len))
6040                 return -1;
6041         return len;
6042 }
6043
6044 /** Parse flow command, initialize output buffer for subsequent tokens. */
6045 static int
6046 parse_init(struct context *ctx, const struct token *token,
6047            const char *str, unsigned int len,
6048            void *buf, unsigned int size)
6049 {
6050         struct buffer *out = buf;
6051
6052         /* Token name must match. */
6053         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6054                 return -1;
6055         /* Nothing else to do if there is no buffer. */
6056         if (!out)
6057                 return len;
6058         /* Make sure buffer is large enough. */
6059         if (size < sizeof(*out))
6060                 return -1;
6061         /* Initialize buffer. */
6062         memset(out, 0x00, sizeof(*out));
6063         memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out));
6064         ctx->objdata = 0;
6065         ctx->object = out;
6066         ctx->objmask = NULL;
6067         return len;
6068 }
6069
6070 /** Parse tokens for indirect action commands. */
6071 static int
6072 parse_ia(struct context *ctx, const struct token *token,
6073          const char *str, unsigned int len,
6074          void *buf, unsigned int size)
6075 {
6076         struct buffer *out = buf;
6077
6078         /* Token name must match. */
6079         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6080                 return -1;
6081         /* Nothing else to do if there is no buffer. */
6082         if (!out)
6083                 return len;
6084         if (!out->command) {
6085                 if (ctx->curr != INDIRECT_ACTION)
6086                         return -1;
6087                 if (sizeof(*out) > size)
6088                         return -1;
6089                 out->command = ctx->curr;
6090                 ctx->objdata = 0;
6091                 ctx->object = out;
6092                 ctx->objmask = NULL;
6093                 out->args.vc.data = (uint8_t *)out + size;
6094                 return len;
6095         }
6096         switch (ctx->curr) {
6097         case INDIRECT_ACTION_CREATE:
6098         case INDIRECT_ACTION_UPDATE:
6099                 out->args.vc.actions =
6100                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
6101                                                sizeof(double));
6102                 out->args.vc.attr.group = UINT32_MAX;
6103                 /* fallthrough */
6104         case INDIRECT_ACTION_QUERY:
6105                 out->command = ctx->curr;
6106                 ctx->objdata = 0;
6107                 ctx->object = out;
6108                 ctx->objmask = NULL;
6109                 return len;
6110         case INDIRECT_ACTION_EGRESS:
6111                 out->args.vc.attr.egress = 1;
6112                 return len;
6113         case INDIRECT_ACTION_INGRESS:
6114                 out->args.vc.attr.ingress = 1;
6115                 return len;
6116         case INDIRECT_ACTION_TRANSFER:
6117                 out->args.vc.attr.transfer = 1;
6118                 return len;
6119         default:
6120                 return -1;
6121         }
6122 }
6123
6124
6125 /** Parse tokens for indirect action destroy command. */
6126 static int
6127 parse_ia_destroy(struct context *ctx, const struct token *token,
6128                  const char *str, unsigned int len,
6129                  void *buf, unsigned int size)
6130 {
6131         struct buffer *out = buf;
6132         uint32_t *action_id;
6133
6134         /* Token name must match. */
6135         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6136                 return -1;
6137         /* Nothing else to do if there is no buffer. */
6138         if (!out)
6139                 return len;
6140         if (!out->command || out->command == INDIRECT_ACTION) {
6141                 if (ctx->curr != INDIRECT_ACTION_DESTROY)
6142                         return -1;
6143                 if (sizeof(*out) > size)
6144                         return -1;
6145                 out->command = ctx->curr;
6146                 ctx->objdata = 0;
6147                 ctx->object = out;
6148                 ctx->objmask = NULL;
6149                 out->args.ia_destroy.action_id =
6150                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
6151                                                sizeof(double));
6152                 return len;
6153         }
6154         action_id = out->args.ia_destroy.action_id
6155                     + out->args.ia_destroy.action_id_n++;
6156         if ((uint8_t *)action_id > (uint8_t *)out + size)
6157                 return -1;
6158         ctx->objdata = 0;
6159         ctx->object = action_id;
6160         ctx->objmask = NULL;
6161         return len;
6162 }
6163
6164 /** Parse tokens for meter policy action commands. */
6165 static int
6166 parse_mp(struct context *ctx, const struct token *token,
6167         const char *str, unsigned int len,
6168         void *buf, unsigned int size)
6169 {
6170         struct buffer *out = buf;
6171
6172         /* Token name must match. */
6173         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6174                 return -1;
6175         /* Nothing else to do if there is no buffer. */
6176         if (!out)
6177                 return len;
6178         if (!out->command) {
6179                 if (ctx->curr != ITEM_POL_POLICY)
6180                         return -1;
6181                 if (sizeof(*out) > size)
6182                         return -1;
6183                 out->command = ctx->curr;
6184                 ctx->objdata = 0;
6185                 ctx->object = out;
6186                 ctx->objmask = NULL;
6187                 out->args.vc.data = (uint8_t *)out + size;
6188                 return len;
6189         }
6190         switch (ctx->curr) {
6191         case ACTION_POL_G:
6192                 out->args.vc.actions =
6193                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
6194                                         sizeof(double));
6195                 out->command = ctx->curr;
6196                 ctx->objdata = 0;
6197                 ctx->object = out;
6198                 ctx->objmask = NULL;
6199                 return len;
6200         default:
6201                 return -1;
6202         }
6203 }
6204
6205 /** Parse tokens for validate/create commands. */
6206 static int
6207 parse_vc(struct context *ctx, const struct token *token,
6208          const char *str, unsigned int len,
6209          void *buf, unsigned int size)
6210 {
6211         struct buffer *out = buf;
6212         uint8_t *data;
6213         uint32_t data_size;
6214
6215         /* Token name must match. */
6216         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6217                 return -1;
6218         /* Nothing else to do if there is no buffer. */
6219         if (!out)
6220                 return len;
6221         if (!out->command) {
6222                 if (ctx->curr != VALIDATE && ctx->curr != CREATE &&
6223                     ctx->curr != PATTERN_TEMPLATE_CREATE &&
6224                     ctx->curr != ACTIONS_TEMPLATE_CREATE)
6225                         return -1;
6226                 if (sizeof(*out) > size)
6227                         return -1;
6228                 out->command = ctx->curr;
6229                 ctx->objdata = 0;
6230                 ctx->object = out;
6231                 ctx->objmask = NULL;
6232                 out->args.vc.data = (uint8_t *)out + size;
6233                 return len;
6234         }
6235         ctx->objdata = 0;
6236         switch (ctx->curr) {
6237         default:
6238                 ctx->object = &out->args.vc.attr;
6239                 break;
6240         case VC_TUNNEL_SET:
6241         case VC_TUNNEL_MATCH:
6242                 ctx->object = &out->args.vc.tunnel_ops;
6243                 break;
6244         }
6245         ctx->objmask = NULL;
6246         switch (ctx->curr) {
6247         case VC_GROUP:
6248         case VC_PRIORITY:
6249                 return len;
6250         case VC_TUNNEL_SET:
6251                 out->args.vc.tunnel_ops.enabled = 1;
6252                 out->args.vc.tunnel_ops.actions = 1;
6253                 return len;
6254         case VC_TUNNEL_MATCH:
6255                 out->args.vc.tunnel_ops.enabled = 1;
6256                 out->args.vc.tunnel_ops.items = 1;
6257                 return len;
6258         case VC_INGRESS:
6259                 out->args.vc.attr.ingress = 1;
6260                 return len;
6261         case VC_EGRESS:
6262                 out->args.vc.attr.egress = 1;
6263                 return len;
6264         case VC_TRANSFER:
6265                 out->args.vc.attr.transfer = 1;
6266                 return len;
6267         case ITEM_PATTERN:
6268                 out->args.vc.pattern =
6269                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
6270                                                sizeof(double));
6271                 ctx->object = out->args.vc.pattern;
6272                 ctx->objmask = NULL;
6273                 return len;
6274         case ACTIONS:
6275                 out->args.vc.actions =
6276                         (void *)RTE_ALIGN_CEIL((uintptr_t)
6277                                                (out->args.vc.pattern +
6278                                                 out->args.vc.pattern_n),
6279                                                sizeof(double));
6280                 ctx->object = out->args.vc.actions;
6281                 ctx->objmask = NULL;
6282                 return len;
6283         default:
6284                 if (!token->priv)
6285                         return -1;
6286                 break;
6287         }
6288         if (!out->args.vc.actions) {
6289                 const struct parse_item_priv *priv = token->priv;
6290                 struct rte_flow_item *item =
6291                         out->args.vc.pattern + out->args.vc.pattern_n;
6292
6293                 data_size = priv->size * 3; /* spec, last, mask */
6294                 data = (void *)RTE_ALIGN_FLOOR((uintptr_t)
6295                                                (out->args.vc.data - data_size),
6296                                                sizeof(double));
6297                 if ((uint8_t *)item + sizeof(*item) > data)
6298                         return -1;
6299                 *item = (struct rte_flow_item){
6300                         .type = priv->type,
6301                 };
6302                 ++out->args.vc.pattern_n;
6303                 ctx->object = item;
6304                 ctx->objmask = NULL;
6305         } else {
6306                 const struct parse_action_priv *priv = token->priv;
6307                 struct rte_flow_action *action =
6308                         out->args.vc.actions + out->args.vc.actions_n;
6309
6310                 data_size = priv->size; /* configuration */
6311                 data = (void *)RTE_ALIGN_FLOOR((uintptr_t)
6312                                                (out->args.vc.data - data_size),
6313                                                sizeof(double));
6314                 if ((uint8_t *)action + sizeof(*action) > data)
6315                         return -1;
6316                 *action = (struct rte_flow_action){
6317                         .type = priv->type,
6318                         .conf = data_size ? data : NULL,
6319                 };
6320                 ++out->args.vc.actions_n;
6321                 ctx->object = action;
6322                 ctx->objmask = NULL;
6323         }
6324         memset(data, 0, data_size);
6325         out->args.vc.data = data;
6326         ctx->objdata = data_size;
6327         return len;
6328 }
6329
6330 /** Parse pattern item parameter type. */
6331 static int
6332 parse_vc_spec(struct context *ctx, const struct token *token,
6333               const char *str, unsigned int len,
6334               void *buf, unsigned int size)
6335 {
6336         struct buffer *out = buf;
6337         struct rte_flow_item *item;
6338         uint32_t data_size;
6339         int index;
6340         int objmask = 0;
6341
6342         (void)size;
6343         /* Token name must match. */
6344         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6345                 return -1;
6346         /* Parse parameter types. */
6347         switch (ctx->curr) {
6348                 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX);
6349
6350         case ITEM_PARAM_IS:
6351                 index = 0;
6352                 objmask = 1;
6353                 break;
6354         case ITEM_PARAM_SPEC:
6355                 index = 0;
6356                 break;
6357         case ITEM_PARAM_LAST:
6358                 index = 1;
6359                 break;
6360         case ITEM_PARAM_PREFIX:
6361                 /* Modify next token to expect a prefix. */
6362                 if (ctx->next_num < 2)
6363                         return -1;
6364                 ctx->next[ctx->next_num - 2] = prefix;
6365                 /* Fall through. */
6366         case ITEM_PARAM_MASK:
6367                 index = 2;
6368                 break;
6369         default:
6370                 return -1;
6371         }
6372         /* Nothing else to do if there is no buffer. */
6373         if (!out)
6374                 return len;
6375         if (!out->args.vc.pattern_n)
6376                 return -1;
6377         item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
6378         data_size = ctx->objdata / 3; /* spec, last, mask */
6379         /* Point to selected object. */
6380         ctx->object = out->args.vc.data + (data_size * index);
6381         if (objmask) {
6382                 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */
6383                 item->mask = ctx->objmask;
6384         } else
6385                 ctx->objmask = NULL;
6386         /* Update relevant item pointer. */
6387         *((const void **[]){ &item->spec, &item->last, &item->mask })[index] =
6388                 ctx->object;
6389         return len;
6390 }
6391
6392 /** Parse action configuration field. */
6393 static int
6394 parse_vc_conf(struct context *ctx, const struct token *token,
6395               const char *str, unsigned int len,
6396               void *buf, unsigned int size)
6397 {
6398         struct buffer *out = buf;
6399
6400         (void)size;
6401         /* Token name must match. */
6402         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6403                 return -1;
6404         /* Nothing else to do if there is no buffer. */
6405         if (!out)
6406                 return len;
6407         /* Point to selected object. */
6408         ctx->object = out->args.vc.data;
6409         ctx->objmask = NULL;
6410         return len;
6411 }
6412
6413 /** Parse eCPRI common header type field. */
6414 static int
6415 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
6416                          const char *str, unsigned int len,
6417                          void *buf, unsigned int size)
6418 {
6419         struct rte_flow_item_ecpri *ecpri;
6420         struct rte_flow_item_ecpri *ecpri_mask;
6421         struct rte_flow_item *item;
6422         uint32_t data_size;
6423         uint8_t msg_type;
6424         struct buffer *out = buf;
6425         const struct arg *arg;
6426
6427         (void)size;
6428         /* Token name must match. */
6429         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6430                 return -1;
6431         switch (ctx->curr) {
6432         case ITEM_ECPRI_COMMON_TYPE_IQ_DATA:
6433                 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA;
6434                 break;
6435         case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL:
6436                 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL;
6437                 break;
6438         case ITEM_ECPRI_COMMON_TYPE_DLY_MSR:
6439                 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR;
6440                 break;
6441         default:
6442                 return -1;
6443         }
6444         if (!ctx->object)
6445                 return len;
6446         arg = pop_args(ctx);
6447         if (!arg)
6448                 return -1;
6449         ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data;
6450         ecpri->hdr.common.type = msg_type;
6451         data_size = ctx->objdata / 3; /* spec, last, mask */
6452         ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data +
6453                                                     (data_size * 2));
6454         ecpri_mask->hdr.common.type = 0xFF;
6455         if (arg->hton) {
6456                 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32);
6457                 ecpri_mask->hdr.common.u32 =
6458                                 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32);
6459         }
6460         item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
6461         item->spec = ecpri;
6462         item->mask = ecpri_mask;
6463         return len;
6464 }
6465
6466 /** Parse L2TPv2 common header type field. */
6467 static int
6468 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token,
6469                          const char *str, unsigned int len,
6470                          void *buf, unsigned int size)
6471 {
6472         struct rte_flow_item_l2tpv2 *l2tpv2;
6473         struct rte_flow_item_l2tpv2 *l2tpv2_mask;
6474         struct rte_flow_item *item;
6475         uint32_t data_size;
6476         uint16_t msg_type = 0;
6477         struct buffer *out = buf;
6478         const struct arg *arg;
6479
6480         (void)size;
6481         /* Token name must match. */
6482         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6483                 return -1;
6484         switch (ctx->curr) {
6485         case ITEM_L2TPV2_TYPE_DATA:
6486                 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA;
6487                 break;
6488         case ITEM_L2TPV2_TYPE_DATA_L:
6489                 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L;
6490                 break;
6491         case ITEM_L2TPV2_TYPE_DATA_S:
6492                 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S;
6493                 break;
6494         case ITEM_L2TPV2_TYPE_DATA_O:
6495                 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O;
6496                 break;
6497         case ITEM_L2TPV2_TYPE_DATA_L_S:
6498                 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S;
6499                 break;
6500         case ITEM_L2TPV2_TYPE_CTRL:
6501                 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL;
6502                 break;
6503         default:
6504                 return -1;
6505         }
6506         if (!ctx->object)
6507                 return len;
6508         arg = pop_args(ctx);
6509         if (!arg)
6510                 return -1;
6511         l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data;
6512         l2tpv2->hdr.common.flags_version |= msg_type;
6513         data_size = ctx->objdata / 3; /* spec, last, mask */
6514         l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data +
6515                                                     (data_size * 2));
6516         l2tpv2_mask->hdr.common.flags_version = 0xFFFF;
6517         if (arg->hton) {
6518                 l2tpv2->hdr.common.flags_version =
6519                         rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version);
6520                 l2tpv2_mask->hdr.common.flags_version =
6521                     rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version);
6522         }
6523         item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
6524         item->spec = l2tpv2;
6525         item->mask = l2tpv2_mask;
6526         return len;
6527 }
6528
6529 /** Parse meter color action type. */
6530 static int
6531 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token,
6532                                 const char *str, unsigned int len,
6533                                 void *buf, unsigned int size)
6534 {
6535         struct rte_flow_action *action_data;
6536         struct rte_flow_action_meter_color *conf;
6537         enum rte_color color;
6538
6539         (void)buf;
6540         (void)size;
6541         /* Token name must match. */
6542         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6543                 return -1;
6544         switch (ctx->curr) {
6545         case ACTION_METER_COLOR_GREEN:
6546                 color = RTE_COLOR_GREEN;
6547         break;
6548         case ACTION_METER_COLOR_YELLOW:
6549                 color = RTE_COLOR_YELLOW;
6550         break;
6551         case ACTION_METER_COLOR_RED:
6552                 color = RTE_COLOR_RED;
6553         break;
6554         default:
6555                 return -1;
6556         }
6557
6558         if (!ctx->object)
6559                 return len;
6560         action_data = ctx->object;
6561         conf = (struct rte_flow_action_meter_color *)
6562                                         (uintptr_t)(action_data->conf);
6563         conf->color = color;
6564         return len;
6565 }
6566
6567 /** Parse RSS action. */
6568 static int
6569 parse_vc_action_rss(struct context *ctx, const struct token *token,
6570                     const char *str, unsigned int len,
6571                     void *buf, unsigned int size)
6572 {
6573         struct buffer *out = buf;
6574         struct rte_flow_action *action;
6575         struct action_rss_data *action_rss_data;
6576         unsigned int i;
6577         int ret;
6578
6579         ret = parse_vc(ctx, token, str, len, buf, size);
6580         if (ret < 0)
6581                 return ret;
6582         /* Nothing else to do if there is no buffer. */
6583         if (!out)
6584                 return ret;
6585         if (!out->args.vc.actions_n)
6586                 return -1;
6587         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6588         /* Point to selected object. */
6589         ctx->object = out->args.vc.data;
6590         ctx->objmask = NULL;
6591         /* Set up default configuration. */
6592         action_rss_data = ctx->object;
6593         *action_rss_data = (struct action_rss_data){
6594                 .conf = (struct rte_flow_action_rss){
6595                         .func = RTE_ETH_HASH_FUNCTION_DEFAULT,
6596                         .level = 0,
6597                         .types = rss_hf,
6598                         .key_len = 0,
6599                         .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
6600                         .key = NULL,
6601                         .queue = action_rss_data->queue,
6602                 },
6603                 .queue = { 0 },
6604         };
6605         for (i = 0; i < action_rss_data->conf.queue_num; ++i)
6606                 action_rss_data->queue[i] = i;
6607         action->conf = &action_rss_data->conf;
6608         return ret;
6609 }
6610
6611 /**
6612  * Parse func field for RSS action.
6613  *
6614  * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the
6615  * ACTION_RSS_FUNC_* index that called this function.
6616  */
6617 static int
6618 parse_vc_action_rss_func(struct context *ctx, const struct token *token,
6619                          const char *str, unsigned int len,
6620                          void *buf, unsigned int size)
6621 {
6622         struct action_rss_data *action_rss_data;
6623         enum rte_eth_hash_function func;
6624
6625         (void)buf;
6626         (void)size;
6627         /* Token name must match. */
6628         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6629                 return -1;
6630         switch (ctx->curr) {
6631         case ACTION_RSS_FUNC_DEFAULT:
6632                 func = RTE_ETH_HASH_FUNCTION_DEFAULT;
6633                 break;
6634         case ACTION_RSS_FUNC_TOEPLITZ:
6635                 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
6636                 break;
6637         case ACTION_RSS_FUNC_SIMPLE_XOR:
6638                 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
6639                 break;
6640         case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ:
6641                 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ;
6642                 break;
6643         default:
6644                 return -1;
6645         }
6646         if (!ctx->object)
6647                 return len;
6648         action_rss_data = ctx->object;
6649         action_rss_data->conf.func = func;
6650         return len;
6651 }
6652
6653 /**
6654  * Parse type field for RSS action.
6655  *
6656  * Valid tokens are type field names and the "end" token.
6657  */
6658 static int
6659 parse_vc_action_rss_type(struct context *ctx, const struct token *token,
6660                           const char *str, unsigned int len,
6661                           void *buf, unsigned int size)
6662 {
6663         static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE);
6664         struct action_rss_data *action_rss_data;
6665         unsigned int i;
6666
6667         (void)token;
6668         (void)buf;
6669         (void)size;
6670         if (ctx->curr != ACTION_RSS_TYPE)
6671                 return -1;
6672         if (!(ctx->objdata >> 16) && ctx->object) {
6673                 action_rss_data = ctx->object;
6674                 action_rss_data->conf.types = 0;
6675         }
6676         if (!strcmp_partial("end", str, len)) {
6677                 ctx->objdata &= 0xffff;
6678                 return len;
6679         }
6680         for (i = 0; rss_type_table[i].str; ++i)
6681                 if (!strcmp_partial(rss_type_table[i].str, str, len))
6682                         break;
6683         if (!rss_type_table[i].str)
6684                 return -1;
6685         ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff);
6686         /* Repeat token. */
6687         if (ctx->next_num == RTE_DIM(ctx->next))
6688                 return -1;
6689         ctx->next[ctx->next_num++] = next;
6690         if (!ctx->object)
6691                 return len;
6692         action_rss_data = ctx->object;
6693         action_rss_data->conf.types |= rss_type_table[i].rss_type;
6694         return len;
6695 }
6696
6697 /**
6698  * Parse queue field for RSS action.
6699  *
6700  * Valid tokens are queue indices and the "end" token.
6701  */
6702 static int
6703 parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
6704                           const char *str, unsigned int len,
6705                           void *buf, unsigned int size)
6706 {
6707         static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE);
6708         struct action_rss_data *action_rss_data;
6709         const struct arg *arg;
6710         int ret;
6711         int i;
6712
6713         (void)token;
6714         (void)buf;
6715         (void)size;
6716         if (ctx->curr != ACTION_RSS_QUEUE)
6717                 return -1;
6718         i = ctx->objdata >> 16;
6719         if (!strcmp_partial("end", str, len)) {
6720                 ctx->objdata &= 0xffff;
6721                 goto end;
6722         }
6723         if (i >= ACTION_RSS_QUEUE_NUM)
6724                 return -1;
6725         arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) +
6726                              i * sizeof(action_rss_data->queue[i]),
6727                              sizeof(action_rss_data->queue[i]));
6728         if (push_args(ctx, arg))
6729                 return -1;
6730         ret = parse_int(ctx, token, str, len, NULL, 0);
6731         if (ret < 0) {
6732                 pop_args(ctx);
6733                 return -1;
6734         }
6735         ++i;
6736         ctx->objdata = i << 16 | (ctx->objdata & 0xffff);
6737         /* Repeat token. */
6738         if (ctx->next_num == RTE_DIM(ctx->next))
6739                 return -1;
6740         ctx->next[ctx->next_num++] = next;
6741 end:
6742         if (!ctx->object)
6743                 return len;
6744         action_rss_data = ctx->object;
6745         action_rss_data->conf.queue_num = i;
6746         action_rss_data->conf.queue = i ? action_rss_data->queue : NULL;
6747         return len;
6748 }
6749
6750 /** Setup VXLAN encap configuration. */
6751 static int
6752 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data)
6753 {
6754         /* Set up default configuration. */
6755         *action_vxlan_encap_data = (struct action_vxlan_encap_data){
6756                 .conf = (struct rte_flow_action_vxlan_encap){
6757                         .definition = action_vxlan_encap_data->items,
6758                 },
6759                 .items = {
6760                         {
6761                                 .type = RTE_FLOW_ITEM_TYPE_ETH,
6762                                 .spec = &action_vxlan_encap_data->item_eth,
6763                                 .mask = &rte_flow_item_eth_mask,
6764                         },
6765                         {
6766                                 .type = RTE_FLOW_ITEM_TYPE_VLAN,
6767                                 .spec = &action_vxlan_encap_data->item_vlan,
6768                                 .mask = &rte_flow_item_vlan_mask,
6769                         },
6770                         {
6771                                 .type = RTE_FLOW_ITEM_TYPE_IPV4,
6772                                 .spec = &action_vxlan_encap_data->item_ipv4,
6773                                 .mask = &rte_flow_item_ipv4_mask,
6774                         },
6775                         {
6776                                 .type = RTE_FLOW_ITEM_TYPE_UDP,
6777                                 .spec = &action_vxlan_encap_data->item_udp,
6778                                 .mask = &rte_flow_item_udp_mask,
6779                         },
6780                         {
6781                                 .type = RTE_FLOW_ITEM_TYPE_VXLAN,
6782                                 .spec = &action_vxlan_encap_data->item_vxlan,
6783                                 .mask = &rte_flow_item_vxlan_mask,
6784                         },
6785                         {
6786                                 .type = RTE_FLOW_ITEM_TYPE_END,
6787                         },
6788                 },
6789                 .item_eth.type = 0,
6790                 .item_vlan = {
6791                         .tci = vxlan_encap_conf.vlan_tci,
6792                         .inner_type = 0,
6793                 },
6794                 .item_ipv4.hdr = {
6795                         .src_addr = vxlan_encap_conf.ipv4_src,
6796                         .dst_addr = vxlan_encap_conf.ipv4_dst,
6797                 },
6798                 .item_udp.hdr = {
6799                         .src_port = vxlan_encap_conf.udp_src,
6800                         .dst_port = vxlan_encap_conf.udp_dst,
6801                 },
6802                 .item_vxlan.flags = 0,
6803         };
6804         memcpy(action_vxlan_encap_data->item_eth.dst.addr_bytes,
6805                vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
6806         memcpy(action_vxlan_encap_data->item_eth.src.addr_bytes,
6807                vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
6808         if (!vxlan_encap_conf.select_ipv4) {
6809                 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr,
6810                        &vxlan_encap_conf.ipv6_src,
6811                        sizeof(vxlan_encap_conf.ipv6_src));
6812                 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr,
6813                        &vxlan_encap_conf.ipv6_dst,
6814                        sizeof(vxlan_encap_conf.ipv6_dst));
6815                 action_vxlan_encap_data->items[2] = (struct rte_flow_item){
6816                         .type = RTE_FLOW_ITEM_TYPE_IPV6,
6817                         .spec = &action_vxlan_encap_data->item_ipv6,
6818                         .mask = &rte_flow_item_ipv6_mask,
6819                 };
6820         }
6821         if (!vxlan_encap_conf.select_vlan)
6822                 action_vxlan_encap_data->items[1].type =
6823                         RTE_FLOW_ITEM_TYPE_VOID;
6824         if (vxlan_encap_conf.select_tos_ttl) {
6825                 if (vxlan_encap_conf.select_ipv4) {
6826                         static struct rte_flow_item_ipv4 ipv4_mask_tos;
6827
6828                         memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask,
6829                                sizeof(ipv4_mask_tos));
6830                         ipv4_mask_tos.hdr.type_of_service = 0xff;
6831                         ipv4_mask_tos.hdr.time_to_live = 0xff;
6832                         action_vxlan_encap_data->item_ipv4.hdr.type_of_service =
6833                                         vxlan_encap_conf.ip_tos;
6834                         action_vxlan_encap_data->item_ipv4.hdr.time_to_live =
6835                                         vxlan_encap_conf.ip_ttl;
6836                         action_vxlan_encap_data->items[2].mask =
6837                                                         &ipv4_mask_tos;
6838                 } else {
6839                         static struct rte_flow_item_ipv6 ipv6_mask_tos;
6840
6841                         memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask,
6842                                sizeof(ipv6_mask_tos));
6843                         ipv6_mask_tos.hdr.vtc_flow |=
6844                                 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT);
6845                         ipv6_mask_tos.hdr.hop_limits = 0xff;
6846                         action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |=
6847                                 rte_cpu_to_be_32
6848                                         ((uint32_t)vxlan_encap_conf.ip_tos <<
6849                                          RTE_IPV6_HDR_TC_SHIFT);
6850                         action_vxlan_encap_data->item_ipv6.hdr.hop_limits =
6851                                         vxlan_encap_conf.ip_ttl;
6852                         action_vxlan_encap_data->items[2].mask =
6853                                                         &ipv6_mask_tos;
6854                 }
6855         }
6856         memcpy(action_vxlan_encap_data->item_vxlan.vni, vxlan_encap_conf.vni,
6857                RTE_DIM(vxlan_encap_conf.vni));
6858         return 0;
6859 }
6860
6861 /** Parse VXLAN encap action. */
6862 static int
6863 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token,
6864                             const char *str, unsigned int len,
6865                             void *buf, unsigned int size)
6866 {
6867         struct buffer *out = buf;
6868         struct rte_flow_action *action;
6869         struct action_vxlan_encap_data *action_vxlan_encap_data;
6870         int ret;
6871
6872         ret = parse_vc(ctx, token, str, len, buf, size);
6873         if (ret < 0)
6874                 return ret;
6875         /* Nothing else to do if there is no buffer. */
6876         if (!out)
6877                 return ret;
6878         if (!out->args.vc.actions_n)
6879                 return -1;
6880         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6881         /* Point to selected object. */
6882         ctx->object = out->args.vc.data;
6883         ctx->objmask = NULL;
6884         action_vxlan_encap_data = ctx->object;
6885         parse_setup_vxlan_encap_data(action_vxlan_encap_data);
6886         action->conf = &action_vxlan_encap_data->conf;
6887         return ret;
6888 }
6889
6890 /** Setup NVGRE encap configuration. */
6891 static int
6892 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data)
6893 {
6894         /* Set up default configuration. */
6895         *action_nvgre_encap_data = (struct action_nvgre_encap_data){
6896                 .conf = (struct rte_flow_action_nvgre_encap){
6897                         .definition = action_nvgre_encap_data->items,
6898                 },
6899                 .items = {
6900                         {
6901                                 .type = RTE_FLOW_ITEM_TYPE_ETH,
6902                                 .spec = &action_nvgre_encap_data->item_eth,
6903                                 .mask = &rte_flow_item_eth_mask,
6904                         },
6905                         {
6906                                 .type = RTE_FLOW_ITEM_TYPE_VLAN,
6907                                 .spec = &action_nvgre_encap_data->item_vlan,
6908                                 .mask = &rte_flow_item_vlan_mask,
6909                         },
6910                         {
6911                                 .type = RTE_FLOW_ITEM_TYPE_IPV4,
6912                                 .spec = &action_nvgre_encap_data->item_ipv4,
6913                                 .mask = &rte_flow_item_ipv4_mask,
6914                         },
6915                         {
6916                                 .type = RTE_FLOW_ITEM_TYPE_NVGRE,
6917                                 .spec = &action_nvgre_encap_data->item_nvgre,
6918                                 .mask = &rte_flow_item_nvgre_mask,
6919                         },
6920                         {
6921                                 .type = RTE_FLOW_ITEM_TYPE_END,
6922                         },
6923                 },
6924                 .item_eth.type = 0,
6925                 .item_vlan = {
6926                         .tci = nvgre_encap_conf.vlan_tci,
6927                         .inner_type = 0,
6928                 },
6929                 .item_ipv4.hdr = {
6930                        .src_addr = nvgre_encap_conf.ipv4_src,
6931                        .dst_addr = nvgre_encap_conf.ipv4_dst,
6932                 },
6933                 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000),
6934                 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB),
6935                 .item_nvgre.flow_id = 0,
6936         };
6937         memcpy(action_nvgre_encap_data->item_eth.dst.addr_bytes,
6938                nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
6939         memcpy(action_nvgre_encap_data->item_eth.src.addr_bytes,
6940                nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
6941         if (!nvgre_encap_conf.select_ipv4) {
6942                 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr,
6943                        &nvgre_encap_conf.ipv6_src,
6944                        sizeof(nvgre_encap_conf.ipv6_src));
6945                 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr,
6946                        &nvgre_encap_conf.ipv6_dst,
6947                        sizeof(nvgre_encap_conf.ipv6_dst));
6948                 action_nvgre_encap_data->items[2] = (struct rte_flow_item){
6949                         .type = RTE_FLOW_ITEM_TYPE_IPV6,
6950                         .spec = &action_nvgre_encap_data->item_ipv6,
6951                         .mask = &rte_flow_item_ipv6_mask,
6952                 };
6953         }
6954         if (!nvgre_encap_conf.select_vlan)
6955                 action_nvgre_encap_data->items[1].type =
6956                         RTE_FLOW_ITEM_TYPE_VOID;
6957         memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni,
6958                RTE_DIM(nvgre_encap_conf.tni));
6959         return 0;
6960 }
6961
6962 /** Parse NVGRE encap action. */
6963 static int
6964 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token,
6965                             const char *str, unsigned int len,
6966                             void *buf, unsigned int size)
6967 {
6968         struct buffer *out = buf;
6969         struct rte_flow_action *action;
6970         struct action_nvgre_encap_data *action_nvgre_encap_data;
6971         int ret;
6972
6973         ret = parse_vc(ctx, token, str, len, buf, size);
6974         if (ret < 0)
6975                 return ret;
6976         /* Nothing else to do if there is no buffer. */
6977         if (!out)
6978                 return ret;
6979         if (!out->args.vc.actions_n)
6980                 return -1;
6981         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6982         /* Point to selected object. */
6983         ctx->object = out->args.vc.data;
6984         ctx->objmask = NULL;
6985         action_nvgre_encap_data = ctx->object;
6986         parse_setup_nvgre_encap_data(action_nvgre_encap_data);
6987         action->conf = &action_nvgre_encap_data->conf;
6988         return ret;
6989 }
6990
6991 /** Parse l2 encap action. */
6992 static int
6993 parse_vc_action_l2_encap(struct context *ctx, const struct token *token,
6994                          const char *str, unsigned int len,
6995                          void *buf, unsigned int size)
6996 {
6997         struct buffer *out = buf;
6998         struct rte_flow_action *action;
6999         struct action_raw_encap_data *action_encap_data;
7000         struct rte_flow_item_eth eth = { .type = 0, };
7001         struct rte_flow_item_vlan vlan = {
7002                 .tci = mplsoudp_encap_conf.vlan_tci,
7003                 .inner_type = 0,
7004         };
7005         uint8_t *header;
7006         int ret;
7007
7008         ret = parse_vc(ctx, token, str, len, buf, size);
7009         if (ret < 0)
7010                 return ret;
7011         /* Nothing else to do if there is no buffer. */
7012         if (!out)
7013                 return ret;
7014         if (!out->args.vc.actions_n)
7015                 return -1;
7016         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7017         /* Point to selected object. */
7018         ctx->object = out->args.vc.data;
7019         ctx->objmask = NULL;
7020         /* Copy the headers to the buffer. */
7021         action_encap_data = ctx->object;
7022         *action_encap_data = (struct action_raw_encap_data) {
7023                 .conf = (struct rte_flow_action_raw_encap){
7024                         .data = action_encap_data->data,
7025                 },
7026                 .data = {},
7027         };
7028         header = action_encap_data->data;
7029         if (l2_encap_conf.select_vlan)
7030                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
7031         else if (l2_encap_conf.select_ipv4)
7032                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
7033         else
7034                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
7035         memcpy(eth.dst.addr_bytes,
7036                l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
7037         memcpy(eth.src.addr_bytes,
7038                l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
7039         memcpy(header, &eth, sizeof(eth));
7040         header += sizeof(eth);
7041         if (l2_encap_conf.select_vlan) {
7042                 if (l2_encap_conf.select_ipv4)
7043                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
7044                 else
7045                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
7046                 memcpy(header, &vlan, sizeof(vlan));
7047                 header += sizeof(vlan);
7048         }
7049         action_encap_data->conf.size = header -
7050                 action_encap_data->data;
7051         action->conf = &action_encap_data->conf;
7052         return ret;
7053 }
7054
7055 /** Parse l2 decap action. */
7056 static int
7057 parse_vc_action_l2_decap(struct context *ctx, const struct token *token,
7058                          const char *str, unsigned int len,
7059                          void *buf, unsigned int size)
7060 {
7061         struct buffer *out = buf;
7062         struct rte_flow_action *action;
7063         struct action_raw_decap_data *action_decap_data;
7064         struct rte_flow_item_eth eth = { .type = 0, };
7065         struct rte_flow_item_vlan vlan = {
7066                 .tci = mplsoudp_encap_conf.vlan_tci,
7067                 .inner_type = 0,
7068         };
7069         uint8_t *header;
7070         int ret;
7071
7072         ret = parse_vc(ctx, token, str, len, buf, size);
7073         if (ret < 0)
7074                 return ret;
7075         /* Nothing else to do if there is no buffer. */
7076         if (!out)
7077                 return ret;
7078         if (!out->args.vc.actions_n)
7079                 return -1;
7080         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7081         /* Point to selected object. */
7082         ctx->object = out->args.vc.data;
7083         ctx->objmask = NULL;
7084         /* Copy the headers to the buffer. */
7085         action_decap_data = ctx->object;
7086         *action_decap_data = (struct action_raw_decap_data) {
7087                 .conf = (struct rte_flow_action_raw_decap){
7088                         .data = action_decap_data->data,
7089                 },
7090                 .data = {},
7091         };
7092         header = action_decap_data->data;
7093         if (l2_decap_conf.select_vlan)
7094                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
7095         memcpy(header, &eth, sizeof(eth));
7096         header += sizeof(eth);
7097         if (l2_decap_conf.select_vlan) {
7098                 memcpy(header, &vlan, sizeof(vlan));
7099                 header += sizeof(vlan);
7100         }
7101         action_decap_data->conf.size = header -
7102                 action_decap_data->data;
7103         action->conf = &action_decap_data->conf;
7104         return ret;
7105 }
7106
7107 #define ETHER_TYPE_MPLS_UNICAST 0x8847
7108
7109 /** Parse MPLSOGRE encap action. */
7110 static int
7111 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token,
7112                                const char *str, unsigned int len,
7113                                void *buf, unsigned int size)
7114 {
7115         struct buffer *out = buf;
7116         struct rte_flow_action *action;
7117         struct action_raw_encap_data *action_encap_data;
7118         struct rte_flow_item_eth eth = { .type = 0, };
7119         struct rte_flow_item_vlan vlan = {
7120                 .tci = mplsogre_encap_conf.vlan_tci,
7121                 .inner_type = 0,
7122         };
7123         struct rte_flow_item_ipv4 ipv4 = {
7124                 .hdr =  {
7125                         .src_addr = mplsogre_encap_conf.ipv4_src,
7126                         .dst_addr = mplsogre_encap_conf.ipv4_dst,
7127                         .next_proto_id = IPPROTO_GRE,
7128                         .version_ihl = RTE_IPV4_VHL_DEF,
7129                         .time_to_live = IPDEFTTL,
7130                 },
7131         };
7132         struct rte_flow_item_ipv6 ipv6 = {
7133                 .hdr =  {
7134                         .proto = IPPROTO_GRE,
7135                         .hop_limits = IPDEFTTL,
7136                 },
7137         };
7138         struct rte_flow_item_gre gre = {
7139                 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST),
7140         };
7141         struct rte_flow_item_mpls mpls = {
7142                 .ttl = 0,
7143         };
7144         uint8_t *header;
7145         int ret;
7146
7147         ret = parse_vc(ctx, token, str, len, buf, size);
7148         if (ret < 0)
7149                 return ret;
7150         /* Nothing else to do if there is no buffer. */
7151         if (!out)
7152                 return ret;
7153         if (!out->args.vc.actions_n)
7154                 return -1;
7155         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7156         /* Point to selected object. */
7157         ctx->object = out->args.vc.data;
7158         ctx->objmask = NULL;
7159         /* Copy the headers to the buffer. */
7160         action_encap_data = ctx->object;
7161         *action_encap_data = (struct action_raw_encap_data) {
7162                 .conf = (struct rte_flow_action_raw_encap){
7163                         .data = action_encap_data->data,
7164                 },
7165                 .data = {},
7166                 .preserve = {},
7167         };
7168         header = action_encap_data->data;
7169         if (mplsogre_encap_conf.select_vlan)
7170                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
7171         else if (mplsogre_encap_conf.select_ipv4)
7172                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
7173         else
7174                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
7175         memcpy(eth.dst.addr_bytes,
7176                mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
7177         memcpy(eth.src.addr_bytes,
7178                mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
7179         memcpy(header, &eth, sizeof(eth));
7180         header += sizeof(eth);
7181         if (mplsogre_encap_conf.select_vlan) {
7182                 if (mplsogre_encap_conf.select_ipv4)
7183                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
7184                 else
7185                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
7186                 memcpy(header, &vlan, sizeof(vlan));
7187                 header += sizeof(vlan);
7188         }
7189         if (mplsogre_encap_conf.select_ipv4) {
7190                 memcpy(header, &ipv4, sizeof(ipv4));
7191                 header += sizeof(ipv4);
7192         } else {
7193                 memcpy(&ipv6.hdr.src_addr,
7194                        &mplsogre_encap_conf.ipv6_src,
7195                        sizeof(mplsogre_encap_conf.ipv6_src));
7196                 memcpy(&ipv6.hdr.dst_addr,
7197                        &mplsogre_encap_conf.ipv6_dst,
7198                        sizeof(mplsogre_encap_conf.ipv6_dst));
7199                 memcpy(header, &ipv6, sizeof(ipv6));
7200                 header += sizeof(ipv6);
7201         }
7202         memcpy(header, &gre, sizeof(gre));
7203         header += sizeof(gre);
7204         memcpy(mpls.label_tc_s, mplsogre_encap_conf.label,
7205                RTE_DIM(mplsogre_encap_conf.label));
7206         mpls.label_tc_s[2] |= 0x1;
7207         memcpy(header, &mpls, sizeof(mpls));
7208         header += sizeof(mpls);
7209         action_encap_data->conf.size = header -
7210                 action_encap_data->data;
7211         action->conf = &action_encap_data->conf;
7212         return ret;
7213 }
7214
7215 /** Parse MPLSOGRE decap action. */
7216 static int
7217 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token,
7218                                const char *str, unsigned int len,
7219                                void *buf, unsigned int size)
7220 {
7221         struct buffer *out = buf;
7222         struct rte_flow_action *action;
7223         struct action_raw_decap_data *action_decap_data;
7224         struct rte_flow_item_eth eth = { .type = 0, };
7225         struct rte_flow_item_vlan vlan = {.tci = 0};
7226         struct rte_flow_item_ipv4 ipv4 = {
7227                 .hdr =  {
7228                         .next_proto_id = IPPROTO_GRE,
7229                 },
7230         };
7231         struct rte_flow_item_ipv6 ipv6 = {
7232                 .hdr =  {
7233                         .proto = IPPROTO_GRE,
7234                 },
7235         };
7236         struct rte_flow_item_gre gre = {
7237                 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST),
7238         };
7239         struct rte_flow_item_mpls mpls;
7240         uint8_t *header;
7241         int ret;
7242
7243         ret = parse_vc(ctx, token, str, len, buf, size);
7244         if (ret < 0)
7245                 return ret;
7246         /* Nothing else to do if there is no buffer. */
7247         if (!out)
7248                 return ret;
7249         if (!out->args.vc.actions_n)
7250                 return -1;
7251         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7252         /* Point to selected object. */
7253         ctx->object = out->args.vc.data;
7254         ctx->objmask = NULL;
7255         /* Copy the headers to the buffer. */
7256         action_decap_data = ctx->object;
7257         *action_decap_data = (struct action_raw_decap_data) {
7258                 .conf = (struct rte_flow_action_raw_decap){
7259                         .data = action_decap_data->data,
7260                 },
7261                 .data = {},
7262         };
7263         header = action_decap_data->data;
7264         if (mplsogre_decap_conf.select_vlan)
7265                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
7266         else if (mplsogre_encap_conf.select_ipv4)
7267                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
7268         else
7269                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
7270         memcpy(eth.dst.addr_bytes,
7271                mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
7272         memcpy(eth.src.addr_bytes,
7273                mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
7274         memcpy(header, &eth, sizeof(eth));
7275         header += sizeof(eth);
7276         if (mplsogre_encap_conf.select_vlan) {
7277                 if (mplsogre_encap_conf.select_ipv4)
7278                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
7279                 else
7280                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
7281                 memcpy(header, &vlan, sizeof(vlan));
7282                 header += sizeof(vlan);
7283         }
7284         if (mplsogre_encap_conf.select_ipv4) {
7285                 memcpy(header, &ipv4, sizeof(ipv4));
7286                 header += sizeof(ipv4);
7287         } else {
7288                 memcpy(header, &ipv6, sizeof(ipv6));
7289                 header += sizeof(ipv6);
7290         }
7291         memcpy(header, &gre, sizeof(gre));
7292         header += sizeof(gre);
7293         memset(&mpls, 0, sizeof(mpls));
7294         memcpy(header, &mpls, sizeof(mpls));
7295         header += sizeof(mpls);
7296         action_decap_data->conf.size = header -
7297                 action_decap_data->data;
7298         action->conf = &action_decap_data->conf;
7299         return ret;
7300 }
7301
7302 /** Parse MPLSOUDP encap action. */
7303 static int
7304 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token,
7305                                const char *str, unsigned int len,
7306                                void *buf, unsigned int size)
7307 {
7308         struct buffer *out = buf;
7309         struct rte_flow_action *action;
7310         struct action_raw_encap_data *action_encap_data;
7311         struct rte_flow_item_eth eth = { .type = 0, };
7312         struct rte_flow_item_vlan vlan = {
7313                 .tci = mplsoudp_encap_conf.vlan_tci,
7314                 .inner_type = 0,
7315         };
7316         struct rte_flow_item_ipv4 ipv4 = {
7317                 .hdr =  {
7318                         .src_addr = mplsoudp_encap_conf.ipv4_src,
7319                         .dst_addr = mplsoudp_encap_conf.ipv4_dst,
7320                         .next_proto_id = IPPROTO_UDP,
7321                         .version_ihl = RTE_IPV4_VHL_DEF,
7322                         .time_to_live = IPDEFTTL,
7323                 },
7324         };
7325         struct rte_flow_item_ipv6 ipv6 = {
7326                 .hdr =  {
7327                         .proto = IPPROTO_UDP,
7328                         .hop_limits = IPDEFTTL,
7329                 },
7330         };
7331         struct rte_flow_item_udp udp = {
7332                 .hdr = {
7333                         .src_port = mplsoudp_encap_conf.udp_src,
7334                         .dst_port = mplsoudp_encap_conf.udp_dst,
7335                 },
7336         };
7337         struct rte_flow_item_mpls mpls;
7338         uint8_t *header;
7339         int ret;
7340
7341         ret = parse_vc(ctx, token, str, len, buf, size);
7342         if (ret < 0)
7343                 return ret;
7344         /* Nothing else to do if there is no buffer. */
7345         if (!out)
7346                 return ret;
7347         if (!out->args.vc.actions_n)
7348                 return -1;
7349         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7350         /* Point to selected object. */
7351         ctx->object = out->args.vc.data;
7352         ctx->objmask = NULL;
7353         /* Copy the headers to the buffer. */
7354         action_encap_data = ctx->object;
7355         *action_encap_data = (struct action_raw_encap_data) {
7356                 .conf = (struct rte_flow_action_raw_encap){
7357                         .data = action_encap_data->data,
7358                 },
7359                 .data = {},
7360                 .preserve = {},
7361         };
7362         header = action_encap_data->data;
7363         if (mplsoudp_encap_conf.select_vlan)
7364                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
7365         else if (mplsoudp_encap_conf.select_ipv4)
7366                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
7367         else
7368                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
7369         memcpy(eth.dst.addr_bytes,
7370                mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
7371         memcpy(eth.src.addr_bytes,
7372                mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
7373         memcpy(header, &eth, sizeof(eth));
7374         header += sizeof(eth);
7375         if (mplsoudp_encap_conf.select_vlan) {
7376                 if (mplsoudp_encap_conf.select_ipv4)
7377                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
7378                 else
7379                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
7380                 memcpy(header, &vlan, sizeof(vlan));
7381                 header += sizeof(vlan);
7382         }
7383         if (mplsoudp_encap_conf.select_ipv4) {
7384                 memcpy(header, &ipv4, sizeof(ipv4));
7385                 header += sizeof(ipv4);
7386         } else {
7387                 memcpy(&ipv6.hdr.src_addr,
7388                        &mplsoudp_encap_conf.ipv6_src,
7389                        sizeof(mplsoudp_encap_conf.ipv6_src));
7390                 memcpy(&ipv6.hdr.dst_addr,
7391                        &mplsoudp_encap_conf.ipv6_dst,
7392                        sizeof(mplsoudp_encap_conf.ipv6_dst));
7393                 memcpy(header, &ipv6, sizeof(ipv6));
7394                 header += sizeof(ipv6);
7395         }
7396         memcpy(header, &udp, sizeof(udp));
7397         header += sizeof(udp);
7398         memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label,
7399                RTE_DIM(mplsoudp_encap_conf.label));
7400         mpls.label_tc_s[2] |= 0x1;
7401         memcpy(header, &mpls, sizeof(mpls));
7402         header += sizeof(mpls);
7403         action_encap_data->conf.size = header -
7404                 action_encap_data->data;
7405         action->conf = &action_encap_data->conf;
7406         return ret;
7407 }
7408
7409 /** Parse MPLSOUDP decap action. */
7410 static int
7411 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token,
7412                                const char *str, unsigned int len,
7413                                void *buf, unsigned int size)
7414 {
7415         struct buffer *out = buf;
7416         struct rte_flow_action *action;
7417         struct action_raw_decap_data *action_decap_data;
7418         struct rte_flow_item_eth eth = { .type = 0, };
7419         struct rte_flow_item_vlan vlan = {.tci = 0};
7420         struct rte_flow_item_ipv4 ipv4 = {
7421                 .hdr =  {
7422                         .next_proto_id = IPPROTO_UDP,
7423                 },
7424         };
7425         struct rte_flow_item_ipv6 ipv6 = {
7426                 .hdr =  {
7427                         .proto = IPPROTO_UDP,
7428                 },
7429         };
7430         struct rte_flow_item_udp udp = {
7431                 .hdr = {
7432                         .dst_port = rte_cpu_to_be_16(6635),
7433                 },
7434         };
7435         struct rte_flow_item_mpls mpls;
7436         uint8_t *header;
7437         int ret;
7438
7439         ret = parse_vc(ctx, token, str, len, buf, size);
7440         if (ret < 0)
7441                 return ret;
7442         /* Nothing else to do if there is no buffer. */
7443         if (!out)
7444                 return ret;
7445         if (!out->args.vc.actions_n)
7446                 return -1;
7447         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7448         /* Point to selected object. */
7449         ctx->object = out->args.vc.data;
7450         ctx->objmask = NULL;
7451         /* Copy the headers to the buffer. */
7452         action_decap_data = ctx->object;
7453         *action_decap_data = (struct action_raw_decap_data) {
7454                 .conf = (struct rte_flow_action_raw_decap){
7455                         .data = action_decap_data->data,
7456                 },
7457                 .data = {},
7458         };
7459         header = action_decap_data->data;
7460         if (mplsoudp_decap_conf.select_vlan)
7461                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
7462         else if (mplsoudp_encap_conf.select_ipv4)
7463                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
7464         else
7465                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
7466         memcpy(eth.dst.addr_bytes,
7467                mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
7468         memcpy(eth.src.addr_bytes,
7469                mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
7470         memcpy(header, &eth, sizeof(eth));
7471         header += sizeof(eth);
7472         if (mplsoudp_encap_conf.select_vlan) {
7473                 if (mplsoudp_encap_conf.select_ipv4)
7474                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
7475                 else
7476                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
7477                 memcpy(header, &vlan, sizeof(vlan));
7478                 header += sizeof(vlan);
7479         }
7480         if (mplsoudp_encap_conf.select_ipv4) {
7481                 memcpy(header, &ipv4, sizeof(ipv4));
7482                 header += sizeof(ipv4);
7483         } else {
7484                 memcpy(header, &ipv6, sizeof(ipv6));
7485                 header += sizeof(ipv6);
7486         }
7487         memcpy(header, &udp, sizeof(udp));
7488         header += sizeof(udp);
7489         memset(&mpls, 0, sizeof(mpls));
7490         memcpy(header, &mpls, sizeof(mpls));
7491         header += sizeof(mpls);
7492         action_decap_data->conf.size = header -
7493                 action_decap_data->data;
7494         action->conf = &action_decap_data->conf;
7495         return ret;
7496 }
7497
7498 static int
7499 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token,
7500                                 const char *str, unsigned int len, void *buf,
7501                                 unsigned int size)
7502 {
7503         struct action_raw_decap_data *action_raw_decap_data;
7504         struct rte_flow_action *action;
7505         const struct arg *arg;
7506         struct buffer *out = buf;
7507         int ret;
7508         uint16_t idx;
7509
7510         RTE_SET_USED(token);
7511         RTE_SET_USED(buf);
7512         RTE_SET_USED(size);
7513         arg = ARGS_ENTRY_ARB_BOUNDED
7514                 (offsetof(struct action_raw_decap_data, idx),
7515                  sizeof(((struct action_raw_decap_data *)0)->idx),
7516                  0, RAW_ENCAP_CONFS_MAX_NUM - 1);
7517         if (push_args(ctx, arg))
7518                 return -1;
7519         ret = parse_int(ctx, token, str, len, NULL, 0);
7520         if (ret < 0) {
7521                 pop_args(ctx);
7522                 return -1;
7523         }
7524         if (!ctx->object)
7525                 return len;
7526         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7527         action_raw_decap_data = ctx->object;
7528         idx = action_raw_decap_data->idx;
7529         action_raw_decap_data->conf.data = raw_decap_confs[idx].data;
7530         action_raw_decap_data->conf.size = raw_decap_confs[idx].size;
7531         action->conf = &action_raw_decap_data->conf;
7532         return len;
7533 }
7534
7535
7536 static int
7537 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token,
7538                                 const char *str, unsigned int len, void *buf,
7539                                 unsigned int size)
7540 {
7541         struct action_raw_encap_data *action_raw_encap_data;
7542         struct rte_flow_action *action;
7543         const struct arg *arg;
7544         struct buffer *out = buf;
7545         int ret;
7546         uint16_t idx;
7547
7548         RTE_SET_USED(token);
7549         RTE_SET_USED(buf);
7550         RTE_SET_USED(size);
7551         if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE)
7552                 return -1;
7553         arg = ARGS_ENTRY_ARB_BOUNDED
7554                 (offsetof(struct action_raw_encap_data, idx),
7555                  sizeof(((struct action_raw_encap_data *)0)->idx),
7556                  0, RAW_ENCAP_CONFS_MAX_NUM - 1);
7557         if (push_args(ctx, arg))
7558                 return -1;
7559         ret = parse_int(ctx, token, str, len, NULL, 0);
7560         if (ret < 0) {
7561                 pop_args(ctx);
7562                 return -1;
7563         }
7564         if (!ctx->object)
7565                 return len;
7566         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7567         action_raw_encap_data = ctx->object;
7568         idx = action_raw_encap_data->idx;
7569         action_raw_encap_data->conf.data = raw_encap_confs[idx].data;
7570         action_raw_encap_data->conf.size = raw_encap_confs[idx].size;
7571         action_raw_encap_data->conf.preserve = NULL;
7572         action->conf = &action_raw_encap_data->conf;
7573         return len;
7574 }
7575
7576 static int
7577 parse_vc_action_raw_encap(struct context *ctx, const struct token *token,
7578                           const char *str, unsigned int len, void *buf,
7579                           unsigned int size)
7580 {
7581         struct buffer *out = buf;
7582         struct rte_flow_action *action;
7583         struct action_raw_encap_data *action_raw_encap_data = NULL;
7584         int ret;
7585
7586         ret = parse_vc(ctx, token, str, len, buf, size);
7587         if (ret < 0)
7588                 return ret;
7589         /* Nothing else to do if there is no buffer. */
7590         if (!out)
7591                 return ret;
7592         if (!out->args.vc.actions_n)
7593                 return -1;
7594         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7595         /* Point to selected object. */
7596         ctx->object = out->args.vc.data;
7597         ctx->objmask = NULL;
7598         /* Copy the headers to the buffer. */
7599         action_raw_encap_data = ctx->object;
7600         action_raw_encap_data->conf.data = raw_encap_confs[0].data;
7601         action_raw_encap_data->conf.preserve = NULL;
7602         action_raw_encap_data->conf.size = raw_encap_confs[0].size;
7603         action->conf = &action_raw_encap_data->conf;
7604         return ret;
7605 }
7606
7607 static int
7608 parse_vc_action_raw_decap(struct context *ctx, const struct token *token,
7609                           const char *str, unsigned int len, void *buf,
7610                           unsigned int size)
7611 {
7612         struct buffer *out = buf;
7613         struct rte_flow_action *action;
7614         struct action_raw_decap_data *action_raw_decap_data = NULL;
7615         int ret;
7616
7617         ret = parse_vc(ctx, token, str, len, buf, size);
7618         if (ret < 0)
7619                 return ret;
7620         /* Nothing else to do if there is no buffer. */
7621         if (!out)
7622                 return ret;
7623         if (!out->args.vc.actions_n)
7624                 return -1;
7625         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7626         /* Point to selected object. */
7627         ctx->object = out->args.vc.data;
7628         ctx->objmask = NULL;
7629         /* Copy the headers to the buffer. */
7630         action_raw_decap_data = ctx->object;
7631         action_raw_decap_data->conf.data = raw_decap_confs[0].data;
7632         action_raw_decap_data->conf.size = raw_decap_confs[0].size;
7633         action->conf = &action_raw_decap_data->conf;
7634         return ret;
7635 }
7636
7637 static int
7638 parse_vc_action_set_meta(struct context *ctx, const struct token *token,
7639                          const char *str, unsigned int len, void *buf,
7640                          unsigned int size)
7641 {
7642         int ret;
7643
7644         ret = parse_vc(ctx, token, str, len, buf, size);
7645         if (ret < 0)
7646                 return ret;
7647         ret = rte_flow_dynf_metadata_register();
7648         if (ret < 0)
7649                 return -1;
7650         return len;
7651 }
7652
7653 static int
7654 parse_vc_action_sample(struct context *ctx, const struct token *token,
7655                          const char *str, unsigned int len, void *buf,
7656                          unsigned int size)
7657 {
7658         struct buffer *out = buf;
7659         struct rte_flow_action *action;
7660         struct action_sample_data *action_sample_data = NULL;
7661         static struct rte_flow_action end_action = {
7662                 RTE_FLOW_ACTION_TYPE_END, 0
7663         };
7664         int ret;
7665
7666         ret = parse_vc(ctx, token, str, len, buf, size);
7667         if (ret < 0)
7668                 return ret;
7669         /* Nothing else to do if there is no buffer. */
7670         if (!out)
7671                 return ret;
7672         if (!out->args.vc.actions_n)
7673                 return -1;
7674         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7675         /* Point to selected object. */
7676         ctx->object = out->args.vc.data;
7677         ctx->objmask = NULL;
7678         /* Copy the headers to the buffer. */
7679         action_sample_data = ctx->object;
7680         action_sample_data->conf.actions = &end_action;
7681         action->conf = &action_sample_data->conf;
7682         return ret;
7683 }
7684
7685 static int
7686 parse_vc_action_sample_index(struct context *ctx, const struct token *token,
7687                                 const char *str, unsigned int len, void *buf,
7688                                 unsigned int size)
7689 {
7690         struct action_sample_data *action_sample_data;
7691         struct rte_flow_action *action;
7692         const struct arg *arg;
7693         struct buffer *out = buf;
7694         int ret;
7695         uint16_t idx;
7696
7697         RTE_SET_USED(token);
7698         RTE_SET_USED(buf);
7699         RTE_SET_USED(size);
7700         if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE)
7701                 return -1;
7702         arg = ARGS_ENTRY_ARB_BOUNDED
7703                 (offsetof(struct action_sample_data, idx),
7704                  sizeof(((struct action_sample_data *)0)->idx),
7705                  0, RAW_SAMPLE_CONFS_MAX_NUM - 1);
7706         if (push_args(ctx, arg))
7707                 return -1;
7708         ret = parse_int(ctx, token, str, len, NULL, 0);
7709         if (ret < 0) {
7710                 pop_args(ctx);
7711                 return -1;
7712         }
7713         if (!ctx->object)
7714                 return len;
7715         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
7716         action_sample_data = ctx->object;
7717         idx = action_sample_data->idx;
7718         action_sample_data->conf.actions = raw_sample_confs[idx].data;
7719         action->conf = &action_sample_data->conf;
7720         return len;
7721 }
7722
7723 /** Parse operation for modify_field command. */
7724 static int
7725 parse_vc_modify_field_op(struct context *ctx, const struct token *token,
7726                          const char *str, unsigned int len, void *buf,
7727                          unsigned int size)
7728 {
7729         struct rte_flow_action_modify_field *action_modify_field;
7730         unsigned int i;
7731
7732         (void)token;
7733         (void)buf;
7734         (void)size;
7735         if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE)
7736                 return -1;
7737         for (i = 0; modify_field_ops[i]; ++i)
7738                 if (!strcmp_partial(modify_field_ops[i], str, len))
7739                         break;
7740         if (!modify_field_ops[i])
7741                 return -1;
7742         if (!ctx->object)
7743                 return len;
7744         action_modify_field = ctx->object;
7745         action_modify_field->operation = (enum rte_flow_modify_op)i;
7746         return len;
7747 }
7748
7749 /** Parse id for modify_field command. */
7750 static int
7751 parse_vc_modify_field_id(struct context *ctx, const struct token *token,
7752                          const char *str, unsigned int len, void *buf,
7753                          unsigned int size)
7754 {
7755         struct rte_flow_action_modify_field *action_modify_field;
7756         unsigned int i;
7757
7758         (void)token;
7759         (void)buf;
7760         (void)size;
7761         if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE &&
7762                 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)
7763                 return -1;
7764         for (i = 0; modify_field_ids[i]; ++i)
7765                 if (!strcmp_partial(modify_field_ids[i], str, len))
7766                         break;
7767         if (!modify_field_ids[i])
7768                 return -1;
7769         if (!ctx->object)
7770                 return len;
7771         action_modify_field = ctx->object;
7772         if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE)
7773                 action_modify_field->dst.field = (enum rte_flow_field_id)i;
7774         else
7775                 action_modify_field->src.field = (enum rte_flow_field_id)i;
7776         return len;
7777 }
7778
7779 /** Parse the conntrack update, not a rte_flow_action. */
7780 static int
7781 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token,
7782                          const char *str, unsigned int len, void *buf,
7783                          unsigned int size)
7784 {
7785         struct buffer *out = buf;
7786         struct rte_flow_modify_conntrack *ct_modify = NULL;
7787
7788         (void)size;
7789         if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX &&
7790             ctx->curr != ACTION_CONNTRACK_UPDATE_DIR)
7791                 return -1;
7792         /* Token name must match. */
7793         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7794                 return -1;
7795         /* Nothing else to do if there is no buffer. */
7796         if (!out)
7797                 return len;
7798         ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data;
7799         if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) {
7800                 ct_modify->new_ct.is_original_dir =
7801                                 conntrack_context.is_original_dir;
7802                 ct_modify->direction = 1;
7803         } else {
7804                 uint32_t old_dir;
7805
7806                 old_dir = ct_modify->new_ct.is_original_dir;
7807                 memcpy(&ct_modify->new_ct, &conntrack_context,
7808                        sizeof(conntrack_context));
7809                 ct_modify->new_ct.is_original_dir = old_dir;
7810                 ct_modify->state = 1;
7811         }
7812         return len;
7813 }
7814
7815 /** Parse tokens for destroy command. */
7816 static int
7817 parse_destroy(struct context *ctx, const struct token *token,
7818               const char *str, unsigned int len,
7819               void *buf, unsigned int size)
7820 {
7821         struct buffer *out = buf;
7822
7823         /* Token name must match. */
7824         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7825                 return -1;
7826         /* Nothing else to do if there is no buffer. */
7827         if (!out)
7828                 return len;
7829         if (!out->command) {
7830                 if (ctx->curr != DESTROY)
7831                         return -1;
7832                 if (sizeof(*out) > size)
7833                         return -1;
7834                 out->command = ctx->curr;
7835                 ctx->objdata = 0;
7836                 ctx->object = out;
7837                 ctx->objmask = NULL;
7838                 out->args.destroy.rule =
7839                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
7840                                                sizeof(double));
7841                 return len;
7842         }
7843         if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) +
7844              sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size)
7845                 return -1;
7846         ctx->objdata = 0;
7847         ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++;
7848         ctx->objmask = NULL;
7849         return len;
7850 }
7851
7852 /** Parse tokens for flush command. */
7853 static int
7854 parse_flush(struct context *ctx, const struct token *token,
7855             const char *str, unsigned int len,
7856             void *buf, unsigned int size)
7857 {
7858         struct buffer *out = buf;
7859
7860         /* Token name must match. */
7861         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7862                 return -1;
7863         /* Nothing else to do if there is no buffer. */
7864         if (!out)
7865                 return len;
7866         if (!out->command) {
7867                 if (ctx->curr != FLUSH)
7868                         return -1;
7869                 if (sizeof(*out) > size)
7870                         return -1;
7871                 out->command = ctx->curr;
7872                 ctx->objdata = 0;
7873                 ctx->object = out;
7874                 ctx->objmask = NULL;
7875         }
7876         return len;
7877 }
7878
7879 /** Parse tokens for dump command. */
7880 static int
7881 parse_dump(struct context *ctx, const struct token *token,
7882             const char *str, unsigned int len,
7883             void *buf, unsigned int size)
7884 {
7885         struct buffer *out = buf;
7886
7887         /* Token name must match. */
7888         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7889                 return -1;
7890         /* Nothing else to do if there is no buffer. */
7891         if (!out)
7892                 return len;
7893         if (!out->command) {
7894                 if (ctx->curr != DUMP)
7895                         return -1;
7896                 if (sizeof(*out) > size)
7897                         return -1;
7898                 out->command = ctx->curr;
7899                 ctx->objdata = 0;
7900                 ctx->object = out;
7901                 ctx->objmask = NULL;
7902                 return len;
7903         }
7904         switch (ctx->curr) {
7905         case DUMP_ALL:
7906         case DUMP_ONE:
7907                 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false;
7908                 out->command = ctx->curr;
7909                 ctx->objdata = 0;
7910                 ctx->object = out;
7911                 ctx->objmask = NULL;
7912                 return len;
7913         default:
7914                 return -1;
7915         }
7916 }
7917
7918 /** Parse tokens for query command. */
7919 static int
7920 parse_query(struct context *ctx, const struct token *token,
7921             const char *str, unsigned int len,
7922             void *buf, unsigned int size)
7923 {
7924         struct buffer *out = buf;
7925
7926         /* Token name must match. */
7927         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7928                 return -1;
7929         /* Nothing else to do if there is no buffer. */
7930         if (!out)
7931                 return len;
7932         if (!out->command) {
7933                 if (ctx->curr != QUERY)
7934                         return -1;
7935                 if (sizeof(*out) > size)
7936                         return -1;
7937                 out->command = ctx->curr;
7938                 ctx->objdata = 0;
7939                 ctx->object = out;
7940                 ctx->objmask = NULL;
7941         }
7942         return len;
7943 }
7944
7945 /** Parse action names. */
7946 static int
7947 parse_action(struct context *ctx, const struct token *token,
7948              const char *str, unsigned int len,
7949              void *buf, unsigned int size)
7950 {
7951         struct buffer *out = buf;
7952         const struct arg *arg = pop_args(ctx);
7953         unsigned int i;
7954
7955         (void)size;
7956         /* Argument is expected. */
7957         if (!arg)
7958                 return -1;
7959         /* Parse action name. */
7960         for (i = 0; next_action[i]; ++i) {
7961                 const struct parse_action_priv *priv;
7962
7963                 token = &token_list[next_action[i]];
7964                 if (strcmp_partial(token->name, str, len))
7965                         continue;
7966                 priv = token->priv;
7967                 if (!priv)
7968                         goto error;
7969                 if (out)
7970                         memcpy((uint8_t *)ctx->object + arg->offset,
7971                                &priv->type,
7972                                arg->size);
7973                 return len;
7974         }
7975 error:
7976         push_args(ctx, arg);
7977         return -1;
7978 }
7979
7980 /** Parse tokens for list command. */
7981 static int
7982 parse_list(struct context *ctx, const struct token *token,
7983            const char *str, unsigned int len,
7984            void *buf, unsigned int size)
7985 {
7986         struct buffer *out = buf;
7987
7988         /* Token name must match. */
7989         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7990                 return -1;
7991         /* Nothing else to do if there is no buffer. */
7992         if (!out)
7993                 return len;
7994         if (!out->command) {
7995                 if (ctx->curr != LIST)
7996                         return -1;
7997                 if (sizeof(*out) > size)
7998                         return -1;
7999                 out->command = ctx->curr;
8000                 ctx->objdata = 0;
8001                 ctx->object = out;
8002                 ctx->objmask = NULL;
8003                 out->args.list.group =
8004                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
8005                                                sizeof(double));
8006                 return len;
8007         }
8008         if (((uint8_t *)(out->args.list.group + out->args.list.group_n) +
8009              sizeof(*out->args.list.group)) > (uint8_t *)out + size)
8010                 return -1;
8011         ctx->objdata = 0;
8012         ctx->object = out->args.list.group + out->args.list.group_n++;
8013         ctx->objmask = NULL;
8014         return len;
8015 }
8016
8017 /** Parse tokens for list all aged flows command. */
8018 static int
8019 parse_aged(struct context *ctx, const struct token *token,
8020            const char *str, unsigned int len,
8021            void *buf, unsigned int size)
8022 {
8023         struct buffer *out = buf;
8024
8025         /* Token name must match. */
8026         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
8027                 return -1;
8028         /* Nothing else to do if there is no buffer. */
8029         if (!out)
8030                 return len;
8031         if (!out->command) {
8032                 if (ctx->curr != AGED)
8033                         return -1;
8034                 if (sizeof(*out) > size)
8035                         return -1;
8036                 out->command = ctx->curr;
8037                 ctx->objdata = 0;
8038                 ctx->object = out;
8039                 ctx->objmask = NULL;
8040         }
8041         if (ctx->curr == AGED_DESTROY)
8042                 out->args.aged.destroy = 1;
8043         return len;
8044 }
8045
8046 /** Parse tokens for isolate command. */
8047 static int
8048 parse_isolate(struct context *ctx, const struct token *token,
8049               const char *str, unsigned int len,
8050               void *buf, unsigned int size)
8051 {
8052         struct buffer *out = buf;
8053
8054         /* Token name must match. */
8055         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
8056                 return -1;
8057         /* Nothing else to do if there is no buffer. */
8058         if (!out)
8059                 return len;
8060         if (!out->command) {
8061                 if (ctx->curr != ISOLATE)
8062                         return -1;
8063                 if (sizeof(*out) > size)
8064                         return -1;
8065                 out->command = ctx->curr;
8066                 ctx->objdata = 0;
8067                 ctx->object = out;
8068                 ctx->objmask = NULL;
8069         }
8070         return len;
8071 }
8072
8073 /** Parse tokens for info/configure command. */
8074 static int
8075 parse_configure(struct context *ctx, const struct token *token,
8076                 const char *str, unsigned int len,
8077                 void *buf, unsigned int size)
8078 {
8079         struct buffer *out = buf;
8080
8081         /* Token name must match. */
8082         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
8083                 return -1;
8084         /* Nothing else to do if there is no buffer. */
8085         if (!out)
8086                 return len;
8087         if (!out->command) {
8088                 if (ctx->curr != INFO && ctx->curr != CONFIGURE)
8089                         return -1;
8090                 if (sizeof(*out) > size)
8091                         return -1;
8092                 out->command = ctx->curr;
8093                 ctx->objdata = 0;
8094                 ctx->object = out;
8095                 ctx->objmask = NULL;
8096         }
8097         return len;
8098 }
8099
8100 /** Parse tokens for template create command. */
8101 static int
8102 parse_template(struct context *ctx, const struct token *token,
8103                const char *str, unsigned int len,
8104                void *buf, unsigned int size)
8105 {
8106         struct buffer *out = buf;
8107
8108         /* Token name must match. */
8109         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
8110                 return -1;
8111         /* Nothing else to do if there is no buffer. */
8112         if (!out)
8113                 return len;
8114         if (!out->command) {
8115                 if (ctx->curr != PATTERN_TEMPLATE &&
8116                     ctx->curr != ACTIONS_TEMPLATE)
8117                         return -1;
8118                 if (sizeof(*out) > size)
8119                         return -1;
8120                 out->command = ctx->curr;
8121                 ctx->objdata = 0;
8122                 ctx->object = out;
8123                 ctx->objmask = NULL;
8124                 out->args.vc.data = (uint8_t *)out + size;
8125                 return len;
8126         }
8127         switch (ctx->curr) {
8128         case PATTERN_TEMPLATE_CREATE:
8129                 out->args.vc.pattern =
8130                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
8131                                                sizeof(double));
8132                 out->args.vc.pat_templ_id = UINT32_MAX;
8133                 out->command = ctx->curr;
8134                 ctx->objdata = 0;
8135                 ctx->object = out;
8136                 ctx->objmask = NULL;
8137                 return len;
8138         case PATTERN_TEMPLATE_EGRESS:
8139                 out->args.vc.attr.egress = 1;
8140                 return len;
8141         case PATTERN_TEMPLATE_INGRESS:
8142                 out->args.vc.attr.ingress = 1;
8143                 return len;
8144         case PATTERN_TEMPLATE_TRANSFER:
8145                 out->args.vc.attr.transfer = 1;
8146                 return len;
8147         case ACTIONS_TEMPLATE_CREATE:
8148                 out->args.vc.act_templ_id = UINT32_MAX;
8149                 out->command = ctx->curr;
8150                 ctx->objdata = 0;
8151                 ctx->object = out;
8152                 ctx->objmask = NULL;
8153                 return len;
8154         case ACTIONS_TEMPLATE_SPEC:
8155                 out->args.vc.actions =
8156                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
8157                                                sizeof(double));
8158                 ctx->object = out->args.vc.actions;
8159                 ctx->objmask = NULL;
8160                 return len;
8161         case ACTIONS_TEMPLATE_MASK:
8162                 out->args.vc.masks =
8163                         (void *)RTE_ALIGN_CEIL((uintptr_t)
8164                                                (out->args.vc.actions +
8165                                                 out->args.vc.actions_n),
8166                                                sizeof(double));
8167                 ctx->object = out->args.vc.masks;
8168                 ctx->objmask = NULL;
8169                 return len;
8170         case ACTIONS_TEMPLATE_EGRESS:
8171                 out->args.vc.attr.egress = 1;
8172                 return len;
8173         case ACTIONS_TEMPLATE_INGRESS:
8174                 out->args.vc.attr.ingress = 1;
8175                 return len;
8176         case ACTIONS_TEMPLATE_TRANSFER:
8177                 out->args.vc.attr.transfer = 1;
8178                 return len;
8179         default:
8180                 return -1;
8181         }
8182 }
8183
8184 /** Parse tokens for template destroy command. */
8185 static int
8186 parse_template_destroy(struct context *ctx, const struct token *token,
8187                        const char *str, unsigned int len,
8188                        void *buf, unsigned int size)
8189 {
8190         struct buffer *out = buf;
8191         uint32_t *template_id;
8192
8193         /* Token name must match. */
8194         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
8195                 return -1;
8196         /* Nothing else to do if there is no buffer. */
8197         if (!out)
8198                 return len;
8199         if (!out->command ||
8200                 out->command == PATTERN_TEMPLATE ||
8201                 out->command == ACTIONS_TEMPLATE) {
8202                 if (ctx->curr != PATTERN_TEMPLATE_DESTROY &&
8203                         ctx->curr != ACTIONS_TEMPLATE_DESTROY)
8204                         return -1;
8205                 if (sizeof(*out) > size)
8206                         return -1;
8207                 out->command = ctx->curr;
8208                 ctx->objdata = 0;
8209                 ctx->object = out;
8210                 ctx->objmask = NULL;
8211                 out->args.templ_destroy.template_id =
8212                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
8213                                                sizeof(double));
8214                 return len;
8215         }
8216         template_id = out->args.templ_destroy.template_id
8217                     + out->args.templ_destroy.template_id_n++;
8218         if ((uint8_t *)template_id > (uint8_t *)out + size)
8219                 return -1;
8220         ctx->objdata = 0;
8221         ctx->object = template_id;
8222         ctx->objmask = NULL;
8223         return len;
8224 }
8225
8226 static int
8227 parse_flex(struct context *ctx, const struct token *token,
8228              const char *str, unsigned int len,
8229              void *buf, unsigned int size)
8230 {
8231         struct buffer *out = buf;
8232
8233         /* Token name must match. */
8234         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
8235                 return -1;
8236         /* Nothing else to do if there is no buffer. */
8237         if (!out)
8238                 return len;
8239         if (out->command == ZERO) {
8240                 if (ctx->curr != FLEX)
8241                         return -1;
8242                 if (sizeof(*out) > size)
8243                         return -1;
8244                 out->command = ctx->curr;
8245                 ctx->objdata = 0;
8246                 ctx->object = out;
8247                 ctx->objmask = NULL;
8248         } else {
8249                 switch (ctx->curr) {
8250                 default:
8251                         break;
8252                 case FLEX_ITEM_INIT:
8253                 case FLEX_ITEM_CREATE:
8254                 case FLEX_ITEM_DESTROY:
8255                         out->command = ctx->curr;
8256                         break;
8257                 }
8258         }
8259
8260         return len;
8261 }
8262
8263 static int
8264 parse_tunnel(struct context *ctx, const struct token *token,
8265              const char *str, unsigned int len,
8266              void *buf, unsigned int size)
8267 {
8268         struct buffer *out = buf;
8269
8270         /* Token name must match. */
8271         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
8272                 return -1;
8273         /* Nothing else to do if there is no buffer. */
8274         if (!out)
8275                 return len;
8276         if (!out->command) {
8277                 if (ctx->curr != TUNNEL)
8278                         return -1;
8279                 if (sizeof(*out) > size)
8280                         return -1;
8281                 out->command = ctx->curr;
8282                 ctx->objdata = 0;
8283                 ctx->object = out;
8284                 ctx->objmask = NULL;
8285         } else {
8286                 switch (ctx->curr) {
8287                 default:
8288                         break;
8289                 case TUNNEL_CREATE:
8290                 case TUNNEL_DESTROY:
8291                 case TUNNEL_LIST:
8292                         out->command = ctx->curr;
8293                         break;
8294                 case TUNNEL_CREATE_TYPE:
8295                 case TUNNEL_DESTROY_ID:
8296                         ctx->object = &out->args.vc.tunnel_ops;
8297                         break;
8298                 }
8299         }
8300
8301         return len;
8302 }
8303
8304 /**
8305  * Parse signed/unsigned integers 8 to 64-bit long.
8306  *
8307  * Last argument (ctx->args) is retrieved to determine integer type and
8308  * storage location.
8309  */
8310 static int
8311 parse_int(struct context *ctx, const struct token *token,
8312           const char *str, unsigned int len,
8313           void *buf, unsigned int size)
8314 {
8315         const struct arg *arg = pop_args(ctx);
8316         uintmax_t u;
8317         char *end;
8318
8319         (void)token;
8320         /* Argument is expected. */
8321         if (!arg)
8322                 return -1;
8323         errno = 0;
8324         u = arg->sign ?
8325                 (uintmax_t)strtoimax(str, &end, 0) :
8326                 strtoumax(str, &end, 0);
8327         if (errno || (size_t)(end - str) != len)
8328                 goto error;
8329         if (arg->bounded &&
8330             ((arg->sign && ((intmax_t)u < (intmax_t)arg->min ||
8331                             (intmax_t)u > (intmax_t)arg->max)) ||
8332              (!arg->sign && (u < arg->min || u > arg->max))))
8333                 goto error;
8334         if (!ctx->object)
8335                 return len;
8336         if (arg->mask) {
8337                 if (!arg_entry_bf_fill(ctx->object, u, arg) ||
8338                     !arg_entry_bf_fill(ctx->objmask, -1, arg))
8339                         goto error;
8340                 return len;
8341         }
8342         buf = (uint8_t *)ctx->object + arg->offset;
8343         size = arg->size;
8344         if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t))
8345                 return -1;
8346 objmask:
8347         switch (size) {
8348         case sizeof(uint8_t):
8349                 *(uint8_t *)buf = u;
8350                 break;
8351         case sizeof(uint16_t):
8352                 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u;
8353                 break;
8354         case sizeof(uint8_t [3]):
8355 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
8356                 if (!arg->hton) {
8357                         ((uint8_t *)buf)[0] = u;
8358                         ((uint8_t *)buf)[1] = u >> 8;
8359                         ((uint8_t *)buf)[2] = u >> 16;
8360                         break;
8361                 }
8362 #endif
8363                 ((uint8_t *)buf)[0] = u >> 16;
8364                 ((uint8_t *)buf)[1] = u >> 8;
8365                 ((uint8_t *)buf)[2] = u;
8366                 break;
8367         case sizeof(uint32_t):
8368                 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u;
8369                 break;
8370         case sizeof(uint64_t):
8371                 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u;
8372                 break;
8373         default:
8374                 goto error;
8375         }
8376         if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) {
8377                 u = -1;
8378                 buf = (uint8_t *)ctx->objmask + arg->offset;
8379                 goto objmask;
8380         }
8381         return len;
8382 error:
8383         push_args(ctx, arg);
8384         return -1;
8385 }
8386
8387 /**
8388  * Parse a string.
8389  *
8390  * Three arguments (ctx->args) are retrieved from the stack to store data,
8391  * its actual length and address (in that order).
8392  */
8393 static int
8394 parse_string(struct context *ctx, const struct token *token,
8395              const char *str, unsigned int len,
8396              void *buf, unsigned int size)
8397 {
8398         const struct arg *arg_data = pop_args(ctx);
8399         const struct arg *arg_len = pop_args(ctx);
8400         const struct arg *arg_addr = pop_args(ctx);
8401         char tmp[16]; /* Ought to be enough. */
8402         int ret;
8403
8404         /* Arguments are expected. */
8405         if (!arg_data)
8406                 return -1;
8407         if (!arg_len) {
8408                 push_args(ctx, arg_data);
8409                 return -1;
8410         }
8411         if (!arg_addr) {
8412                 push_args(ctx, arg_len);
8413                 push_args(ctx, arg_data);
8414                 return -1;
8415         }
8416         size = arg_data->size;
8417         /* Bit-mask fill is not supported. */
8418         if (arg_data->mask || size < len)
8419                 goto error;
8420         if (!ctx->object)
8421                 return len;
8422         /* Let parse_int() fill length information first. */
8423         ret = snprintf(tmp, sizeof(tmp), "%u", len);
8424         if (ret < 0)
8425                 goto error;
8426         push_args(ctx, arg_len);
8427         ret = parse_int(ctx, token, tmp, ret, NULL, 0);
8428         if (ret < 0) {
8429                 pop_args(ctx);
8430                 goto error;
8431         }
8432         buf = (uint8_t *)ctx->object + arg_data->offset;
8433         /* Output buffer is not necessarily NUL-terminated. */
8434         memcpy(buf, str, len);
8435         memset((uint8_t *)buf + len, 0x00, size - len);
8436         if (ctx->objmask)
8437                 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len);
8438         /* Save address if requested. */
8439         if (arg_addr->size) {
8440                 memcpy((uint8_t *)ctx->object + arg_addr->offset,
8441                        (void *[]){
8442                         (uint8_t *)ctx->object + arg_data->offset
8443                        },
8444                        arg_addr->size);
8445                 if (ctx->objmask)
8446                         memcpy((uint8_t *)ctx->objmask + arg_addr->offset,
8447                                (void *[]){
8448                                 (uint8_t *)ctx->objmask + arg_data->offset
8449                                },
8450                                arg_addr->size);
8451         }
8452         return len;
8453 error:
8454         push_args(ctx, arg_addr);
8455         push_args(ctx, arg_len);
8456         push_args(ctx, arg_data);
8457         return -1;
8458 }
8459
8460 static int
8461 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size)
8462 {
8463         const uint8_t *head = dst;
8464         uint32_t left;
8465
8466         /* Check input parameters */
8467         if ((src == NULL) ||
8468                 (dst == NULL) ||
8469                 (size == NULL) ||
8470                 (*size == 0))
8471                 return -1;
8472
8473         left = *size;
8474
8475         /* Convert chars to bytes */
8476         while (left) {
8477                 char tmp[3], *end = tmp;
8478                 uint32_t read_lim = left & 1 ? 1 : 2;
8479
8480                 snprintf(tmp, read_lim + 1, "%s", src);
8481                 *dst = strtoul(tmp, &end, 16);
8482                 if (*end) {
8483                         *dst = 0;
8484                         *size = (uint32_t)(dst - head);
8485                         return -1;
8486                 }
8487                 left -= read_lim;
8488                 src += read_lim;
8489                 dst++;
8490         }
8491         *dst = 0;
8492         *size = (uint32_t)(dst - head);
8493         return 0;
8494 }
8495
8496 static int
8497 parse_hex(struct context *ctx, const struct token *token,
8498                 const char *str, unsigned int len,
8499                 void *buf, unsigned int size)
8500 {
8501         const struct arg *arg_data = pop_args(ctx);
8502         const struct arg *arg_len = pop_args(ctx);
8503         const struct arg *arg_addr = pop_args(ctx);
8504         char tmp[16]; /* Ought to be enough. */
8505         int ret;
8506         unsigned int hexlen = len;
8507         unsigned int length = 256;
8508         uint8_t hex_tmp[length];
8509
8510         /* Arguments are expected. */
8511         if (!arg_data)
8512                 return -1;
8513         if (!arg_len) {
8514                 push_args(ctx, arg_data);
8515                 return -1;
8516         }
8517         if (!arg_addr) {
8518                 push_args(ctx, arg_len);
8519                 push_args(ctx, arg_data);
8520                 return -1;
8521         }
8522         size = arg_data->size;
8523         /* Bit-mask fill is not supported. */
8524         if (arg_data->mask)
8525                 goto error;
8526         if (!ctx->object)
8527                 return len;
8528
8529         /* translate bytes string to array. */
8530         if (str[0] == '0' && ((str[1] == 'x') ||
8531                         (str[1] == 'X'))) {
8532                 str += 2;
8533                 hexlen -= 2;
8534         }
8535         if (hexlen > length)
8536                 goto error;
8537         ret = parse_hex_string(str, hex_tmp, &hexlen);
8538         if (ret < 0)
8539                 goto error;
8540         /* Check the converted binary fits into data buffer. */
8541         if (hexlen > size)
8542                 goto error;
8543         /* Let parse_int() fill length information first. */
8544         ret = snprintf(tmp, sizeof(tmp), "%u", hexlen);
8545         if (ret < 0)
8546                 goto error;
8547         /* Save length if requested. */
8548         if (arg_len->size) {
8549                 push_args(ctx, arg_len);
8550                 ret = parse_int(ctx, token, tmp, ret, NULL, 0);
8551                 if (ret < 0) {
8552                         pop_args(ctx);
8553                         goto error;
8554                 }
8555         }
8556         buf = (uint8_t *)ctx->object + arg_data->offset;
8557         /* Output buffer is not necessarily NUL-terminated. */
8558         memcpy(buf, hex_tmp, hexlen);
8559         memset((uint8_t *)buf + hexlen, 0x00, size - hexlen);
8560         if (ctx->objmask)
8561                 memset((uint8_t *)ctx->objmask + arg_data->offset,
8562                                         0xff, hexlen);
8563         /* Save address if requested. */
8564         if (arg_addr->size) {
8565                 memcpy((uint8_t *)ctx->object + arg_addr->offset,
8566                        (void *[]){
8567                         (uint8_t *)ctx->object + arg_data->offset
8568                        },
8569                        arg_addr->size);
8570                 if (ctx->objmask)
8571                         memcpy((uint8_t *)ctx->objmask + arg_addr->offset,
8572                                (void *[]){
8573                                 (uint8_t *)ctx->objmask + arg_data->offset
8574                                },
8575                                arg_addr->size);
8576         }
8577         return len;
8578 error:
8579         push_args(ctx, arg_addr);
8580         push_args(ctx, arg_len);
8581         push_args(ctx, arg_data);
8582         return -1;
8583
8584 }
8585
8586 /**
8587  * Parse a zero-ended string.
8588  */
8589 static int
8590 parse_string0(struct context *ctx, const struct token *token __rte_unused,
8591              const char *str, unsigned int len,
8592              void *buf, unsigned int size)
8593 {
8594         const struct arg *arg_data = pop_args(ctx);
8595
8596         /* Arguments are expected. */
8597         if (!arg_data)
8598                 return -1;
8599         size = arg_data->size;
8600         /* Bit-mask fill is not supported. */
8601         if (arg_data->mask || size < len + 1)
8602                 goto error;
8603         if (!ctx->object)
8604                 return len;
8605         buf = (uint8_t *)ctx->object + arg_data->offset;
8606         strncpy(buf, str, len);
8607         if (ctx->objmask)
8608                 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len);
8609         return len;
8610 error:
8611         push_args(ctx, arg_data);
8612         return -1;
8613 }
8614
8615 /**
8616  * Parse a MAC address.
8617  *
8618  * Last argument (ctx->args) is retrieved to determine storage size and
8619  * location.
8620  */
8621 static int
8622 parse_mac_addr(struct context *ctx, const struct token *token,
8623                const char *str, unsigned int len,
8624                void *buf, unsigned int size)
8625 {
8626         const struct arg *arg = pop_args(ctx);
8627         struct rte_ether_addr tmp;
8628         int ret;
8629
8630         (void)token;
8631         /* Argument is expected. */
8632         if (!arg)
8633                 return -1;
8634         size = arg->size;
8635         /* Bit-mask fill is not supported. */
8636         if (arg->mask || size != sizeof(tmp))
8637                 goto error;
8638         /* Only network endian is supported. */
8639         if (!arg->hton)
8640                 goto error;
8641         ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
8642         if (ret < 0 || (unsigned int)ret != len)
8643                 goto error;
8644         if (!ctx->object)
8645                 return len;
8646         buf = (uint8_t *)ctx->object + arg->offset;
8647         memcpy(buf, &tmp, size);
8648         if (ctx->objmask)
8649                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
8650         return len;
8651 error:
8652         push_args(ctx, arg);
8653         return -1;
8654 }
8655
8656 /**
8657  * Parse an IPv4 address.
8658  *
8659  * Last argument (ctx->args) is retrieved to determine storage size and
8660  * location.
8661  */
8662 static int
8663 parse_ipv4_addr(struct context *ctx, const struct token *token,
8664                 const char *str, unsigned int len,
8665                 void *buf, unsigned int size)
8666 {
8667         const struct arg *arg = pop_args(ctx);
8668         char str2[len + 1];
8669         struct in_addr tmp;
8670         int ret;
8671
8672         /* Argument is expected. */
8673         if (!arg)
8674                 return -1;
8675         size = arg->size;
8676         /* Bit-mask fill is not supported. */
8677         if (arg->mask || size != sizeof(tmp))
8678                 goto error;
8679         /* Only network endian is supported. */
8680         if (!arg->hton)
8681                 goto error;
8682         memcpy(str2, str, len);
8683         str2[len] = '\0';
8684         ret = inet_pton(AF_INET, str2, &tmp);
8685         if (ret != 1) {
8686                 /* Attempt integer parsing. */
8687                 push_args(ctx, arg);
8688                 return parse_int(ctx, token, str, len, buf, size);
8689         }
8690         if (!ctx->object)
8691                 return len;
8692         buf = (uint8_t *)ctx->object + arg->offset;
8693         memcpy(buf, &tmp, size);
8694         if (ctx->objmask)
8695                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
8696         return len;
8697 error:
8698         push_args(ctx, arg);
8699         return -1;
8700 }
8701
8702 /**
8703  * Parse an IPv6 address.
8704  *
8705  * Last argument (ctx->args) is retrieved to determine storage size and
8706  * location.
8707  */
8708 static int
8709 parse_ipv6_addr(struct context *ctx, const struct token *token,
8710                 const char *str, unsigned int len,
8711                 void *buf, unsigned int size)
8712 {
8713         const struct arg *arg = pop_args(ctx);
8714         char str2[len + 1];
8715         struct in6_addr tmp;
8716         int ret;
8717
8718         (void)token;
8719         /* Argument is expected. */
8720         if (!arg)
8721                 return -1;
8722         size = arg->size;
8723         /* Bit-mask fill is not supported. */
8724         if (arg->mask || size != sizeof(tmp))
8725                 goto error;
8726         /* Only network endian is supported. */
8727         if (!arg->hton)
8728                 goto error;
8729         memcpy(str2, str, len);
8730         str2[len] = '\0';
8731         ret = inet_pton(AF_INET6, str2, &tmp);
8732         if (ret != 1)
8733                 goto error;
8734         if (!ctx->object)
8735                 return len;
8736         buf = (uint8_t *)ctx->object + arg->offset;
8737         memcpy(buf, &tmp, size);
8738         if (ctx->objmask)
8739                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
8740         return len;
8741 error:
8742         push_args(ctx, arg);
8743         return -1;
8744 }
8745
8746 /** Boolean values (even indices stand for false). */
8747 static const char *const boolean_name[] = {
8748         "0", "1",
8749         "false", "true",
8750         "no", "yes",
8751         "N", "Y",
8752         "off", "on",
8753         NULL,
8754 };
8755
8756 /**
8757  * Parse a boolean value.
8758  *
8759  * Last argument (ctx->args) is retrieved to determine storage size and
8760  * location.
8761  */
8762 static int
8763 parse_boolean(struct context *ctx, const struct token *token,
8764               const char *str, unsigned int len,
8765               void *buf, unsigned int size)
8766 {
8767         const struct arg *arg = pop_args(ctx);
8768         unsigned int i;
8769         int ret;
8770
8771         /* Argument is expected. */
8772         if (!arg)
8773                 return -1;
8774         for (i = 0; boolean_name[i]; ++i)
8775                 if (!strcmp_partial(boolean_name[i], str, len))
8776                         break;
8777         /* Process token as integer. */
8778         if (boolean_name[i])
8779                 str = i & 1 ? "1" : "0";
8780         push_args(ctx, arg);
8781         ret = parse_int(ctx, token, str, strlen(str), buf, size);
8782         return ret > 0 ? (int)len : ret;
8783 }
8784
8785 /** Parse port and update context. */
8786 static int
8787 parse_port(struct context *ctx, const struct token *token,
8788            const char *str, unsigned int len,
8789            void *buf, unsigned int size)
8790 {
8791         struct buffer *out = &(struct buffer){ .port = 0 };
8792         int ret;
8793
8794         if (buf)
8795                 out = buf;
8796         else {
8797                 ctx->objdata = 0;
8798                 ctx->object = out;
8799                 ctx->objmask = NULL;
8800                 size = sizeof(*out);
8801         }
8802         ret = parse_int(ctx, token, str, len, out, size);
8803         if (ret >= 0)
8804                 ctx->port = out->port;
8805         if (!buf)
8806                 ctx->object = NULL;
8807         return ret;
8808 }
8809
8810 static int
8811 parse_ia_id2ptr(struct context *ctx, const struct token *token,
8812                 const char *str, unsigned int len,
8813                 void *buf, unsigned int size)
8814 {
8815         struct rte_flow_action *action = ctx->object;
8816         uint32_t id;
8817         int ret;
8818
8819         (void)buf;
8820         (void)size;
8821         ctx->objdata = 0;
8822         ctx->object = &id;
8823         ctx->objmask = NULL;
8824         ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id));
8825         ctx->object = action;
8826         if (ret != (int)len)
8827                 return ret;
8828         /* set indirect action */
8829         if (action) {
8830                 action->conf = port_action_handle_get_by_id(ctx->port, id);
8831                 ret = (action->conf) ? ret : -1;
8832         }
8833         return ret;
8834 }
8835
8836 /** Parse set command, initialize output buffer for subsequent tokens. */
8837 static int
8838 parse_set_raw_encap_decap(struct context *ctx, const struct token *token,
8839                           const char *str, unsigned int len,
8840                           void *buf, unsigned int size)
8841 {
8842         struct buffer *out = buf;
8843
8844         /* Token name must match. */
8845         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
8846                 return -1;
8847         /* Nothing else to do if there is no buffer. */
8848         if (!out)
8849                 return len;
8850         /* Make sure buffer is large enough. */
8851         if (size < sizeof(*out))
8852                 return -1;
8853         ctx->objdata = 0;
8854         ctx->objmask = NULL;
8855         ctx->object = out;
8856         if (!out->command)
8857                 return -1;
8858         out->command = ctx->curr;
8859         /* For encap/decap we need is pattern */
8860         out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
8861                                                        sizeof(double));
8862         return len;
8863 }
8864
8865 /** Parse set command, initialize output buffer for subsequent tokens. */
8866 static int
8867 parse_set_sample_action(struct context *ctx, const struct token *token,
8868                           const char *str, unsigned int len,
8869                           void *buf, unsigned int size)
8870 {
8871         struct buffer *out = buf;
8872
8873         /* Token name must match. */
8874         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
8875                 return -1;
8876         /* Nothing else to do if there is no buffer. */
8877         if (!out)
8878                 return len;
8879         /* Make sure buffer is large enough. */
8880         if (size < sizeof(*out))
8881                 return -1;
8882         ctx->objdata = 0;
8883         ctx->objmask = NULL;
8884         ctx->object = out;
8885         if (!out->command)
8886                 return -1;
8887         out->command = ctx->curr;
8888         /* For sampler we need is actions */
8889         out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
8890                                                        sizeof(double));
8891         return len;
8892 }
8893
8894 /**
8895  * Parse set raw_encap/raw_decap command,
8896  * initialize output buffer for subsequent tokens.
8897  */
8898 static int
8899 parse_set_init(struct context *ctx, const struct token *token,
8900                const char *str, unsigned int len,
8901                void *buf, unsigned int size)
8902 {
8903         struct buffer *out = buf;
8904
8905         /* Token name must match. */
8906         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
8907                 return -1;
8908         /* Nothing else to do if there is no buffer. */
8909         if (!out)
8910                 return len;
8911         /* Make sure buffer is large enough. */
8912         if (size < sizeof(*out))
8913                 return -1;
8914         /* Initialize buffer. */
8915         memset(out, 0x00, sizeof(*out));
8916         memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out));
8917         ctx->objdata = 0;
8918         ctx->object = out;
8919         ctx->objmask = NULL;
8920         if (!out->command) {
8921                 if (ctx->curr != SET)
8922                         return -1;
8923                 if (sizeof(*out) > size)
8924                         return -1;
8925                 out->command = ctx->curr;
8926                 out->args.vc.data = (uint8_t *)out + size;
8927                 ctx->object  = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
8928                                                        sizeof(double));
8929         }
8930         return len;
8931 }
8932
8933 /*
8934  * Replace testpmd handles in a flex flow item with real values.
8935  */
8936 static int
8937 parse_flex_handle(struct context *ctx, const struct token *token,
8938                   const char *str, unsigned int len,
8939                   void *buf, unsigned int size)
8940 {
8941         struct rte_flow_item_flex *spec, *mask;
8942         const struct rte_flow_item_flex *src_spec, *src_mask;
8943         const struct arg *arg = pop_args(ctx);
8944         uint32_t offset;
8945         uint16_t handle;
8946         int ret;
8947
8948         if (!arg) {
8949                 printf("Bad environment\n");
8950                 return -1;
8951         }
8952         offset = arg->offset;
8953         push_args(ctx, arg);
8954         ret = parse_int(ctx, token, str, len, buf, size);
8955         if (ret <= 0 || !ctx->object)
8956                 return ret;
8957         if (ctx->port >= RTE_MAX_ETHPORTS) {
8958                 printf("Bad port\n");
8959                 return -1;
8960         }
8961         if (offset == offsetof(struct rte_flow_item_flex, handle)) {
8962                 const struct flex_item *fp;
8963                 struct rte_flow_item_flex *item_flex = ctx->object;
8964                 handle = (uint16_t)(uintptr_t)item_flex->handle;
8965                 if (handle >= FLEX_MAX_PARSERS_NUM) {
8966                         printf("Bad flex item handle\n");
8967                         return -1;
8968                 }
8969                 fp = flex_items[ctx->port][handle];
8970                 if (!fp) {
8971                         printf("Bad flex item handle\n");
8972                         return -1;
8973                 }
8974                 item_flex->handle = fp->flex_handle;
8975         } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) {
8976                 handle = (uint16_t)(uintptr_t)
8977                         ((struct rte_flow_item_flex *)ctx->object)->pattern;
8978                 if (handle >= FLEX_MAX_PATTERNS_NUM) {
8979                         printf("Bad pattern handle\n");
8980                         return -1;
8981                 }
8982                 src_spec = &flex_patterns[handle].spec;
8983                 src_mask = &flex_patterns[handle].mask;
8984                 spec = ctx->object;
8985                 mask = spec + 2; /* spec, last, mask */
8986                 /* fill flow rule spec and mask parameters */
8987                 spec->length = src_spec->length;
8988                 spec->pattern = src_spec->pattern;
8989                 mask->length = src_mask->length;
8990                 mask->pattern = src_mask->pattern;
8991         } else {
8992                 printf("Bad arguments - unknown flex item offset\n");
8993                 return -1;
8994         }
8995         return ret;
8996 }
8997
8998 /** No completion. */
8999 static int
9000 comp_none(struct context *ctx, const struct token *token,
9001           unsigned int ent, char *buf, unsigned int size)
9002 {
9003         (void)ctx;
9004         (void)token;
9005         (void)ent;
9006         (void)buf;
9007         (void)size;
9008         return 0;
9009 }
9010
9011 /** Complete boolean values. */
9012 static int
9013 comp_boolean(struct context *ctx, const struct token *token,
9014              unsigned int ent, char *buf, unsigned int size)
9015 {
9016         unsigned int i;
9017
9018         (void)ctx;
9019         (void)token;
9020         for (i = 0; boolean_name[i]; ++i)
9021                 if (buf && i == ent)
9022                         return strlcpy(buf, boolean_name[i], size);
9023         if (buf)
9024                 return -1;
9025         return i;
9026 }
9027
9028 /** Complete action names. */
9029 static int
9030 comp_action(struct context *ctx, const struct token *token,
9031             unsigned int ent, char *buf, unsigned int size)
9032 {
9033         unsigned int i;
9034
9035         (void)ctx;
9036         (void)token;
9037         for (i = 0; next_action[i]; ++i)
9038                 if (buf && i == ent)
9039                         return strlcpy(buf, token_list[next_action[i]].name,
9040                                        size);
9041         if (buf)
9042                 return -1;
9043         return i;
9044 }
9045
9046 /** Complete available ports. */
9047 static int
9048 comp_port(struct context *ctx, const struct token *token,
9049           unsigned int ent, char *buf, unsigned int size)
9050 {
9051         unsigned int i = 0;
9052         portid_t p;
9053
9054         (void)ctx;
9055         (void)token;
9056         RTE_ETH_FOREACH_DEV(p) {
9057                 if (buf && i == ent)
9058                         return snprintf(buf, size, "%u", p);
9059                 ++i;
9060         }
9061         if (buf)
9062                 return -1;
9063         return i;
9064 }
9065
9066 /** Complete available rule IDs. */
9067 static int
9068 comp_rule_id(struct context *ctx, const struct token *token,
9069              unsigned int ent, char *buf, unsigned int size)
9070 {
9071         unsigned int i = 0;
9072         struct rte_port *port;
9073         struct port_flow *pf;
9074
9075         (void)token;
9076         if (port_id_is_invalid(ctx->port, DISABLED_WARN) ||
9077             ctx->port == (portid_t)RTE_PORT_ALL)
9078                 return -1;
9079         port = &ports[ctx->port];
9080         for (pf = port->flow_list; pf != NULL; pf = pf->next) {
9081                 if (buf && i == ent)
9082                         return snprintf(buf, size, "%u", pf->id);
9083                 ++i;
9084         }
9085         if (buf)
9086                 return -1;
9087         return i;
9088 }
9089
9090 /** Complete type field for RSS action. */
9091 static int
9092 comp_vc_action_rss_type(struct context *ctx, const struct token *token,
9093                         unsigned int ent, char *buf, unsigned int size)
9094 {
9095         unsigned int i;
9096
9097         (void)ctx;
9098         (void)token;
9099         for (i = 0; rss_type_table[i].str; ++i)
9100                 ;
9101         if (!buf)
9102                 return i + 1;
9103         if (ent < i)
9104                 return strlcpy(buf, rss_type_table[ent].str, size);
9105         if (ent == i)
9106                 return snprintf(buf, size, "end");
9107         return -1;
9108 }
9109
9110 /** Complete queue field for RSS action. */
9111 static int
9112 comp_vc_action_rss_queue(struct context *ctx, const struct token *token,
9113                          unsigned int ent, char *buf, unsigned int size)
9114 {
9115         (void)ctx;
9116         (void)token;
9117         if (!buf)
9118                 return nb_rxq + 1;
9119         if (ent < nb_rxq)
9120                 return snprintf(buf, size, "%u", ent);
9121         if (ent == nb_rxq)
9122                 return snprintf(buf, size, "end");
9123         return -1;
9124 }
9125
9126 /** Complete index number for set raw_encap/raw_decap commands. */
9127 static int
9128 comp_set_raw_index(struct context *ctx, const struct token *token,
9129                    unsigned int ent, char *buf, unsigned int size)
9130 {
9131         uint16_t idx = 0;
9132         uint16_t nb = 0;
9133
9134         RTE_SET_USED(ctx);
9135         RTE_SET_USED(token);
9136         for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) {
9137                 if (buf && idx == ent)
9138                         return snprintf(buf, size, "%u", idx);
9139                 ++nb;
9140         }
9141         return nb;
9142 }
9143
9144 /** Complete index number for set raw_encap/raw_decap commands. */
9145 static int
9146 comp_set_sample_index(struct context *ctx, const struct token *token,
9147                    unsigned int ent, char *buf, unsigned int size)
9148 {
9149         uint16_t idx = 0;
9150         uint16_t nb = 0;
9151
9152         RTE_SET_USED(ctx);
9153         RTE_SET_USED(token);
9154         for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) {
9155                 if (buf && idx == ent)
9156                         return snprintf(buf, size, "%u", idx);
9157                 ++nb;
9158         }
9159         return nb;
9160 }
9161
9162 /** Complete operation for modify_field command. */
9163 static int
9164 comp_set_modify_field_op(struct context *ctx, const struct token *token,
9165                    unsigned int ent, char *buf, unsigned int size)
9166 {
9167         RTE_SET_USED(ctx);
9168         RTE_SET_USED(token);
9169         if (!buf)
9170                 return RTE_DIM(modify_field_ops);
9171         if (ent < RTE_DIM(modify_field_ops) - 1)
9172                 return strlcpy(buf, modify_field_ops[ent], size);
9173         return -1;
9174 }
9175
9176 /** Complete field id for modify_field command. */
9177 static int
9178 comp_set_modify_field_id(struct context *ctx, const struct token *token,
9179                    unsigned int ent, char *buf, unsigned int size)
9180 {
9181         const char *name;
9182
9183         RTE_SET_USED(token);
9184         if (!buf)
9185                 return RTE_DIM(modify_field_ids);
9186         if (ent >= RTE_DIM(modify_field_ids) - 1)
9187                 return -1;
9188         name = modify_field_ids[ent];
9189         if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE ||
9190             (strcmp(name, "pointer") && strcmp(name, "value")))
9191                 return strlcpy(buf, name, size);
9192         return -1;
9193 }
9194
9195 /** Complete available pattern template IDs. */
9196 static int
9197 comp_pattern_template_id(struct context *ctx, const struct token *token,
9198                          unsigned int ent, char *buf, unsigned int size)
9199 {
9200         unsigned int i = 0;
9201         struct rte_port *port;
9202         struct port_template *pt;
9203
9204         (void)token;
9205         if (port_id_is_invalid(ctx->port, DISABLED_WARN) ||
9206             ctx->port == (portid_t)RTE_PORT_ALL)
9207                 return -1;
9208         port = &ports[ctx->port];
9209         for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) {
9210                 if (buf && i == ent)
9211                         return snprintf(buf, size, "%u", pt->id);
9212                 ++i;
9213         }
9214         if (buf)
9215                 return -1;
9216         return i;
9217 }
9218
9219 /** Complete available actions template IDs. */
9220 static int
9221 comp_actions_template_id(struct context *ctx, const struct token *token,
9222                          unsigned int ent, char *buf, unsigned int size)
9223 {
9224         unsigned int i = 0;
9225         struct rte_port *port;
9226         struct port_template *pt;
9227
9228         (void)token;
9229         if (port_id_is_invalid(ctx->port, DISABLED_WARN) ||
9230             ctx->port == (portid_t)RTE_PORT_ALL)
9231                 return -1;
9232         port = &ports[ctx->port];
9233         for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) {
9234                 if (buf && i == ent)
9235                         return snprintf(buf, size, "%u", pt->id);
9236                 ++i;
9237         }
9238         if (buf)
9239                 return -1;
9240         return i;
9241 }
9242
9243 /** Internal context. */
9244 static struct context cmd_flow_context;
9245
9246 /** Global parser instance (cmdline API). */
9247 cmdline_parse_inst_t cmd_flow;
9248 cmdline_parse_inst_t cmd_set_raw;
9249
9250 /** Initialize context. */
9251 static void
9252 cmd_flow_context_init(struct context *ctx)
9253 {
9254         /* A full memset() is not necessary. */
9255         ctx->curr = ZERO;
9256         ctx->prev = ZERO;
9257         ctx->next_num = 0;
9258         ctx->args_num = 0;
9259         ctx->eol = 0;
9260         ctx->last = 0;
9261         ctx->port = 0;
9262         ctx->objdata = 0;
9263         ctx->object = NULL;
9264         ctx->objmask = NULL;
9265 }
9266
9267 /** Parse a token (cmdline API). */
9268 static int
9269 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result,
9270                unsigned int size)
9271 {
9272         struct context *ctx = &cmd_flow_context;
9273         const struct token *token;
9274         const enum index *list;
9275         int len;
9276         int i;
9277
9278         (void)hdr;
9279         token = &token_list[ctx->curr];
9280         /* Check argument length. */
9281         ctx->eol = 0;
9282         ctx->last = 1;
9283         for (len = 0; src[len]; ++len)
9284                 if (src[len] == '#' || isspace(src[len]))
9285                         break;
9286         if (!len)
9287                 return -1;
9288         /* Last argument and EOL detection. */
9289         for (i = len; src[i]; ++i)
9290                 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n')
9291                         break;
9292                 else if (!isspace(src[i])) {
9293                         ctx->last = 0;
9294                         break;
9295                 }
9296         for (; src[i]; ++i)
9297                 if (src[i] == '\r' || src[i] == '\n') {
9298                         ctx->eol = 1;
9299                         break;
9300                 }
9301         /* Initialize context if necessary. */
9302         if (!ctx->next_num) {
9303                 if (!token->next)
9304                         return 0;
9305                 ctx->next[ctx->next_num++] = token->next[0];
9306         }
9307         /* Process argument through candidates. */
9308         ctx->prev = ctx->curr;
9309         list = ctx->next[ctx->next_num - 1];
9310         for (i = 0; list[i]; ++i) {
9311                 const struct token *next = &token_list[list[i]];
9312                 int tmp;
9313
9314                 ctx->curr = list[i];
9315                 if (next->call)
9316                         tmp = next->call(ctx, next, src, len, result, size);
9317                 else
9318                         tmp = parse_default(ctx, next, src, len, result, size);
9319                 if (tmp == -1 || tmp != len)
9320                         continue;
9321                 token = next;
9322                 break;
9323         }
9324         if (!list[i])
9325                 return -1;
9326         --ctx->next_num;
9327         /* Push subsequent tokens if any. */
9328         if (token->next)
9329                 for (i = 0; token->next[i]; ++i) {
9330                         if (ctx->next_num == RTE_DIM(ctx->next))
9331                                 return -1;
9332                         ctx->next[ctx->next_num++] = token->next[i];
9333                 }
9334         /* Push arguments if any. */
9335         if (token->args)
9336                 for (i = 0; token->args[i]; ++i) {
9337                         if (ctx->args_num == RTE_DIM(ctx->args))
9338                                 return -1;
9339                         ctx->args[ctx->args_num++] = token->args[i];
9340                 }
9341         return len;
9342 }
9343
9344 int
9345 flow_parse(const char *src, void *result, unsigned int size,
9346            struct rte_flow_attr **attr,
9347            struct rte_flow_item **pattern, struct rte_flow_action **actions)
9348 {
9349         int ret;
9350         struct context saved_flow_ctx = cmd_flow_context;
9351
9352         cmd_flow_context_init(&cmd_flow_context);
9353         do {
9354                 ret = cmd_flow_parse(NULL, src, result, size);
9355                 if (ret > 0) {
9356                         src += ret;
9357                         while (isspace(*src))
9358                                 src++;
9359                 }
9360         } while (ret > 0 && strlen(src));
9361         cmd_flow_context = saved_flow_ctx;
9362         *attr = &((struct buffer *)result)->args.vc.attr;
9363         *pattern = ((struct buffer *)result)->args.vc.pattern;
9364         *actions = ((struct buffer *)result)->args.vc.actions;
9365         return (ret >= 0 && !strlen(src)) ? 0 : -1;
9366 }
9367
9368 /** Return number of completion entries (cmdline API). */
9369 static int
9370 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr)
9371 {
9372         struct context *ctx = &cmd_flow_context;
9373         const struct token *token = &token_list[ctx->curr];
9374         const enum index *list;
9375         int i;
9376
9377         (void)hdr;
9378         /* Count number of tokens in current list. */
9379         if (ctx->next_num)
9380                 list = ctx->next[ctx->next_num - 1];
9381         else
9382                 list = token->next[0];
9383         for (i = 0; list[i]; ++i)
9384                 ;
9385         if (!i)
9386                 return 0;
9387         /*
9388          * If there is a single token, use its completion callback, otherwise
9389          * return the number of entries.
9390          */
9391         token = &token_list[list[0]];
9392         if (i == 1 && token->comp) {
9393                 /* Save index for cmd_flow_get_help(). */
9394                 ctx->prev = list[0];
9395                 return token->comp(ctx, token, 0, NULL, 0);
9396         }
9397         return i;
9398 }
9399
9400 /** Return a completion entry (cmdline API). */
9401 static int
9402 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index,
9403                           char *dst, unsigned int size)
9404 {
9405         struct context *ctx = &cmd_flow_context;
9406         const struct token *token = &token_list[ctx->curr];
9407         const enum index *list;
9408         int i;
9409
9410         (void)hdr;
9411         /* Count number of tokens in current list. */
9412         if (ctx->next_num)
9413                 list = ctx->next[ctx->next_num - 1];
9414         else
9415                 list = token->next[0];
9416         for (i = 0; list[i]; ++i)
9417                 ;
9418         if (!i)
9419                 return -1;
9420         /* If there is a single token, use its completion callback. */
9421         token = &token_list[list[0]];
9422         if (i == 1 && token->comp) {
9423                 /* Save index for cmd_flow_get_help(). */
9424                 ctx->prev = list[0];
9425                 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0;
9426         }
9427         /* Otherwise make sure the index is valid and use defaults. */
9428         if (index >= i)
9429                 return -1;
9430         token = &token_list[list[index]];
9431         strlcpy(dst, token->name, size);
9432         /* Save index for cmd_flow_get_help(). */
9433         ctx->prev = list[index];
9434         return 0;
9435 }
9436
9437 /** Populate help strings for current token (cmdline API). */
9438 static int
9439 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size)
9440 {
9441         struct context *ctx = &cmd_flow_context;
9442         const struct token *token = &token_list[ctx->prev];
9443
9444         (void)hdr;
9445         if (!size)
9446                 return -1;
9447         /* Set token type and update global help with details. */
9448         strlcpy(dst, (token->type ? token->type : "TOKEN"), size);
9449         if (token->help)
9450                 cmd_flow.help_str = token->help;
9451         else
9452                 cmd_flow.help_str = token->name;
9453         return 0;
9454 }
9455
9456 /** Token definition template (cmdline API). */
9457 static struct cmdline_token_hdr cmd_flow_token_hdr = {
9458         .ops = &(struct cmdline_token_ops){
9459                 .parse = cmd_flow_parse,
9460                 .complete_get_nb = cmd_flow_complete_get_nb,
9461                 .complete_get_elt = cmd_flow_complete_get_elt,
9462                 .get_help = cmd_flow_get_help,
9463         },
9464         .offset = 0,
9465 };
9466
9467 /** Populate the next dynamic token. */
9468 static void
9469 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr,
9470              cmdline_parse_token_hdr_t **hdr_inst)
9471 {
9472         struct context *ctx = &cmd_flow_context;
9473
9474         /* Always reinitialize context before requesting the first token. */
9475         if (!(hdr_inst - cmd_flow.tokens))
9476                 cmd_flow_context_init(ctx);
9477         /* Return NULL when no more tokens are expected. */
9478         if (!ctx->next_num && ctx->curr) {
9479                 *hdr = NULL;
9480                 return;
9481         }
9482         /* Determine if command should end here. */
9483         if (ctx->eol && ctx->last && ctx->next_num) {
9484                 const enum index *list = ctx->next[ctx->next_num - 1];
9485                 int i;
9486
9487                 for (i = 0; list[i]; ++i) {
9488                         if (list[i] != END)
9489                                 continue;
9490                         *hdr = NULL;
9491                         return;
9492                 }
9493         }
9494         *hdr = &cmd_flow_token_hdr;
9495 }
9496
9497 /** Dispatch parsed buffer to function calls. */
9498 static void
9499 cmd_flow_parsed(const struct buffer *in)
9500 {
9501         switch (in->command) {
9502         case INFO:
9503                 port_flow_get_info(in->port);
9504                 break;
9505         case CONFIGURE:
9506                 port_flow_configure(in->port,
9507                                     &in->args.configure.port_attr,
9508                                     in->args.configure.nb_queue,
9509                                     &in->args.configure.queue_attr);
9510                 break;
9511         case PATTERN_TEMPLATE_CREATE:
9512                 port_flow_pattern_template_create(in->port,
9513                                 in->args.vc.pat_templ_id,
9514                                 &((const struct rte_flow_pattern_template_attr) {
9515                                         .relaxed_matching = in->args.vc.attr.reserved,
9516                                         .ingress = in->args.vc.attr.ingress,
9517                                         .egress = in->args.vc.attr.egress,
9518                                         .transfer = in->args.vc.attr.transfer,
9519                                 }),
9520                                 in->args.vc.pattern);
9521                 break;
9522         case PATTERN_TEMPLATE_DESTROY:
9523                 port_flow_pattern_template_destroy(in->port,
9524                                 in->args.templ_destroy.template_id_n,
9525                                 in->args.templ_destroy.template_id);
9526                 break;
9527         case ACTIONS_TEMPLATE_CREATE:
9528                 port_flow_actions_template_create(in->port,
9529                                 in->args.vc.act_templ_id,
9530                                 &((const struct rte_flow_actions_template_attr) {
9531                                         .ingress = in->args.vc.attr.ingress,
9532                                         .egress = in->args.vc.attr.egress,
9533                                         .transfer = in->args.vc.attr.transfer,
9534                                 }),
9535                                 in->args.vc.actions,
9536                                 in->args.vc.masks);
9537                 break;
9538         case ACTIONS_TEMPLATE_DESTROY:
9539                 port_flow_actions_template_destroy(in->port,
9540                                 in->args.templ_destroy.template_id_n,
9541                                 in->args.templ_destroy.template_id);
9542                 break;
9543         case INDIRECT_ACTION_CREATE:
9544                 port_action_handle_create(
9545                                 in->port, in->args.vc.attr.group,
9546                                 &((const struct rte_flow_indir_action_conf) {
9547                                         .ingress = in->args.vc.attr.ingress,
9548                                         .egress = in->args.vc.attr.egress,
9549                                         .transfer = in->args.vc.attr.transfer,
9550                                 }),
9551                                 in->args.vc.actions);
9552                 break;
9553         case INDIRECT_ACTION_DESTROY:
9554                 port_action_handle_destroy(in->port,
9555                                            in->args.ia_destroy.action_id_n,
9556                                            in->args.ia_destroy.action_id);
9557                 break;
9558         case INDIRECT_ACTION_UPDATE:
9559                 port_action_handle_update(in->port, in->args.vc.attr.group,
9560                                           in->args.vc.actions);
9561                 break;
9562         case INDIRECT_ACTION_QUERY:
9563                 port_action_handle_query(in->port, in->args.ia.action_id);
9564                 break;
9565         case VALIDATE:
9566                 port_flow_validate(in->port, &in->args.vc.attr,
9567                                    in->args.vc.pattern, in->args.vc.actions,
9568                                    &in->args.vc.tunnel_ops);
9569                 break;
9570         case CREATE:
9571                 port_flow_create(in->port, &in->args.vc.attr,
9572                                  in->args.vc.pattern, in->args.vc.actions,
9573                                  &in->args.vc.tunnel_ops);
9574                 break;
9575         case DESTROY:
9576                 port_flow_destroy(in->port, in->args.destroy.rule_n,
9577                                   in->args.destroy.rule);
9578                 break;
9579         case FLUSH:
9580                 port_flow_flush(in->port);
9581                 break;
9582         case DUMP_ONE:
9583         case DUMP_ALL:
9584                 port_flow_dump(in->port, in->args.dump.mode,
9585                                 in->args.dump.rule, in->args.dump.file);
9586                 break;
9587         case QUERY:
9588                 port_flow_query(in->port, in->args.query.rule,
9589                                 &in->args.query.action);
9590                 break;
9591         case LIST:
9592                 port_flow_list(in->port, in->args.list.group_n,
9593                                in->args.list.group);
9594                 break;
9595         case ISOLATE:
9596                 port_flow_isolate(in->port, in->args.isolate.set);
9597                 break;
9598         case AGED:
9599                 port_flow_aged(in->port, in->args.aged.destroy);
9600                 break;
9601         case TUNNEL_CREATE:
9602                 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops);
9603                 break;
9604         case TUNNEL_DESTROY:
9605                 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id);
9606                 break;
9607         case TUNNEL_LIST:
9608                 port_flow_tunnel_list(in->port);
9609                 break;
9610         case ACTION_POL_G:
9611                 port_meter_policy_add(in->port, in->args.policy.policy_id,
9612                                         in->args.vc.actions);
9613                 break;
9614         case FLEX_ITEM_CREATE:
9615                 flex_item_create(in->port, in->args.flex.token,
9616                                  in->args.flex.filename);
9617                 break;
9618         case FLEX_ITEM_DESTROY:
9619                 flex_item_destroy(in->port, in->args.flex.token);
9620                 break;
9621         default:
9622                 break;
9623         }
9624 }
9625
9626 /** Token generator and output processing callback (cmdline API). */
9627 static void
9628 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2)
9629 {
9630         if (cl == NULL)
9631                 cmd_flow_tok(arg0, arg2);
9632         else
9633                 cmd_flow_parsed(arg0);
9634 }
9635
9636 /** Global parser instance (cmdline API). */
9637 cmdline_parse_inst_t cmd_flow = {
9638         .f = cmd_flow_cb,
9639         .data = NULL, /**< Unused. */
9640         .help_str = NULL, /**< Updated by cmd_flow_get_help(). */
9641         .tokens = {
9642                 NULL,
9643         }, /**< Tokens are returned by cmd_flow_tok(). */
9644 };
9645
9646 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */
9647
9648 static void
9649 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto)
9650 {
9651         struct rte_ipv4_hdr *ipv4;
9652         struct rte_ether_hdr *eth;
9653         struct rte_ipv6_hdr *ipv6;
9654         struct rte_vxlan_hdr *vxlan;
9655         struct rte_vxlan_gpe_hdr *gpe;
9656         struct rte_flow_item_nvgre *nvgre;
9657         uint32_t ipv6_vtc_flow;
9658
9659         switch (item->type) {
9660         case RTE_FLOW_ITEM_TYPE_ETH:
9661                 eth = (struct rte_ether_hdr *)buf;
9662                 if (next_proto)
9663                         eth->ether_type = rte_cpu_to_be_16(next_proto);
9664                 break;
9665         case RTE_FLOW_ITEM_TYPE_IPV4:
9666                 ipv4 = (struct rte_ipv4_hdr *)buf;
9667                 if (!ipv4->version_ihl)
9668                         ipv4->version_ihl = RTE_IPV4_VHL_DEF;
9669                 if (next_proto && ipv4->next_proto_id == 0)
9670                         ipv4->next_proto_id = (uint8_t)next_proto;
9671                 break;
9672         case RTE_FLOW_ITEM_TYPE_IPV6:
9673                 ipv6 = (struct rte_ipv6_hdr *)buf;
9674                 if (next_proto && ipv6->proto == 0)
9675                         ipv6->proto = (uint8_t)next_proto;
9676                 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow);
9677                 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */
9678                 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */
9679                 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow);
9680                 break;
9681         case RTE_FLOW_ITEM_TYPE_VXLAN:
9682                 vxlan = (struct rte_vxlan_hdr *)buf;
9683                 vxlan->vx_flags = 0x08;
9684                 break;
9685         case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
9686                 gpe = (struct rte_vxlan_gpe_hdr *)buf;
9687                 gpe->vx_flags = 0x0C;
9688                 break;
9689         case RTE_FLOW_ITEM_TYPE_NVGRE:
9690                 nvgre = (struct rte_flow_item_nvgre *)buf;
9691                 nvgre->protocol = rte_cpu_to_be_16(0x6558);
9692                 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000);
9693                 break;
9694         default:
9695                 break;
9696         }
9697 }
9698
9699 /** Helper of get item's default mask. */
9700 static const void *
9701 flow_item_default_mask(const struct rte_flow_item *item)
9702 {
9703         const void *mask = NULL;
9704         static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX);
9705
9706         switch (item->type) {
9707         case RTE_FLOW_ITEM_TYPE_ANY:
9708                 mask = &rte_flow_item_any_mask;
9709                 break;
9710         case RTE_FLOW_ITEM_TYPE_VF:
9711                 mask = &rte_flow_item_vf_mask;
9712                 break;
9713         case RTE_FLOW_ITEM_TYPE_PORT_ID:
9714                 mask = &rte_flow_item_port_id_mask;
9715                 break;
9716         case RTE_FLOW_ITEM_TYPE_RAW:
9717                 mask = &rte_flow_item_raw_mask;
9718                 break;
9719         case RTE_FLOW_ITEM_TYPE_ETH:
9720                 mask = &rte_flow_item_eth_mask;
9721                 break;
9722         case RTE_FLOW_ITEM_TYPE_VLAN:
9723                 mask = &rte_flow_item_vlan_mask;
9724                 break;
9725         case RTE_FLOW_ITEM_TYPE_IPV4:
9726                 mask = &rte_flow_item_ipv4_mask;
9727                 break;
9728         case RTE_FLOW_ITEM_TYPE_IPV6:
9729                 mask = &rte_flow_item_ipv6_mask;
9730                 break;
9731         case RTE_FLOW_ITEM_TYPE_ICMP:
9732                 mask = &rte_flow_item_icmp_mask;
9733                 break;
9734         case RTE_FLOW_ITEM_TYPE_UDP:
9735                 mask = &rte_flow_item_udp_mask;
9736                 break;
9737         case RTE_FLOW_ITEM_TYPE_TCP:
9738                 mask = &rte_flow_item_tcp_mask;
9739                 break;
9740         case RTE_FLOW_ITEM_TYPE_SCTP:
9741                 mask = &rte_flow_item_sctp_mask;
9742                 break;
9743         case RTE_FLOW_ITEM_TYPE_VXLAN:
9744                 mask = &rte_flow_item_vxlan_mask;
9745                 break;
9746         case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
9747                 mask = &rte_flow_item_vxlan_gpe_mask;
9748                 break;
9749         case RTE_FLOW_ITEM_TYPE_E_TAG:
9750                 mask = &rte_flow_item_e_tag_mask;
9751                 break;
9752         case RTE_FLOW_ITEM_TYPE_NVGRE:
9753                 mask = &rte_flow_item_nvgre_mask;
9754                 break;
9755         case RTE_FLOW_ITEM_TYPE_MPLS:
9756                 mask = &rte_flow_item_mpls_mask;
9757                 break;
9758         case RTE_FLOW_ITEM_TYPE_GRE:
9759                 mask = &rte_flow_item_gre_mask;
9760                 break;
9761         case RTE_FLOW_ITEM_TYPE_GRE_KEY:
9762                 mask = &gre_key_default_mask;
9763                 break;
9764         case RTE_FLOW_ITEM_TYPE_META:
9765                 mask = &rte_flow_item_meta_mask;
9766                 break;
9767         case RTE_FLOW_ITEM_TYPE_FUZZY:
9768                 mask = &rte_flow_item_fuzzy_mask;
9769                 break;
9770         case RTE_FLOW_ITEM_TYPE_GTP:
9771                 mask = &rte_flow_item_gtp_mask;
9772                 break;
9773         case RTE_FLOW_ITEM_TYPE_GTP_PSC:
9774                 mask = &rte_flow_item_gtp_psc_mask;
9775                 break;
9776         case RTE_FLOW_ITEM_TYPE_GENEVE:
9777                 mask = &rte_flow_item_geneve_mask;
9778                 break;
9779         case RTE_FLOW_ITEM_TYPE_GENEVE_OPT:
9780                 mask = &rte_flow_item_geneve_opt_mask;
9781                 break;
9782         case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID:
9783                 mask = &rte_flow_item_pppoe_proto_id_mask;
9784                 break;
9785         case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
9786                 mask = &rte_flow_item_l2tpv3oip_mask;
9787                 break;
9788         case RTE_FLOW_ITEM_TYPE_ESP:
9789                 mask = &rte_flow_item_esp_mask;
9790                 break;
9791         case RTE_FLOW_ITEM_TYPE_AH:
9792                 mask = &rte_flow_item_ah_mask;
9793                 break;
9794         case RTE_FLOW_ITEM_TYPE_PFCP:
9795                 mask = &rte_flow_item_pfcp_mask;
9796                 break;
9797         case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
9798         case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
9799                 mask = &rte_flow_item_ethdev_mask;
9800                 break;
9801         case RTE_FLOW_ITEM_TYPE_L2TPV2:
9802                 mask = &rte_flow_item_l2tpv2_mask;
9803                 break;
9804         case RTE_FLOW_ITEM_TYPE_PPP:
9805                 mask = &rte_flow_item_ppp_mask;
9806                 break;
9807         default:
9808                 break;
9809         }
9810         return mask;
9811 }
9812
9813 /** Dispatch parsed buffer to function calls. */
9814 static void
9815 cmd_set_raw_parsed_sample(const struct buffer *in)
9816 {
9817         uint32_t n = in->args.vc.actions_n;
9818         uint32_t i = 0;
9819         struct rte_flow_action *action = NULL;
9820         struct rte_flow_action *data = NULL;
9821         const struct rte_flow_action_rss *rss = NULL;
9822         size_t size = 0;
9823         uint16_t idx = in->port; /* We borrow port field as index */
9824         uint32_t max_size = sizeof(struct rte_flow_action) *
9825                                                 ACTION_SAMPLE_ACTIONS_NUM;
9826
9827         RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS);
9828         data = (struct rte_flow_action *)&raw_sample_confs[idx].data;
9829         memset(data, 0x00, max_size);
9830         for (; i <= n - 1; i++) {
9831                 action = in->args.vc.actions + i;
9832                 if (action->type == RTE_FLOW_ACTION_TYPE_END)
9833                         break;
9834                 switch (action->type) {
9835                 case RTE_FLOW_ACTION_TYPE_MARK:
9836                         size = sizeof(struct rte_flow_action_mark);
9837                         rte_memcpy(&sample_mark[idx],
9838                                 (const void *)action->conf, size);
9839                         action->conf = &sample_mark[idx];
9840                         break;
9841                 case RTE_FLOW_ACTION_TYPE_COUNT:
9842                         size = sizeof(struct rte_flow_action_count);
9843                         rte_memcpy(&sample_count[idx],
9844                                 (const void *)action->conf, size);
9845                         action->conf = &sample_count[idx];
9846                         break;
9847                 case RTE_FLOW_ACTION_TYPE_QUEUE:
9848                         size = sizeof(struct rte_flow_action_queue);
9849                         rte_memcpy(&sample_queue[idx],
9850                                 (const void *)action->conf, size);
9851                         action->conf = &sample_queue[idx];
9852                         break;
9853                 case RTE_FLOW_ACTION_TYPE_RSS:
9854                         size = sizeof(struct rte_flow_action_rss);
9855                         rss = action->conf;
9856                         rte_memcpy(&sample_rss_data[idx].conf,
9857                                    (const void *)rss, size);
9858                         if (rss->key_len && rss->key) {
9859                                 sample_rss_data[idx].conf.key =
9860                                                 sample_rss_data[idx].key;
9861                                 rte_memcpy((void *)((uintptr_t)
9862                                            sample_rss_data[idx].conf.key),
9863                                            (const void *)rss->key,
9864                                            sizeof(uint8_t) * rss->key_len);
9865                         }
9866                         if (rss->queue_num && rss->queue) {
9867                                 sample_rss_data[idx].conf.queue =
9868                                                 sample_rss_data[idx].queue;
9869                                 rte_memcpy((void *)((uintptr_t)
9870                                            sample_rss_data[idx].conf.queue),
9871                                            (const void *)rss->queue,
9872                                            sizeof(uint16_t) * rss->queue_num);
9873                         }
9874                         action->conf = &sample_rss_data[idx].conf;
9875                         break;
9876                 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
9877                         size = sizeof(struct rte_flow_action_raw_encap);
9878                         rte_memcpy(&sample_encap[idx],
9879                                 (const void *)action->conf, size);
9880                         action->conf = &sample_encap[idx];
9881                         break;
9882                 case RTE_FLOW_ACTION_TYPE_PORT_ID:
9883                         size = sizeof(struct rte_flow_action_port_id);
9884                         rte_memcpy(&sample_port_id[idx],
9885                                 (const void *)action->conf, size);
9886                         action->conf = &sample_port_id[idx];
9887                         break;
9888                 case RTE_FLOW_ACTION_TYPE_PF:
9889                         break;
9890                 case RTE_FLOW_ACTION_TYPE_VF:
9891                         size = sizeof(struct rte_flow_action_vf);
9892                         rte_memcpy(&sample_vf[idx],
9893                                         (const void *)action->conf, size);
9894                         action->conf = &sample_vf[idx];
9895                         break;
9896                 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
9897                         size = sizeof(struct rte_flow_action_vxlan_encap);
9898                         parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]);
9899                         action->conf = &sample_vxlan_encap[idx].conf;
9900                         break;
9901                 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
9902                         size = sizeof(struct rte_flow_action_nvgre_encap);
9903                         parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]);
9904                         action->conf = &sample_nvgre_encap[idx];
9905                         break;
9906                 default:
9907                         fprintf(stderr, "Error - Not supported action\n");
9908                         return;
9909                 }
9910                 rte_memcpy(data, action, sizeof(struct rte_flow_action));
9911                 data++;
9912         }
9913 }
9914
9915 /** Dispatch parsed buffer to function calls. */
9916 static void
9917 cmd_set_raw_parsed(const struct buffer *in)
9918 {
9919         uint32_t n = in->args.vc.pattern_n;
9920         int i = 0;
9921         struct rte_flow_item *item = NULL;
9922         size_t size = 0;
9923         uint8_t *data = NULL;
9924         uint8_t *data_tail = NULL;
9925         size_t *total_size = NULL;
9926         uint16_t upper_layer = 0;
9927         uint16_t proto = 0;
9928         uint16_t idx = in->port; /* We borrow port field as index */
9929         int gtp_psc = -1; /* GTP PSC option index. */
9930
9931         if (in->command == SET_SAMPLE_ACTIONS)
9932                 return cmd_set_raw_parsed_sample(in);
9933         RTE_ASSERT(in->command == SET_RAW_ENCAP ||
9934                    in->command == SET_RAW_DECAP);
9935         if (in->command == SET_RAW_ENCAP) {
9936                 total_size = &raw_encap_confs[idx].size;
9937                 data = (uint8_t *)&raw_encap_confs[idx].data;
9938         } else {
9939                 total_size = &raw_decap_confs[idx].size;
9940                 data = (uint8_t *)&raw_decap_confs[idx].data;
9941         }
9942         *total_size = 0;
9943         memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA);
9944         /* process hdr from upper layer to low layer (L3/L4 -> L2). */
9945         data_tail = data + ACTION_RAW_ENCAP_MAX_DATA;
9946         for (i = n - 1 ; i >= 0; --i) {
9947                 const struct rte_flow_item_gtp *gtp;
9948                 const struct rte_flow_item_geneve_opt *opt;
9949
9950                 item = in->args.vc.pattern + i;
9951                 if (item->spec == NULL)
9952                         item->spec = flow_item_default_mask(item);
9953                 switch (item->type) {
9954                 case RTE_FLOW_ITEM_TYPE_ETH:
9955                         size = sizeof(struct rte_ether_hdr);
9956                         break;
9957                 case RTE_FLOW_ITEM_TYPE_VLAN:
9958                         size = sizeof(struct rte_vlan_hdr);
9959                         proto = RTE_ETHER_TYPE_VLAN;
9960                         break;
9961                 case RTE_FLOW_ITEM_TYPE_IPV4:
9962                         size = sizeof(struct rte_ipv4_hdr);
9963                         proto = RTE_ETHER_TYPE_IPV4;
9964                         break;
9965                 case RTE_FLOW_ITEM_TYPE_IPV6:
9966                         size = sizeof(struct rte_ipv6_hdr);
9967                         proto = RTE_ETHER_TYPE_IPV6;
9968                         break;
9969                 case RTE_FLOW_ITEM_TYPE_UDP:
9970                         size = sizeof(struct rte_udp_hdr);
9971                         proto = 0x11;
9972                         break;
9973                 case RTE_FLOW_ITEM_TYPE_TCP:
9974                         size = sizeof(struct rte_tcp_hdr);
9975                         proto = 0x06;
9976                         break;
9977                 case RTE_FLOW_ITEM_TYPE_VXLAN:
9978                         size = sizeof(struct rte_vxlan_hdr);
9979                         break;
9980                 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
9981                         size = sizeof(struct rte_vxlan_gpe_hdr);
9982                         break;
9983                 case RTE_FLOW_ITEM_TYPE_GRE:
9984                         size = sizeof(struct rte_gre_hdr);
9985                         proto = 0x2F;
9986                         break;
9987                 case RTE_FLOW_ITEM_TYPE_GRE_KEY:
9988                         size = sizeof(rte_be32_t);
9989                         proto = 0x0;
9990                         break;
9991                 case RTE_FLOW_ITEM_TYPE_MPLS:
9992                         size = sizeof(struct rte_mpls_hdr);
9993                         proto = 0x0;
9994                         break;
9995                 case RTE_FLOW_ITEM_TYPE_NVGRE:
9996                         size = sizeof(struct rte_flow_item_nvgre);
9997                         proto = 0x2F;
9998                         break;
9999                 case RTE_FLOW_ITEM_TYPE_GENEVE:
10000                         size = sizeof(struct rte_geneve_hdr);
10001                         break;
10002                 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT:
10003                         opt = (const struct rte_flow_item_geneve_opt *)
10004                                                                 item->spec;
10005                         size = offsetof(struct rte_flow_item_geneve_opt, data);
10006                         if (opt->option_len && opt->data) {
10007                                 *total_size += opt->option_len *
10008                                                sizeof(uint32_t);
10009                                 rte_memcpy(data_tail - (*total_size),
10010                                            opt->data,
10011                                            opt->option_len * sizeof(uint32_t));
10012                         }
10013                         break;
10014                 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
10015                         size = sizeof(rte_be32_t);
10016                         proto = 0x73;
10017                         break;
10018                 case RTE_FLOW_ITEM_TYPE_ESP:
10019                         size = sizeof(struct rte_esp_hdr);
10020                         proto = 0x32;
10021                         break;
10022                 case RTE_FLOW_ITEM_TYPE_AH:
10023                         size = sizeof(struct rte_flow_item_ah);
10024                         proto = 0x33;
10025                         break;
10026                 case RTE_FLOW_ITEM_TYPE_GTP:
10027                         if (gtp_psc < 0) {
10028                                 size = sizeof(struct rte_gtp_hdr);
10029                                 break;
10030                         }
10031                         if (gtp_psc != i + 1) {
10032                                 fprintf(stderr,
10033                                         "Error - GTP PSC does not follow GTP\n");
10034                                 goto error;
10035                         }
10036                         gtp = item->spec;
10037                         if ((gtp->v_pt_rsv_flags & 0x07) != 0x04) {
10038                                 /* Only E flag should be set. */
10039                                 fprintf(stderr,
10040                                         "Error - GTP unsupported flags\n");
10041                                 goto error;
10042                         } else {
10043                                 struct rte_gtp_hdr_ext_word ext_word = {
10044                                         .next_ext = 0x85
10045                                 };
10046
10047                                 /* We have to add GTP header extra word. */
10048                                 *total_size += sizeof(ext_word);
10049                                 rte_memcpy(data_tail - (*total_size),
10050                                            &ext_word, sizeof(ext_word));
10051                         }
10052                         size = sizeof(struct rte_gtp_hdr);
10053                         break;
10054                 case RTE_FLOW_ITEM_TYPE_GTP_PSC:
10055                         if (gtp_psc >= 0) {
10056                                 fprintf(stderr,
10057                                         "Error - Multiple GTP PSC items\n");
10058                                 goto error;
10059                         } else {
10060                                 const struct rte_flow_item_gtp_psc
10061                                         *opt = item->spec;
10062                                 struct {
10063                                         uint8_t len;
10064                                         uint8_t pdu_type:4;
10065                                         uint8_t qfi:6;
10066                                         uint8_t next;
10067                                 } psc;
10068                                 psc.len = sizeof(psc) / 4;
10069                                 psc.pdu_type = opt->hdr.type;
10070                                 psc.qfi = opt->hdr.qfi;
10071                                 psc.next = 0;
10072                                 *total_size += sizeof(psc);
10073                                 rte_memcpy(data_tail - (*total_size),
10074                                            &psc, sizeof(psc));
10075                                 gtp_psc = i;
10076                                 size = 0;
10077                         }
10078                         break;
10079                 case RTE_FLOW_ITEM_TYPE_PFCP:
10080                         size = sizeof(struct rte_flow_item_pfcp);
10081                         break;
10082                 case RTE_FLOW_ITEM_TYPE_FLEX:
10083                         size = item->spec ?
10084                                 ((const struct rte_flow_item_flex *)
10085                                 item->spec)->length : 0;
10086                         break;
10087                 case RTE_FLOW_ITEM_TYPE_GRE_OPTION:
10088                         size = 0;
10089                         if (item->spec) {
10090                                 const struct rte_flow_item_gre_opt
10091                                         *opt = item->spec;
10092                                 if (opt->checksum_rsvd.checksum) {
10093                                         *total_size +=
10094                                                 sizeof(opt->checksum_rsvd);
10095                                         rte_memcpy(data_tail - (*total_size),
10096                                                    &opt->checksum_rsvd,
10097                                                    sizeof(opt->checksum_rsvd));
10098                                 }
10099                                 if (opt->key.key) {
10100                                         *total_size += sizeof(opt->key.key);
10101                                         rte_memcpy(data_tail - (*total_size),
10102                                                    &opt->key.key,
10103                                                    sizeof(opt->key.key));
10104                                 }
10105                                 if (opt->sequence.sequence) {
10106                                         *total_size += sizeof(opt->sequence.sequence);
10107                                         rte_memcpy(data_tail - (*total_size),
10108                                                    &opt->sequence.sequence,
10109                                                    sizeof(opt->sequence.sequence));
10110                                 }
10111                         }
10112                         proto = 0x2F;
10113                         break;
10114                 default:
10115                         fprintf(stderr, "Error - Not supported item\n");
10116                         goto error;
10117                 }
10118                 *total_size += size;
10119                 rte_memcpy(data_tail - (*total_size), item->spec, size);
10120                 /* update some fields which cannot be set by cmdline */
10121                 update_fields((data_tail - (*total_size)), item,
10122                               upper_layer);
10123                 upper_layer = proto;
10124         }
10125         if (verbose_level & 0x1)
10126                 printf("total data size is %zu\n", (*total_size));
10127         RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA);
10128         memmove(data, (data_tail - (*total_size)), *total_size);
10129         return;
10130
10131 error:
10132         *total_size = 0;
10133         memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA);
10134 }
10135
10136 /** Populate help strings for current token (cmdline API). */
10137 static int
10138 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst,
10139                      unsigned int size)
10140 {
10141         struct context *ctx = &cmd_flow_context;
10142         const struct token *token = &token_list[ctx->prev];
10143
10144         (void)hdr;
10145         if (!size)
10146                 return -1;
10147         /* Set token type and update global help with details. */
10148         snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN"));
10149         if (token->help)
10150                 cmd_set_raw.help_str = token->help;
10151         else
10152                 cmd_set_raw.help_str = token->name;
10153         return 0;
10154 }
10155
10156 /** Token definition template (cmdline API). */
10157 static struct cmdline_token_hdr cmd_set_raw_token_hdr = {
10158         .ops = &(struct cmdline_token_ops){
10159                 .parse = cmd_flow_parse,
10160                 .complete_get_nb = cmd_flow_complete_get_nb,
10161                 .complete_get_elt = cmd_flow_complete_get_elt,
10162                 .get_help = cmd_set_raw_get_help,
10163         },
10164         .offset = 0,
10165 };
10166
10167 /** Populate the next dynamic token. */
10168 static void
10169 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr,
10170              cmdline_parse_token_hdr_t **hdr_inst)
10171 {
10172         struct context *ctx = &cmd_flow_context;
10173
10174         /* Always reinitialize context before requesting the first token. */
10175         if (!(hdr_inst - cmd_set_raw.tokens)) {
10176                 cmd_flow_context_init(ctx);
10177                 ctx->curr = START_SET;
10178         }
10179         /* Return NULL when no more tokens are expected. */
10180         if (!ctx->next_num && (ctx->curr != START_SET)) {
10181                 *hdr = NULL;
10182                 return;
10183         }
10184         /* Determine if command should end here. */
10185         if (ctx->eol && ctx->last && ctx->next_num) {
10186                 const enum index *list = ctx->next[ctx->next_num - 1];
10187                 int i;
10188
10189                 for (i = 0; list[i]; ++i) {
10190                         if (list[i] != END)
10191                                 continue;
10192                         *hdr = NULL;
10193                         return;
10194                 }
10195         }
10196         *hdr = &cmd_set_raw_token_hdr;
10197 }
10198
10199 /** Token generator and output processing callback (cmdline API). */
10200 static void
10201 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2)
10202 {
10203         if (cl == NULL)
10204                 cmd_set_raw_tok(arg0, arg2);
10205         else
10206                 cmd_set_raw_parsed(arg0);
10207 }
10208
10209 /** Global parser instance (cmdline API). */
10210 cmdline_parse_inst_t cmd_set_raw = {
10211         .f = cmd_set_raw_cb,
10212         .data = NULL, /**< Unused. */
10213         .help_str = NULL, /**< Updated by cmd_flow_get_help(). */
10214         .tokens = {
10215                 NULL,
10216         }, /**< Tokens are returned by cmd_flow_tok(). */
10217 };
10218
10219 /* *** display raw_encap/raw_decap buf */
10220 struct cmd_show_set_raw_result {
10221         cmdline_fixed_string_t cmd_show;
10222         cmdline_fixed_string_t cmd_what;
10223         cmdline_fixed_string_t cmd_all;
10224         uint16_t cmd_index;
10225 };
10226
10227 static void
10228 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data)
10229 {
10230         struct cmd_show_set_raw_result *res = parsed_result;
10231         uint16_t index = res->cmd_index;
10232         uint8_t all = 0;
10233         uint8_t *raw_data = NULL;
10234         size_t raw_size = 0;
10235         char title[16] = {0};
10236
10237         RTE_SET_USED(cl);
10238         RTE_SET_USED(data);
10239         if (!strcmp(res->cmd_all, "all")) {
10240                 all = 1;
10241                 index = 0;
10242         } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) {
10243                 fprintf(stderr, "index should be 0-%u\n",
10244                         RAW_ENCAP_CONFS_MAX_NUM - 1);
10245                 return;
10246         }
10247         do {
10248                 if (!strcmp(res->cmd_what, "raw_encap")) {
10249                         raw_data = (uint8_t *)&raw_encap_confs[index].data;
10250                         raw_size = raw_encap_confs[index].size;
10251                         snprintf(title, 16, "\nindex: %u", index);
10252                         rte_hexdump(stdout, title, raw_data, raw_size);
10253                 } else {
10254                         raw_data = (uint8_t *)&raw_decap_confs[index].data;
10255                         raw_size = raw_decap_confs[index].size;
10256                         snprintf(title, 16, "\nindex: %u", index);
10257                         rte_hexdump(stdout, title, raw_data, raw_size);
10258                 }
10259         } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM);
10260 }
10261
10262 cmdline_parse_token_string_t cmd_show_set_raw_cmd_show =
10263         TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
10264                         cmd_show, "show");
10265 cmdline_parse_token_string_t cmd_show_set_raw_cmd_what =
10266         TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
10267                         cmd_what, "raw_encap#raw_decap");
10268 cmdline_parse_token_num_t cmd_show_set_raw_cmd_index =
10269         TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result,
10270                         cmd_index, RTE_UINT16);
10271 cmdline_parse_token_string_t cmd_show_set_raw_cmd_all =
10272         TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
10273                         cmd_all, "all");
10274 cmdline_parse_inst_t cmd_show_set_raw = {
10275         .f = cmd_show_set_raw_parsed,
10276         .data = NULL,
10277         .help_str = "show <raw_encap|raw_decap> <index>",
10278         .tokens = {
10279                 (void *)&cmd_show_set_raw_cmd_show,
10280                 (void *)&cmd_show_set_raw_cmd_what,
10281                 (void *)&cmd_show_set_raw_cmd_index,
10282                 NULL,
10283         },
10284 };
10285 cmdline_parse_inst_t cmd_show_set_raw_all = {
10286         .f = cmd_show_set_raw_parsed,
10287         .data = NULL,
10288         .help_str = "show <raw_encap|raw_decap> all",
10289         .tokens = {
10290                 (void *)&cmd_show_set_raw_cmd_show,
10291                 (void *)&cmd_show_set_raw_cmd_what,
10292                 (void *)&cmd_show_set_raw_cmd_all,
10293                 NULL,
10294         },
10295 };