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