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