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