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