xref: /dpdk/app/test-pmd/cmdline_flow.c (revision 573ef95dc7c9e4991da41fa1fc3d45c5c4076deb)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2016 6WIND S.A.
3  * Copyright 2016 Mellanox Technologies, Ltd
4  */
5 
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <inttypes.h>
10 #include <errno.h>
11 #include <ctype.h>
12 #include <string.h>
13 #include <arpa/inet.h>
14 #include <sys/socket.h>
15 
16 #include <rte_string_fns.h>
17 #include <rte_common.h>
18 #include <rte_ethdev.h>
19 #include <rte_byteorder.h>
20 #include <cmdline_parse.h>
21 #include <cmdline_parse_etheraddr.h>
22 #include <cmdline_parse_string.h>
23 #include <cmdline_parse_num.h>
24 #include <rte_flow.h>
25 #include <rte_hexdump.h>
26 
27 #include "testpmd.h"
28 
29 /** Parser token indices. */
30 enum index {
31 	/* Special tokens. */
32 	ZERO = 0,
33 	END,
34 	START_SET,
35 	END_SET,
36 
37 	/* Common tokens. */
38 	INTEGER,
39 	UNSIGNED,
40 	PREFIX,
41 	BOOLEAN,
42 	STRING,
43 	HEX,
44 	FILE_PATH,
45 	MAC_ADDR,
46 	IPV4_ADDR,
47 	IPV6_ADDR,
48 	RULE_ID,
49 	PORT_ID,
50 	GROUP_ID,
51 	PRIORITY_LEVEL,
52 
53 	/* Top-level command. */
54 	SET,
55 	/* Sub-leve commands. */
56 	SET_RAW_ENCAP,
57 	SET_RAW_DECAP,
58 	SET_RAW_INDEX,
59 
60 	/* Top-level command. */
61 	FLOW,
62 	/* Sub-level commands. */
63 	VALIDATE,
64 	CREATE,
65 	DESTROY,
66 	FLUSH,
67 	DUMP,
68 	QUERY,
69 	LIST,
70 	ISOLATE,
71 
72 	/* Destroy arguments. */
73 	DESTROY_RULE,
74 
75 	/* Query arguments. */
76 	QUERY_ACTION,
77 
78 	/* List arguments. */
79 	LIST_GROUP,
80 
81 	/* Validate/create arguments. */
82 	GROUP,
83 	PRIORITY,
84 	INGRESS,
85 	EGRESS,
86 	TRANSFER,
87 
88 	/* Validate/create pattern. */
89 	PATTERN,
90 	ITEM_PARAM_IS,
91 	ITEM_PARAM_SPEC,
92 	ITEM_PARAM_LAST,
93 	ITEM_PARAM_MASK,
94 	ITEM_PARAM_PREFIX,
95 	ITEM_NEXT,
96 	ITEM_END,
97 	ITEM_VOID,
98 	ITEM_INVERT,
99 	ITEM_ANY,
100 	ITEM_ANY_NUM,
101 	ITEM_PF,
102 	ITEM_VF,
103 	ITEM_VF_ID,
104 	ITEM_PHY_PORT,
105 	ITEM_PHY_PORT_INDEX,
106 	ITEM_PORT_ID,
107 	ITEM_PORT_ID_ID,
108 	ITEM_MARK,
109 	ITEM_MARK_ID,
110 	ITEM_RAW,
111 	ITEM_RAW_RELATIVE,
112 	ITEM_RAW_SEARCH,
113 	ITEM_RAW_OFFSET,
114 	ITEM_RAW_LIMIT,
115 	ITEM_RAW_PATTERN,
116 	ITEM_ETH,
117 	ITEM_ETH_DST,
118 	ITEM_ETH_SRC,
119 	ITEM_ETH_TYPE,
120 	ITEM_VLAN,
121 	ITEM_VLAN_TCI,
122 	ITEM_VLAN_PCP,
123 	ITEM_VLAN_DEI,
124 	ITEM_VLAN_VID,
125 	ITEM_VLAN_INNER_TYPE,
126 	ITEM_IPV4,
127 	ITEM_IPV4_TOS,
128 	ITEM_IPV4_TTL,
129 	ITEM_IPV4_PROTO,
130 	ITEM_IPV4_SRC,
131 	ITEM_IPV4_DST,
132 	ITEM_IPV6,
133 	ITEM_IPV6_TC,
134 	ITEM_IPV6_FLOW,
135 	ITEM_IPV6_PROTO,
136 	ITEM_IPV6_HOP,
137 	ITEM_IPV6_SRC,
138 	ITEM_IPV6_DST,
139 	ITEM_ICMP,
140 	ITEM_ICMP_TYPE,
141 	ITEM_ICMP_CODE,
142 	ITEM_UDP,
143 	ITEM_UDP_SRC,
144 	ITEM_UDP_DST,
145 	ITEM_TCP,
146 	ITEM_TCP_SRC,
147 	ITEM_TCP_DST,
148 	ITEM_TCP_FLAGS,
149 	ITEM_SCTP,
150 	ITEM_SCTP_SRC,
151 	ITEM_SCTP_DST,
152 	ITEM_SCTP_TAG,
153 	ITEM_SCTP_CKSUM,
154 	ITEM_VXLAN,
155 	ITEM_VXLAN_VNI,
156 	ITEM_E_TAG,
157 	ITEM_E_TAG_GRP_ECID_B,
158 	ITEM_NVGRE,
159 	ITEM_NVGRE_TNI,
160 	ITEM_MPLS,
161 	ITEM_MPLS_LABEL,
162 	ITEM_MPLS_TC,
163 	ITEM_MPLS_S,
164 	ITEM_GRE,
165 	ITEM_GRE_PROTO,
166 	ITEM_GRE_C_RSVD0_VER,
167 	ITEM_GRE_C_BIT,
168 	ITEM_GRE_K_BIT,
169 	ITEM_GRE_S_BIT,
170 	ITEM_FUZZY,
171 	ITEM_FUZZY_THRESH,
172 	ITEM_GTP,
173 	ITEM_GTP_MSG_TYPE,
174 	ITEM_GTP_TEID,
175 	ITEM_GTPC,
176 	ITEM_GTPU,
177 	ITEM_GENEVE,
178 	ITEM_GENEVE_VNI,
179 	ITEM_GENEVE_PROTO,
180 	ITEM_VXLAN_GPE,
181 	ITEM_VXLAN_GPE_VNI,
182 	ITEM_ARP_ETH_IPV4,
183 	ITEM_ARP_ETH_IPV4_SHA,
184 	ITEM_ARP_ETH_IPV4_SPA,
185 	ITEM_ARP_ETH_IPV4_THA,
186 	ITEM_ARP_ETH_IPV4_TPA,
187 	ITEM_IPV6_EXT,
188 	ITEM_IPV6_EXT_NEXT_HDR,
189 	ITEM_ICMP6,
190 	ITEM_ICMP6_TYPE,
191 	ITEM_ICMP6_CODE,
192 	ITEM_ICMP6_ND_NS,
193 	ITEM_ICMP6_ND_NS_TARGET_ADDR,
194 	ITEM_ICMP6_ND_NA,
195 	ITEM_ICMP6_ND_NA_TARGET_ADDR,
196 	ITEM_ICMP6_ND_OPT,
197 	ITEM_ICMP6_ND_OPT_TYPE,
198 	ITEM_ICMP6_ND_OPT_SLA_ETH,
199 	ITEM_ICMP6_ND_OPT_SLA_ETH_SLA,
200 	ITEM_ICMP6_ND_OPT_TLA_ETH,
201 	ITEM_ICMP6_ND_OPT_TLA_ETH_TLA,
202 	ITEM_META,
203 	ITEM_META_DATA,
204 	ITEM_GRE_KEY,
205 	ITEM_GRE_KEY_VALUE,
206 	ITEM_GTP_PSC,
207 	ITEM_GTP_PSC_QFI,
208 	ITEM_GTP_PSC_PDU_T,
209 	ITEM_PPPOES,
210 	ITEM_PPPOED,
211 	ITEM_PPPOE_SEID,
212 	ITEM_PPPOE_PROTO_ID,
213 	ITEM_HIGIG2,
214 	ITEM_HIGIG2_CLASSIFICATION,
215 	ITEM_HIGIG2_VID,
216 	ITEM_TAG,
217 	ITEM_TAG_DATA,
218 	ITEM_TAG_INDEX,
219 	ITEM_L2TPV3OIP,
220 	ITEM_L2TPV3OIP_SESSION_ID,
221 	ITEM_ESP,
222 	ITEM_ESP_SPI,
223 	ITEM_AH,
224 	ITEM_AH_SPI,
225 
226 	/* Validate/create actions. */
227 	ACTIONS,
228 	ACTION_NEXT,
229 	ACTION_END,
230 	ACTION_VOID,
231 	ACTION_PASSTHRU,
232 	ACTION_JUMP,
233 	ACTION_JUMP_GROUP,
234 	ACTION_MARK,
235 	ACTION_MARK_ID,
236 	ACTION_FLAG,
237 	ACTION_QUEUE,
238 	ACTION_QUEUE_INDEX,
239 	ACTION_DROP,
240 	ACTION_COUNT,
241 	ACTION_COUNT_SHARED,
242 	ACTION_COUNT_ID,
243 	ACTION_RSS,
244 	ACTION_RSS_FUNC,
245 	ACTION_RSS_LEVEL,
246 	ACTION_RSS_FUNC_DEFAULT,
247 	ACTION_RSS_FUNC_TOEPLITZ,
248 	ACTION_RSS_FUNC_SIMPLE_XOR,
249 	ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ,
250 	ACTION_RSS_TYPES,
251 	ACTION_RSS_TYPE,
252 	ACTION_RSS_KEY,
253 	ACTION_RSS_KEY_LEN,
254 	ACTION_RSS_QUEUES,
255 	ACTION_RSS_QUEUE,
256 	ACTION_PF,
257 	ACTION_VF,
258 	ACTION_VF_ORIGINAL,
259 	ACTION_VF_ID,
260 	ACTION_PHY_PORT,
261 	ACTION_PHY_PORT_ORIGINAL,
262 	ACTION_PHY_PORT_INDEX,
263 	ACTION_PORT_ID,
264 	ACTION_PORT_ID_ORIGINAL,
265 	ACTION_PORT_ID_ID,
266 	ACTION_METER,
267 	ACTION_METER_ID,
268 	ACTION_OF_SET_MPLS_TTL,
269 	ACTION_OF_SET_MPLS_TTL_MPLS_TTL,
270 	ACTION_OF_DEC_MPLS_TTL,
271 	ACTION_OF_SET_NW_TTL,
272 	ACTION_OF_SET_NW_TTL_NW_TTL,
273 	ACTION_OF_DEC_NW_TTL,
274 	ACTION_OF_COPY_TTL_OUT,
275 	ACTION_OF_COPY_TTL_IN,
276 	ACTION_OF_POP_VLAN,
277 	ACTION_OF_PUSH_VLAN,
278 	ACTION_OF_PUSH_VLAN_ETHERTYPE,
279 	ACTION_OF_SET_VLAN_VID,
280 	ACTION_OF_SET_VLAN_VID_VLAN_VID,
281 	ACTION_OF_SET_VLAN_PCP,
282 	ACTION_OF_SET_VLAN_PCP_VLAN_PCP,
283 	ACTION_OF_POP_MPLS,
284 	ACTION_OF_POP_MPLS_ETHERTYPE,
285 	ACTION_OF_PUSH_MPLS,
286 	ACTION_OF_PUSH_MPLS_ETHERTYPE,
287 	ACTION_VXLAN_ENCAP,
288 	ACTION_VXLAN_DECAP,
289 	ACTION_NVGRE_ENCAP,
290 	ACTION_NVGRE_DECAP,
291 	ACTION_L2_ENCAP,
292 	ACTION_L2_DECAP,
293 	ACTION_MPLSOGRE_ENCAP,
294 	ACTION_MPLSOGRE_DECAP,
295 	ACTION_MPLSOUDP_ENCAP,
296 	ACTION_MPLSOUDP_DECAP,
297 	ACTION_SET_IPV4_SRC,
298 	ACTION_SET_IPV4_SRC_IPV4_SRC,
299 	ACTION_SET_IPV4_DST,
300 	ACTION_SET_IPV4_DST_IPV4_DST,
301 	ACTION_SET_IPV6_SRC,
302 	ACTION_SET_IPV6_SRC_IPV6_SRC,
303 	ACTION_SET_IPV6_DST,
304 	ACTION_SET_IPV6_DST_IPV6_DST,
305 	ACTION_SET_TP_SRC,
306 	ACTION_SET_TP_SRC_TP_SRC,
307 	ACTION_SET_TP_DST,
308 	ACTION_SET_TP_DST_TP_DST,
309 	ACTION_MAC_SWAP,
310 	ACTION_DEC_TTL,
311 	ACTION_SET_TTL,
312 	ACTION_SET_TTL_TTL,
313 	ACTION_SET_MAC_SRC,
314 	ACTION_SET_MAC_SRC_MAC_SRC,
315 	ACTION_SET_MAC_DST,
316 	ACTION_SET_MAC_DST_MAC_DST,
317 	ACTION_INC_TCP_SEQ,
318 	ACTION_INC_TCP_SEQ_VALUE,
319 	ACTION_DEC_TCP_SEQ,
320 	ACTION_DEC_TCP_SEQ_VALUE,
321 	ACTION_INC_TCP_ACK,
322 	ACTION_INC_TCP_ACK_VALUE,
323 	ACTION_DEC_TCP_ACK,
324 	ACTION_DEC_TCP_ACK_VALUE,
325 	ACTION_RAW_ENCAP,
326 	ACTION_RAW_DECAP,
327 	ACTION_RAW_ENCAP_INDEX,
328 	ACTION_RAW_ENCAP_INDEX_VALUE,
329 	ACTION_RAW_DECAP_INDEX,
330 	ACTION_RAW_DECAP_INDEX_VALUE,
331 	ACTION_SET_TAG,
332 	ACTION_SET_TAG_DATA,
333 	ACTION_SET_TAG_INDEX,
334 	ACTION_SET_TAG_MASK,
335 	ACTION_SET_META,
336 	ACTION_SET_META_DATA,
337 	ACTION_SET_META_MASK,
338 	ACTION_SET_IPV4_DSCP,
339 	ACTION_SET_IPV4_DSCP_VALUE,
340 	ACTION_SET_IPV6_DSCP,
341 	ACTION_SET_IPV6_DSCP_VALUE,
342 };
343 
344 /** Maximum size for pattern in struct rte_flow_item_raw. */
345 #define ITEM_RAW_PATTERN_SIZE 40
346 
347 /** Storage size for struct rte_flow_item_raw including pattern. */
348 #define ITEM_RAW_SIZE \
349 	(sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
350 
351 /** Maximum number of queue indices in struct rte_flow_action_rss. */
352 #define ACTION_RSS_QUEUE_NUM 128
353 
354 /** Storage for struct rte_flow_action_rss including external data. */
355 struct action_rss_data {
356 	struct rte_flow_action_rss conf;
357 	uint8_t key[RSS_HASH_KEY_LENGTH];
358 	uint16_t queue[ACTION_RSS_QUEUE_NUM];
359 };
360 
361 /** Maximum data size in struct rte_flow_action_raw_encap. */
362 #define ACTION_RAW_ENCAP_MAX_DATA 128
363 #define RAW_ENCAP_CONFS_MAX_NUM 8
364 
365 /** Storage for struct rte_flow_action_raw_encap. */
366 struct raw_encap_conf {
367 	uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
368 	uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA];
369 	size_t size;
370 };
371 
372 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM];
373 
374 /** Storage for struct rte_flow_action_raw_encap including external data. */
375 struct action_raw_encap_data {
376 	struct rte_flow_action_raw_encap conf;
377 	uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
378 	uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA];
379 	uint16_t idx;
380 };
381 
382 /** Storage for struct rte_flow_action_raw_decap. */
383 struct raw_decap_conf {
384 	uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
385 	size_t size;
386 };
387 
388 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM];
389 
390 /** Storage for struct rte_flow_action_raw_decap including external data. */
391 struct action_raw_decap_data {
392 	struct rte_flow_action_raw_decap conf;
393 	uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
394 	uint16_t idx;
395 };
396 
397 struct vxlan_encap_conf vxlan_encap_conf = {
398 	.select_ipv4 = 1,
399 	.select_vlan = 0,
400 	.select_tos_ttl = 0,
401 	.vni = "\x00\x00\x00",
402 	.udp_src = 0,
403 	.udp_dst = RTE_BE16(4789),
404 	.ipv4_src = RTE_IPV4(127, 0, 0, 1),
405 	.ipv4_dst = RTE_IPV4(255, 255, 255, 255),
406 	.ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
407 		"\x00\x00\x00\x00\x00\x00\x00\x01",
408 	.ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
409 		"\x00\x00\x00\x00\x00\x00\x11\x11",
410 	.vlan_tci = 0,
411 	.ip_tos = 0,
412 	.ip_ttl = 255,
413 	.eth_src = "\x00\x00\x00\x00\x00\x00",
414 	.eth_dst = "\xff\xff\xff\xff\xff\xff",
415 };
416 
417 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */
418 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6
419 
420 /** Storage for struct rte_flow_action_vxlan_encap including external data. */
421 struct action_vxlan_encap_data {
422 	struct rte_flow_action_vxlan_encap conf;
423 	struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM];
424 	struct rte_flow_item_eth item_eth;
425 	struct rte_flow_item_vlan item_vlan;
426 	union {
427 		struct rte_flow_item_ipv4 item_ipv4;
428 		struct rte_flow_item_ipv6 item_ipv6;
429 	};
430 	struct rte_flow_item_udp item_udp;
431 	struct rte_flow_item_vxlan item_vxlan;
432 };
433 
434 struct nvgre_encap_conf nvgre_encap_conf = {
435 	.select_ipv4 = 1,
436 	.select_vlan = 0,
437 	.tni = "\x00\x00\x00",
438 	.ipv4_src = RTE_IPV4(127, 0, 0, 1),
439 	.ipv4_dst = RTE_IPV4(255, 255, 255, 255),
440 	.ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
441 		"\x00\x00\x00\x00\x00\x00\x00\x01",
442 	.ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
443 		"\x00\x00\x00\x00\x00\x00\x11\x11",
444 	.vlan_tci = 0,
445 	.eth_src = "\x00\x00\x00\x00\x00\x00",
446 	.eth_dst = "\xff\xff\xff\xff\xff\xff",
447 };
448 
449 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */
450 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5
451 
452 /** Storage for struct rte_flow_action_nvgre_encap including external data. */
453 struct action_nvgre_encap_data {
454 	struct rte_flow_action_nvgre_encap conf;
455 	struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM];
456 	struct rte_flow_item_eth item_eth;
457 	struct rte_flow_item_vlan item_vlan;
458 	union {
459 		struct rte_flow_item_ipv4 item_ipv4;
460 		struct rte_flow_item_ipv6 item_ipv6;
461 	};
462 	struct rte_flow_item_nvgre item_nvgre;
463 };
464 
465 struct l2_encap_conf l2_encap_conf;
466 
467 struct l2_decap_conf l2_decap_conf;
468 
469 struct mplsogre_encap_conf mplsogre_encap_conf;
470 
471 struct mplsogre_decap_conf mplsogre_decap_conf;
472 
473 struct mplsoudp_encap_conf mplsoudp_encap_conf;
474 
475 struct mplsoudp_decap_conf mplsoudp_decap_conf;
476 
477 /** Maximum number of subsequent tokens and arguments on the stack. */
478 #define CTX_STACK_SIZE 16
479 
480 /** Parser context. */
481 struct context {
482 	/** Stack of subsequent token lists to process. */
483 	const enum index *next[CTX_STACK_SIZE];
484 	/** Arguments for stacked tokens. */
485 	const void *args[CTX_STACK_SIZE];
486 	enum index curr; /**< Current token index. */
487 	enum index prev; /**< Index of the last token seen. */
488 	int next_num; /**< Number of entries in next[]. */
489 	int args_num; /**< Number of entries in args[]. */
490 	uint32_t eol:1; /**< EOL has been detected. */
491 	uint32_t last:1; /**< No more arguments. */
492 	portid_t port; /**< Current port ID (for completions). */
493 	uint32_t objdata; /**< Object-specific data. */
494 	void *object; /**< Address of current object for relative offsets. */
495 	void *objmask; /**< Object a full mask must be written to. */
496 };
497 
498 /** Token argument. */
499 struct arg {
500 	uint32_t hton:1; /**< Use network byte ordering. */
501 	uint32_t sign:1; /**< Value is signed. */
502 	uint32_t bounded:1; /**< Value is bounded. */
503 	uintmax_t min; /**< Minimum value if bounded. */
504 	uintmax_t max; /**< Maximum value if bounded. */
505 	uint32_t offset; /**< Relative offset from ctx->object. */
506 	uint32_t size; /**< Field size. */
507 	const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */
508 };
509 
510 /** Parser token definition. */
511 struct token {
512 	/** Type displayed during completion (defaults to "TOKEN"). */
513 	const char *type;
514 	/** Help displayed during completion (defaults to token name). */
515 	const char *help;
516 	/** Private data used by parser functions. */
517 	const void *priv;
518 	/**
519 	 * Lists of subsequent tokens to push on the stack. Each call to the
520 	 * parser consumes the last entry of that stack.
521 	 */
522 	const enum index *const *next;
523 	/** Arguments stack for subsequent tokens that need them. */
524 	const struct arg *const *args;
525 	/**
526 	 * Token-processing callback, returns -1 in case of error, the
527 	 * length of the matched string otherwise. If NULL, attempts to
528 	 * match the token name.
529 	 *
530 	 * If buf is not NULL, the result should be stored in it according
531 	 * to context. An error is returned if not large enough.
532 	 */
533 	int (*call)(struct context *ctx, const struct token *token,
534 		    const char *str, unsigned int len,
535 		    void *buf, unsigned int size);
536 	/**
537 	 * Callback that provides possible values for this token, used for
538 	 * completion. Returns -1 in case of error, the number of possible
539 	 * values otherwise. If NULL, the token name is used.
540 	 *
541 	 * If buf is not NULL, entry index ent is written to buf and the
542 	 * full length of the entry is returned (same behavior as
543 	 * snprintf()).
544 	 */
545 	int (*comp)(struct context *ctx, const struct token *token,
546 		    unsigned int ent, char *buf, unsigned int size);
547 	/** Mandatory token name, no default value. */
548 	const char *name;
549 };
550 
551 /** Static initializer for the next field. */
552 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, }
553 
554 /** Static initializer for a NEXT() entry. */
555 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, }
556 
557 /** Static initializer for the args field. */
558 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, }
559 
560 /** Static initializer for ARGS() to target a field. */
561 #define ARGS_ENTRY(s, f) \
562 	(&(const struct arg){ \
563 		.offset = offsetof(s, f), \
564 		.size = sizeof(((s *)0)->f), \
565 	})
566 
567 /** Static initializer for ARGS() to target a bit-field. */
568 #define ARGS_ENTRY_BF(s, f, b) \
569 	(&(const struct arg){ \
570 		.size = sizeof(s), \
571 		.mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \
572 	})
573 
574 /** Static initializer for ARGS() to target an arbitrary bit-mask. */
575 #define ARGS_ENTRY_MASK(s, f, m) \
576 	(&(const struct arg){ \
577 		.offset = offsetof(s, f), \
578 		.size = sizeof(((s *)0)->f), \
579 		.mask = (const void *)(m), \
580 	})
581 
582 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */
583 #define ARGS_ENTRY_MASK_HTON(s, f, m) \
584 	(&(const struct arg){ \
585 		.hton = 1, \
586 		.offset = offsetof(s, f), \
587 		.size = sizeof(((s *)0)->f), \
588 		.mask = (const void *)(m), \
589 	})
590 
591 /** Static initializer for ARGS() to target a pointer. */
592 #define ARGS_ENTRY_PTR(s, f) \
593 	(&(const struct arg){ \
594 		.size = sizeof(*((s *)0)->f), \
595 	})
596 
597 /** Static initializer for ARGS() with arbitrary offset and size. */
598 #define ARGS_ENTRY_ARB(o, s) \
599 	(&(const struct arg){ \
600 		.offset = (o), \
601 		.size = (s), \
602 	})
603 
604 /** Same as ARGS_ENTRY_ARB() with bounded values. */
605 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \
606 	(&(const struct arg){ \
607 		.bounded = 1, \
608 		.min = (i), \
609 		.max = (a), \
610 		.offset = (o), \
611 		.size = (s), \
612 	})
613 
614 /** Same as ARGS_ENTRY() using network byte ordering. */
615 #define ARGS_ENTRY_HTON(s, f) \
616 	(&(const struct arg){ \
617 		.hton = 1, \
618 		.offset = offsetof(s, f), \
619 		.size = sizeof(((s *)0)->f), \
620 	})
621 
622 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */
623 #define ARG_ENTRY_HTON(s) \
624 	(&(const struct arg){ \
625 		.hton = 1, \
626 		.offset = 0, \
627 		.size = sizeof(s), \
628 	})
629 
630 /** Parser output buffer layout expected by cmd_flow_parsed(). */
631 struct buffer {
632 	enum index command; /**< Flow command. */
633 	portid_t port; /**< Affected port ID. */
634 	union {
635 		struct {
636 			struct rte_flow_attr attr;
637 			struct rte_flow_item *pattern;
638 			struct rte_flow_action *actions;
639 			uint32_t pattern_n;
640 			uint32_t actions_n;
641 			uint8_t *data;
642 		} vc; /**< Validate/create arguments. */
643 		struct {
644 			uint32_t *rule;
645 			uint32_t rule_n;
646 		} destroy; /**< Destroy arguments. */
647 		struct {
648 			char file[128];
649 		} dump; /**< Dump arguments. */
650 		struct {
651 			uint32_t rule;
652 			struct rte_flow_action action;
653 		} query; /**< Query arguments. */
654 		struct {
655 			uint32_t *group;
656 			uint32_t group_n;
657 		} list; /**< List arguments. */
658 		struct {
659 			int set;
660 		} isolate; /**< Isolated mode arguments. */
661 	} args; /**< Command arguments. */
662 };
663 
664 /** Private data for pattern items. */
665 struct parse_item_priv {
666 	enum rte_flow_item_type type; /**< Item type. */
667 	uint32_t size; /**< Size of item specification structure. */
668 };
669 
670 #define PRIV_ITEM(t, s) \
671 	(&(const struct parse_item_priv){ \
672 		.type = RTE_FLOW_ITEM_TYPE_ ## t, \
673 		.size = s, \
674 	})
675 
676 /** Private data for actions. */
677 struct parse_action_priv {
678 	enum rte_flow_action_type type; /**< Action type. */
679 	uint32_t size; /**< Size of action configuration structure. */
680 };
681 
682 #define PRIV_ACTION(t, s) \
683 	(&(const struct parse_action_priv){ \
684 		.type = RTE_FLOW_ACTION_TYPE_ ## t, \
685 		.size = s, \
686 	})
687 
688 static const enum index next_vc_attr[] = {
689 	GROUP,
690 	PRIORITY,
691 	INGRESS,
692 	EGRESS,
693 	TRANSFER,
694 	PATTERN,
695 	ZERO,
696 };
697 
698 static const enum index next_destroy_attr[] = {
699 	DESTROY_RULE,
700 	END,
701 	ZERO,
702 };
703 
704 static const enum index next_dump_attr[] = {
705 	FILE_PATH,
706 	END,
707 	ZERO,
708 };
709 
710 static const enum index next_list_attr[] = {
711 	LIST_GROUP,
712 	END,
713 	ZERO,
714 };
715 
716 static const enum index item_param[] = {
717 	ITEM_PARAM_IS,
718 	ITEM_PARAM_SPEC,
719 	ITEM_PARAM_LAST,
720 	ITEM_PARAM_MASK,
721 	ITEM_PARAM_PREFIX,
722 	ZERO,
723 };
724 
725 static const enum index next_item[] = {
726 	ITEM_END,
727 	ITEM_VOID,
728 	ITEM_INVERT,
729 	ITEM_ANY,
730 	ITEM_PF,
731 	ITEM_VF,
732 	ITEM_PHY_PORT,
733 	ITEM_PORT_ID,
734 	ITEM_MARK,
735 	ITEM_RAW,
736 	ITEM_ETH,
737 	ITEM_VLAN,
738 	ITEM_IPV4,
739 	ITEM_IPV6,
740 	ITEM_ICMP,
741 	ITEM_UDP,
742 	ITEM_TCP,
743 	ITEM_SCTP,
744 	ITEM_VXLAN,
745 	ITEM_E_TAG,
746 	ITEM_NVGRE,
747 	ITEM_MPLS,
748 	ITEM_GRE,
749 	ITEM_FUZZY,
750 	ITEM_GTP,
751 	ITEM_GTPC,
752 	ITEM_GTPU,
753 	ITEM_GENEVE,
754 	ITEM_VXLAN_GPE,
755 	ITEM_ARP_ETH_IPV4,
756 	ITEM_IPV6_EXT,
757 	ITEM_ICMP6,
758 	ITEM_ICMP6_ND_NS,
759 	ITEM_ICMP6_ND_NA,
760 	ITEM_ICMP6_ND_OPT,
761 	ITEM_ICMP6_ND_OPT_SLA_ETH,
762 	ITEM_ICMP6_ND_OPT_TLA_ETH,
763 	ITEM_META,
764 	ITEM_GRE_KEY,
765 	ITEM_GTP_PSC,
766 	ITEM_PPPOES,
767 	ITEM_PPPOED,
768 	ITEM_PPPOE_PROTO_ID,
769 	ITEM_HIGIG2,
770 	ITEM_TAG,
771 	ITEM_L2TPV3OIP,
772 	ITEM_ESP,
773 	ITEM_AH,
774 	END_SET,
775 	ZERO,
776 };
777 
778 static const enum index item_fuzzy[] = {
779 	ITEM_FUZZY_THRESH,
780 	ITEM_NEXT,
781 	ZERO,
782 };
783 
784 static const enum index item_any[] = {
785 	ITEM_ANY_NUM,
786 	ITEM_NEXT,
787 	ZERO,
788 };
789 
790 static const enum index item_vf[] = {
791 	ITEM_VF_ID,
792 	ITEM_NEXT,
793 	ZERO,
794 };
795 
796 static const enum index item_phy_port[] = {
797 	ITEM_PHY_PORT_INDEX,
798 	ITEM_NEXT,
799 	ZERO,
800 };
801 
802 static const enum index item_port_id[] = {
803 	ITEM_PORT_ID_ID,
804 	ITEM_NEXT,
805 	ZERO,
806 };
807 
808 static const enum index item_mark[] = {
809 	ITEM_MARK_ID,
810 	ITEM_NEXT,
811 	ZERO,
812 };
813 
814 static const enum index item_raw[] = {
815 	ITEM_RAW_RELATIVE,
816 	ITEM_RAW_SEARCH,
817 	ITEM_RAW_OFFSET,
818 	ITEM_RAW_LIMIT,
819 	ITEM_RAW_PATTERN,
820 	ITEM_NEXT,
821 	ZERO,
822 };
823 
824 static const enum index item_eth[] = {
825 	ITEM_ETH_DST,
826 	ITEM_ETH_SRC,
827 	ITEM_ETH_TYPE,
828 	ITEM_NEXT,
829 	ZERO,
830 };
831 
832 static const enum index item_vlan[] = {
833 	ITEM_VLAN_TCI,
834 	ITEM_VLAN_PCP,
835 	ITEM_VLAN_DEI,
836 	ITEM_VLAN_VID,
837 	ITEM_VLAN_INNER_TYPE,
838 	ITEM_NEXT,
839 	ZERO,
840 };
841 
842 static const enum index item_ipv4[] = {
843 	ITEM_IPV4_TOS,
844 	ITEM_IPV4_TTL,
845 	ITEM_IPV4_PROTO,
846 	ITEM_IPV4_SRC,
847 	ITEM_IPV4_DST,
848 	ITEM_NEXT,
849 	ZERO,
850 };
851 
852 static const enum index item_ipv6[] = {
853 	ITEM_IPV6_TC,
854 	ITEM_IPV6_FLOW,
855 	ITEM_IPV6_PROTO,
856 	ITEM_IPV6_HOP,
857 	ITEM_IPV6_SRC,
858 	ITEM_IPV6_DST,
859 	ITEM_NEXT,
860 	ZERO,
861 };
862 
863 static const enum index item_icmp[] = {
864 	ITEM_ICMP_TYPE,
865 	ITEM_ICMP_CODE,
866 	ITEM_NEXT,
867 	ZERO,
868 };
869 
870 static const enum index item_udp[] = {
871 	ITEM_UDP_SRC,
872 	ITEM_UDP_DST,
873 	ITEM_NEXT,
874 	ZERO,
875 };
876 
877 static const enum index item_tcp[] = {
878 	ITEM_TCP_SRC,
879 	ITEM_TCP_DST,
880 	ITEM_TCP_FLAGS,
881 	ITEM_NEXT,
882 	ZERO,
883 };
884 
885 static const enum index item_sctp[] = {
886 	ITEM_SCTP_SRC,
887 	ITEM_SCTP_DST,
888 	ITEM_SCTP_TAG,
889 	ITEM_SCTP_CKSUM,
890 	ITEM_NEXT,
891 	ZERO,
892 };
893 
894 static const enum index item_vxlan[] = {
895 	ITEM_VXLAN_VNI,
896 	ITEM_NEXT,
897 	ZERO,
898 };
899 
900 static const enum index item_e_tag[] = {
901 	ITEM_E_TAG_GRP_ECID_B,
902 	ITEM_NEXT,
903 	ZERO,
904 };
905 
906 static const enum index item_nvgre[] = {
907 	ITEM_NVGRE_TNI,
908 	ITEM_NEXT,
909 	ZERO,
910 };
911 
912 static const enum index item_mpls[] = {
913 	ITEM_MPLS_LABEL,
914 	ITEM_MPLS_TC,
915 	ITEM_MPLS_S,
916 	ITEM_NEXT,
917 	ZERO,
918 };
919 
920 static const enum index item_gre[] = {
921 	ITEM_GRE_PROTO,
922 	ITEM_GRE_C_RSVD0_VER,
923 	ITEM_GRE_C_BIT,
924 	ITEM_GRE_K_BIT,
925 	ITEM_GRE_S_BIT,
926 	ITEM_NEXT,
927 	ZERO,
928 };
929 
930 static const enum index item_gre_key[] = {
931 	ITEM_GRE_KEY_VALUE,
932 	ITEM_NEXT,
933 	ZERO,
934 };
935 
936 static const enum index item_gtp[] = {
937 	ITEM_GTP_MSG_TYPE,
938 	ITEM_GTP_TEID,
939 	ITEM_NEXT,
940 	ZERO,
941 };
942 
943 static const enum index item_geneve[] = {
944 	ITEM_GENEVE_VNI,
945 	ITEM_GENEVE_PROTO,
946 	ITEM_NEXT,
947 	ZERO,
948 };
949 
950 static const enum index item_vxlan_gpe[] = {
951 	ITEM_VXLAN_GPE_VNI,
952 	ITEM_NEXT,
953 	ZERO,
954 };
955 
956 static const enum index item_arp_eth_ipv4[] = {
957 	ITEM_ARP_ETH_IPV4_SHA,
958 	ITEM_ARP_ETH_IPV4_SPA,
959 	ITEM_ARP_ETH_IPV4_THA,
960 	ITEM_ARP_ETH_IPV4_TPA,
961 	ITEM_NEXT,
962 	ZERO,
963 };
964 
965 static const enum index item_ipv6_ext[] = {
966 	ITEM_IPV6_EXT_NEXT_HDR,
967 	ITEM_NEXT,
968 	ZERO,
969 };
970 
971 static const enum index item_icmp6[] = {
972 	ITEM_ICMP6_TYPE,
973 	ITEM_ICMP6_CODE,
974 	ITEM_NEXT,
975 	ZERO,
976 };
977 
978 static const enum index item_icmp6_nd_ns[] = {
979 	ITEM_ICMP6_ND_NS_TARGET_ADDR,
980 	ITEM_NEXT,
981 	ZERO,
982 };
983 
984 static const enum index item_icmp6_nd_na[] = {
985 	ITEM_ICMP6_ND_NA_TARGET_ADDR,
986 	ITEM_NEXT,
987 	ZERO,
988 };
989 
990 static const enum index item_icmp6_nd_opt[] = {
991 	ITEM_ICMP6_ND_OPT_TYPE,
992 	ITEM_NEXT,
993 	ZERO,
994 };
995 
996 static const enum index item_icmp6_nd_opt_sla_eth[] = {
997 	ITEM_ICMP6_ND_OPT_SLA_ETH_SLA,
998 	ITEM_NEXT,
999 	ZERO,
1000 };
1001 
1002 static const enum index item_icmp6_nd_opt_tla_eth[] = {
1003 	ITEM_ICMP6_ND_OPT_TLA_ETH_TLA,
1004 	ITEM_NEXT,
1005 	ZERO,
1006 };
1007 
1008 static const enum index item_meta[] = {
1009 	ITEM_META_DATA,
1010 	ITEM_NEXT,
1011 	ZERO,
1012 };
1013 
1014 static const enum index item_gtp_psc[] = {
1015 	ITEM_GTP_PSC_QFI,
1016 	ITEM_GTP_PSC_PDU_T,
1017 	ITEM_NEXT,
1018 	ZERO,
1019 };
1020 
1021 static const enum index item_pppoed[] = {
1022 	ITEM_PPPOE_SEID,
1023 	ITEM_NEXT,
1024 	ZERO,
1025 };
1026 
1027 static const enum index item_pppoes[] = {
1028 	ITEM_PPPOE_SEID,
1029 	ITEM_NEXT,
1030 	ZERO,
1031 };
1032 
1033 static const enum index item_pppoe_proto_id[] = {
1034 	ITEM_PPPOE_PROTO_ID,
1035 	ITEM_NEXT,
1036 	ZERO,
1037 };
1038 
1039 static const enum index item_higig2[] = {
1040 	ITEM_HIGIG2_CLASSIFICATION,
1041 	ITEM_HIGIG2_VID,
1042 	ITEM_NEXT,
1043 	ZERO,
1044 };
1045 
1046 static const enum index item_esp[] = {
1047 	ITEM_ESP_SPI,
1048 	ITEM_NEXT,
1049 	ZERO,
1050 };
1051 
1052 static const enum index item_ah[] = {
1053 	ITEM_AH_SPI,
1054 	ITEM_NEXT,
1055 	ZERO,
1056 };
1057 
1058 static const enum index next_set_raw[] = {
1059 	SET_RAW_INDEX,
1060 	ITEM_ETH,
1061 	ZERO,
1062 };
1063 
1064 static const enum index item_tag[] = {
1065 	ITEM_TAG_DATA,
1066 	ITEM_TAG_INDEX,
1067 	ITEM_NEXT,
1068 	ZERO,
1069 };
1070 
1071 static const enum index item_l2tpv3oip[] = {
1072 	ITEM_L2TPV3OIP_SESSION_ID,
1073 	ITEM_NEXT,
1074 	ZERO,
1075 };
1076 
1077 static const enum index next_action[] = {
1078 	ACTION_END,
1079 	ACTION_VOID,
1080 	ACTION_PASSTHRU,
1081 	ACTION_JUMP,
1082 	ACTION_MARK,
1083 	ACTION_FLAG,
1084 	ACTION_QUEUE,
1085 	ACTION_DROP,
1086 	ACTION_COUNT,
1087 	ACTION_RSS,
1088 	ACTION_PF,
1089 	ACTION_VF,
1090 	ACTION_PHY_PORT,
1091 	ACTION_PORT_ID,
1092 	ACTION_METER,
1093 	ACTION_OF_SET_MPLS_TTL,
1094 	ACTION_OF_DEC_MPLS_TTL,
1095 	ACTION_OF_SET_NW_TTL,
1096 	ACTION_OF_DEC_NW_TTL,
1097 	ACTION_OF_COPY_TTL_OUT,
1098 	ACTION_OF_COPY_TTL_IN,
1099 	ACTION_OF_POP_VLAN,
1100 	ACTION_OF_PUSH_VLAN,
1101 	ACTION_OF_SET_VLAN_VID,
1102 	ACTION_OF_SET_VLAN_PCP,
1103 	ACTION_OF_POP_MPLS,
1104 	ACTION_OF_PUSH_MPLS,
1105 	ACTION_VXLAN_ENCAP,
1106 	ACTION_VXLAN_DECAP,
1107 	ACTION_NVGRE_ENCAP,
1108 	ACTION_NVGRE_DECAP,
1109 	ACTION_L2_ENCAP,
1110 	ACTION_L2_DECAP,
1111 	ACTION_MPLSOGRE_ENCAP,
1112 	ACTION_MPLSOGRE_DECAP,
1113 	ACTION_MPLSOUDP_ENCAP,
1114 	ACTION_MPLSOUDP_DECAP,
1115 	ACTION_SET_IPV4_SRC,
1116 	ACTION_SET_IPV4_DST,
1117 	ACTION_SET_IPV6_SRC,
1118 	ACTION_SET_IPV6_DST,
1119 	ACTION_SET_TP_SRC,
1120 	ACTION_SET_TP_DST,
1121 	ACTION_MAC_SWAP,
1122 	ACTION_DEC_TTL,
1123 	ACTION_SET_TTL,
1124 	ACTION_SET_MAC_SRC,
1125 	ACTION_SET_MAC_DST,
1126 	ACTION_INC_TCP_SEQ,
1127 	ACTION_DEC_TCP_SEQ,
1128 	ACTION_INC_TCP_ACK,
1129 	ACTION_DEC_TCP_ACK,
1130 	ACTION_RAW_ENCAP,
1131 	ACTION_RAW_DECAP,
1132 	ACTION_SET_TAG,
1133 	ACTION_SET_META,
1134 	ACTION_SET_IPV4_DSCP,
1135 	ACTION_SET_IPV6_DSCP,
1136 	ZERO,
1137 };
1138 
1139 static const enum index action_mark[] = {
1140 	ACTION_MARK_ID,
1141 	ACTION_NEXT,
1142 	ZERO,
1143 };
1144 
1145 static const enum index action_queue[] = {
1146 	ACTION_QUEUE_INDEX,
1147 	ACTION_NEXT,
1148 	ZERO,
1149 };
1150 
1151 static const enum index action_count[] = {
1152 	ACTION_COUNT_ID,
1153 	ACTION_COUNT_SHARED,
1154 	ACTION_NEXT,
1155 	ZERO,
1156 };
1157 
1158 static const enum index action_rss[] = {
1159 	ACTION_RSS_FUNC,
1160 	ACTION_RSS_LEVEL,
1161 	ACTION_RSS_TYPES,
1162 	ACTION_RSS_KEY,
1163 	ACTION_RSS_KEY_LEN,
1164 	ACTION_RSS_QUEUES,
1165 	ACTION_NEXT,
1166 	ZERO,
1167 };
1168 
1169 static const enum index action_vf[] = {
1170 	ACTION_VF_ORIGINAL,
1171 	ACTION_VF_ID,
1172 	ACTION_NEXT,
1173 	ZERO,
1174 };
1175 
1176 static const enum index action_phy_port[] = {
1177 	ACTION_PHY_PORT_ORIGINAL,
1178 	ACTION_PHY_PORT_INDEX,
1179 	ACTION_NEXT,
1180 	ZERO,
1181 };
1182 
1183 static const enum index action_port_id[] = {
1184 	ACTION_PORT_ID_ORIGINAL,
1185 	ACTION_PORT_ID_ID,
1186 	ACTION_NEXT,
1187 	ZERO,
1188 };
1189 
1190 static const enum index action_meter[] = {
1191 	ACTION_METER_ID,
1192 	ACTION_NEXT,
1193 	ZERO,
1194 };
1195 
1196 static const enum index action_of_set_mpls_ttl[] = {
1197 	ACTION_OF_SET_MPLS_TTL_MPLS_TTL,
1198 	ACTION_NEXT,
1199 	ZERO,
1200 };
1201 
1202 static const enum index action_of_set_nw_ttl[] = {
1203 	ACTION_OF_SET_NW_TTL_NW_TTL,
1204 	ACTION_NEXT,
1205 	ZERO,
1206 };
1207 
1208 static const enum index action_of_push_vlan[] = {
1209 	ACTION_OF_PUSH_VLAN_ETHERTYPE,
1210 	ACTION_NEXT,
1211 	ZERO,
1212 };
1213 
1214 static const enum index action_of_set_vlan_vid[] = {
1215 	ACTION_OF_SET_VLAN_VID_VLAN_VID,
1216 	ACTION_NEXT,
1217 	ZERO,
1218 };
1219 
1220 static const enum index action_of_set_vlan_pcp[] = {
1221 	ACTION_OF_SET_VLAN_PCP_VLAN_PCP,
1222 	ACTION_NEXT,
1223 	ZERO,
1224 };
1225 
1226 static const enum index action_of_pop_mpls[] = {
1227 	ACTION_OF_POP_MPLS_ETHERTYPE,
1228 	ACTION_NEXT,
1229 	ZERO,
1230 };
1231 
1232 static const enum index action_of_push_mpls[] = {
1233 	ACTION_OF_PUSH_MPLS_ETHERTYPE,
1234 	ACTION_NEXT,
1235 	ZERO,
1236 };
1237 
1238 static const enum index action_set_ipv4_src[] = {
1239 	ACTION_SET_IPV4_SRC_IPV4_SRC,
1240 	ACTION_NEXT,
1241 	ZERO,
1242 };
1243 
1244 static const enum index action_set_mac_src[] = {
1245 	ACTION_SET_MAC_SRC_MAC_SRC,
1246 	ACTION_NEXT,
1247 	ZERO,
1248 };
1249 
1250 static const enum index action_set_ipv4_dst[] = {
1251 	ACTION_SET_IPV4_DST_IPV4_DST,
1252 	ACTION_NEXT,
1253 	ZERO,
1254 };
1255 
1256 static const enum index action_set_ipv6_src[] = {
1257 	ACTION_SET_IPV6_SRC_IPV6_SRC,
1258 	ACTION_NEXT,
1259 	ZERO,
1260 };
1261 
1262 static const enum index action_set_ipv6_dst[] = {
1263 	ACTION_SET_IPV6_DST_IPV6_DST,
1264 	ACTION_NEXT,
1265 	ZERO,
1266 };
1267 
1268 static const enum index action_set_tp_src[] = {
1269 	ACTION_SET_TP_SRC_TP_SRC,
1270 	ACTION_NEXT,
1271 	ZERO,
1272 };
1273 
1274 static const enum index action_set_tp_dst[] = {
1275 	ACTION_SET_TP_DST_TP_DST,
1276 	ACTION_NEXT,
1277 	ZERO,
1278 };
1279 
1280 static const enum index action_set_ttl[] = {
1281 	ACTION_SET_TTL_TTL,
1282 	ACTION_NEXT,
1283 	ZERO,
1284 };
1285 
1286 static const enum index action_jump[] = {
1287 	ACTION_JUMP_GROUP,
1288 	ACTION_NEXT,
1289 	ZERO,
1290 };
1291 
1292 static const enum index action_set_mac_dst[] = {
1293 	ACTION_SET_MAC_DST_MAC_DST,
1294 	ACTION_NEXT,
1295 	ZERO,
1296 };
1297 
1298 static const enum index action_inc_tcp_seq[] = {
1299 	ACTION_INC_TCP_SEQ_VALUE,
1300 	ACTION_NEXT,
1301 	ZERO,
1302 };
1303 
1304 static const enum index action_dec_tcp_seq[] = {
1305 	ACTION_DEC_TCP_SEQ_VALUE,
1306 	ACTION_NEXT,
1307 	ZERO,
1308 };
1309 
1310 static const enum index action_inc_tcp_ack[] = {
1311 	ACTION_INC_TCP_ACK_VALUE,
1312 	ACTION_NEXT,
1313 	ZERO,
1314 };
1315 
1316 static const enum index action_dec_tcp_ack[] = {
1317 	ACTION_DEC_TCP_ACK_VALUE,
1318 	ACTION_NEXT,
1319 	ZERO,
1320 };
1321 
1322 static const enum index action_raw_encap[] = {
1323 	ACTION_RAW_ENCAP_INDEX,
1324 	ACTION_NEXT,
1325 	ZERO,
1326 };
1327 
1328 static const enum index action_raw_decap[] = {
1329 	ACTION_RAW_DECAP_INDEX,
1330 	ACTION_NEXT,
1331 	ZERO,
1332 };
1333 
1334 static const enum index action_set_tag[] = {
1335 	ACTION_SET_TAG_DATA,
1336 	ACTION_SET_TAG_INDEX,
1337 	ACTION_SET_TAG_MASK,
1338 	ACTION_NEXT,
1339 	ZERO,
1340 };
1341 
1342 static const enum index action_set_meta[] = {
1343 	ACTION_SET_META_DATA,
1344 	ACTION_SET_META_MASK,
1345 	ACTION_NEXT,
1346 	ZERO,
1347 };
1348 
1349 static const enum index action_set_ipv4_dscp[] = {
1350 	ACTION_SET_IPV4_DSCP_VALUE,
1351 	ACTION_NEXT,
1352 	ZERO,
1353 };
1354 
1355 static const enum index action_set_ipv6_dscp[] = {
1356 	ACTION_SET_IPV6_DSCP_VALUE,
1357 	ACTION_NEXT,
1358 	ZERO,
1359 };
1360 
1361 static int parse_set_raw_encap_decap(struct context *, const struct token *,
1362 				     const char *, unsigned int,
1363 				     void *, unsigned int);
1364 static int parse_set_init(struct context *, const struct token *,
1365 			  const char *, unsigned int,
1366 			  void *, unsigned int);
1367 static int parse_init(struct context *, const struct token *,
1368 		      const char *, unsigned int,
1369 		      void *, unsigned int);
1370 static int parse_vc(struct context *, const struct token *,
1371 		    const char *, unsigned int,
1372 		    void *, unsigned int);
1373 static int parse_vc_spec(struct context *, const struct token *,
1374 			 const char *, unsigned int, void *, unsigned int);
1375 static int parse_vc_conf(struct context *, const struct token *,
1376 			 const char *, unsigned int, void *, unsigned int);
1377 static int parse_vc_action_rss(struct context *, const struct token *,
1378 			       const char *, unsigned int, void *,
1379 			       unsigned int);
1380 static int parse_vc_action_rss_func(struct context *, const struct token *,
1381 				    const char *, unsigned int, void *,
1382 				    unsigned int);
1383 static int parse_vc_action_rss_type(struct context *, const struct token *,
1384 				    const char *, unsigned int, void *,
1385 				    unsigned int);
1386 static int parse_vc_action_rss_queue(struct context *, const struct token *,
1387 				     const char *, unsigned int, void *,
1388 				     unsigned int);
1389 static int parse_vc_action_vxlan_encap(struct context *, const struct token *,
1390 				       const char *, unsigned int, void *,
1391 				       unsigned int);
1392 static int parse_vc_action_nvgre_encap(struct context *, const struct token *,
1393 				       const char *, unsigned int, void *,
1394 				       unsigned int);
1395 static int parse_vc_action_l2_encap(struct context *, const struct token *,
1396 				    const char *, unsigned int, void *,
1397 				    unsigned int);
1398 static int parse_vc_action_l2_decap(struct context *, const struct token *,
1399 				    const char *, unsigned int, void *,
1400 				    unsigned int);
1401 static int parse_vc_action_mplsogre_encap(struct context *,
1402 					  const struct token *, const char *,
1403 					  unsigned int, void *, unsigned int);
1404 static int parse_vc_action_mplsogre_decap(struct context *,
1405 					  const struct token *, const char *,
1406 					  unsigned int, void *, unsigned int);
1407 static int parse_vc_action_mplsoudp_encap(struct context *,
1408 					  const struct token *, const char *,
1409 					  unsigned int, void *, unsigned int);
1410 static int parse_vc_action_mplsoudp_decap(struct context *,
1411 					  const struct token *, const char *,
1412 					  unsigned int, void *, unsigned int);
1413 static int parse_vc_action_raw_encap(struct context *,
1414 				     const struct token *, const char *,
1415 				     unsigned int, void *, unsigned int);
1416 static int parse_vc_action_raw_decap(struct context *,
1417 				     const struct token *, const char *,
1418 				     unsigned int, void *, unsigned int);
1419 static int parse_vc_action_raw_encap_index(struct context *,
1420 					   const struct token *, const char *,
1421 					   unsigned int, void *, unsigned int);
1422 static int parse_vc_action_raw_decap_index(struct context *,
1423 					   const struct token *, const char *,
1424 					   unsigned int, void *, unsigned int);
1425 static int parse_vc_action_set_meta(struct context *ctx,
1426 				    const struct token *token, const char *str,
1427 				    unsigned int len, void *buf,
1428 				    unsigned int size);
1429 static int parse_destroy(struct context *, const struct token *,
1430 			 const char *, unsigned int,
1431 			 void *, unsigned int);
1432 static int parse_flush(struct context *, const struct token *,
1433 		       const char *, unsigned int,
1434 		       void *, unsigned int);
1435 static int parse_dump(struct context *, const struct token *,
1436 		      const char *, unsigned int,
1437 		      void *, unsigned int);
1438 static int parse_query(struct context *, const struct token *,
1439 		       const char *, unsigned int,
1440 		       void *, unsigned int);
1441 static int parse_action(struct context *, const struct token *,
1442 			const char *, unsigned int,
1443 			void *, unsigned int);
1444 static int parse_list(struct context *, const struct token *,
1445 		      const char *, unsigned int,
1446 		      void *, unsigned int);
1447 static int parse_isolate(struct context *, const struct token *,
1448 			 const char *, unsigned int,
1449 			 void *, unsigned int);
1450 static int parse_int(struct context *, const struct token *,
1451 		     const char *, unsigned int,
1452 		     void *, unsigned int);
1453 static int parse_prefix(struct context *, const struct token *,
1454 			const char *, unsigned int,
1455 			void *, unsigned int);
1456 static int parse_boolean(struct context *, const struct token *,
1457 			 const char *, unsigned int,
1458 			 void *, unsigned int);
1459 static int parse_string(struct context *, const struct token *,
1460 			const char *, unsigned int,
1461 			void *, unsigned int);
1462 static int parse_hex(struct context *ctx, const struct token *token,
1463 			const char *str, unsigned int len,
1464 			void *buf, unsigned int size);
1465 static int parse_string0(struct context *, const struct token *,
1466 			const char *, unsigned int,
1467 			void *, unsigned int);
1468 static int parse_mac_addr(struct context *, const struct token *,
1469 			  const char *, unsigned int,
1470 			  void *, unsigned int);
1471 static int parse_ipv4_addr(struct context *, const struct token *,
1472 			   const char *, unsigned int,
1473 			   void *, unsigned int);
1474 static int parse_ipv6_addr(struct context *, const struct token *,
1475 			   const char *, unsigned int,
1476 			   void *, unsigned int);
1477 static int parse_port(struct context *, const struct token *,
1478 		      const char *, unsigned int,
1479 		      void *, unsigned int);
1480 static int comp_none(struct context *, const struct token *,
1481 		     unsigned int, char *, unsigned int);
1482 static int comp_boolean(struct context *, const struct token *,
1483 			unsigned int, char *, unsigned int);
1484 static int comp_action(struct context *, const struct token *,
1485 		       unsigned int, char *, unsigned int);
1486 static int comp_port(struct context *, const struct token *,
1487 		     unsigned int, char *, unsigned int);
1488 static int comp_rule_id(struct context *, const struct token *,
1489 			unsigned int, char *, unsigned int);
1490 static int comp_vc_action_rss_type(struct context *, const struct token *,
1491 				   unsigned int, char *, unsigned int);
1492 static int comp_vc_action_rss_queue(struct context *, const struct token *,
1493 				    unsigned int, char *, unsigned int);
1494 static int comp_set_raw_index(struct context *, const struct token *,
1495 			      unsigned int, char *, unsigned int);
1496 
1497 /** Token definitions. */
1498 static const struct token token_list[] = {
1499 	/* Special tokens. */
1500 	[ZERO] = {
1501 		.name = "ZERO",
1502 		.help = "null entry, abused as the entry point",
1503 		.next = NEXT(NEXT_ENTRY(FLOW)),
1504 	},
1505 	[END] = {
1506 		.name = "",
1507 		.type = "RETURN",
1508 		.help = "command may end here",
1509 	},
1510 	[START_SET] = {
1511 		.name = "START_SET",
1512 		.help = "null entry, abused as the entry point for set",
1513 		.next = NEXT(NEXT_ENTRY(SET)),
1514 	},
1515 	[END_SET] = {
1516 		.name = "end_set",
1517 		.type = "RETURN",
1518 		.help = "set command may end here",
1519 	},
1520 	/* Common tokens. */
1521 	[INTEGER] = {
1522 		.name = "{int}",
1523 		.type = "INTEGER",
1524 		.help = "integer value",
1525 		.call = parse_int,
1526 		.comp = comp_none,
1527 	},
1528 	[UNSIGNED] = {
1529 		.name = "{unsigned}",
1530 		.type = "UNSIGNED",
1531 		.help = "unsigned integer value",
1532 		.call = parse_int,
1533 		.comp = comp_none,
1534 	},
1535 	[PREFIX] = {
1536 		.name = "{prefix}",
1537 		.type = "PREFIX",
1538 		.help = "prefix length for bit-mask",
1539 		.call = parse_prefix,
1540 		.comp = comp_none,
1541 	},
1542 	[BOOLEAN] = {
1543 		.name = "{boolean}",
1544 		.type = "BOOLEAN",
1545 		.help = "any boolean value",
1546 		.call = parse_boolean,
1547 		.comp = comp_boolean,
1548 	},
1549 	[STRING] = {
1550 		.name = "{string}",
1551 		.type = "STRING",
1552 		.help = "fixed string",
1553 		.call = parse_string,
1554 		.comp = comp_none,
1555 	},
1556 	[HEX] = {
1557 		.name = "{hex}",
1558 		.type = "HEX",
1559 		.help = "fixed string",
1560 		.call = parse_hex,
1561 	},
1562 	[FILE_PATH] = {
1563 		.name = "{file path}",
1564 		.type = "STRING",
1565 		.help = "file path",
1566 		.call = parse_string0,
1567 		.comp = comp_none,
1568 	},
1569 	[MAC_ADDR] = {
1570 		.name = "{MAC address}",
1571 		.type = "MAC-48",
1572 		.help = "standard MAC address notation",
1573 		.call = parse_mac_addr,
1574 		.comp = comp_none,
1575 	},
1576 	[IPV4_ADDR] = {
1577 		.name = "{IPv4 address}",
1578 		.type = "IPV4 ADDRESS",
1579 		.help = "standard IPv4 address notation",
1580 		.call = parse_ipv4_addr,
1581 		.comp = comp_none,
1582 	},
1583 	[IPV6_ADDR] = {
1584 		.name = "{IPv6 address}",
1585 		.type = "IPV6 ADDRESS",
1586 		.help = "standard IPv6 address notation",
1587 		.call = parse_ipv6_addr,
1588 		.comp = comp_none,
1589 	},
1590 	[RULE_ID] = {
1591 		.name = "{rule id}",
1592 		.type = "RULE ID",
1593 		.help = "rule identifier",
1594 		.call = parse_int,
1595 		.comp = comp_rule_id,
1596 	},
1597 	[PORT_ID] = {
1598 		.name = "{port_id}",
1599 		.type = "PORT ID",
1600 		.help = "port identifier",
1601 		.call = parse_port,
1602 		.comp = comp_port,
1603 	},
1604 	[GROUP_ID] = {
1605 		.name = "{group_id}",
1606 		.type = "GROUP ID",
1607 		.help = "group identifier",
1608 		.call = parse_int,
1609 		.comp = comp_none,
1610 	},
1611 	[PRIORITY_LEVEL] = {
1612 		.name = "{level}",
1613 		.type = "PRIORITY",
1614 		.help = "priority level",
1615 		.call = parse_int,
1616 		.comp = comp_none,
1617 	},
1618 	/* Top-level command. */
1619 	[FLOW] = {
1620 		.name = "flow",
1621 		.type = "{command} {port_id} [{arg} [...]]",
1622 		.help = "manage ingress/egress flow rules",
1623 		.next = NEXT(NEXT_ENTRY
1624 			     (VALIDATE,
1625 			      CREATE,
1626 			      DESTROY,
1627 			      FLUSH,
1628 			      DUMP,
1629 			      LIST,
1630 			      QUERY,
1631 			      ISOLATE)),
1632 		.call = parse_init,
1633 	},
1634 	/* Sub-level commands. */
1635 	[VALIDATE] = {
1636 		.name = "validate",
1637 		.help = "check whether a flow rule can be created",
1638 		.next = NEXT(next_vc_attr, NEXT_ENTRY(PORT_ID)),
1639 		.args = ARGS(ARGS_ENTRY(struct buffer, port)),
1640 		.call = parse_vc,
1641 	},
1642 	[CREATE] = {
1643 		.name = "create",
1644 		.help = "create a flow rule",
1645 		.next = NEXT(next_vc_attr, NEXT_ENTRY(PORT_ID)),
1646 		.args = ARGS(ARGS_ENTRY(struct buffer, port)),
1647 		.call = parse_vc,
1648 	},
1649 	[DESTROY] = {
1650 		.name = "destroy",
1651 		.help = "destroy specific flow rules",
1652 		.next = NEXT(NEXT_ENTRY(DESTROY_RULE), NEXT_ENTRY(PORT_ID)),
1653 		.args = ARGS(ARGS_ENTRY(struct buffer, port)),
1654 		.call = parse_destroy,
1655 	},
1656 	[FLUSH] = {
1657 		.name = "flush",
1658 		.help = "destroy all flow rules",
1659 		.next = NEXT(NEXT_ENTRY(PORT_ID)),
1660 		.args = ARGS(ARGS_ENTRY(struct buffer, port)),
1661 		.call = parse_flush,
1662 	},
1663 	[DUMP] = {
1664 		.name = "dump",
1665 		.help = "dump all flow rules to file",
1666 		.next = NEXT(next_dump_attr, NEXT_ENTRY(PORT_ID)),
1667 		.args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file),
1668 			     ARGS_ENTRY(struct buffer, port)),
1669 		.call = parse_dump,
1670 	},
1671 	[QUERY] = {
1672 		.name = "query",
1673 		.help = "query an existing flow rule",
1674 		.next = NEXT(NEXT_ENTRY(QUERY_ACTION),
1675 			     NEXT_ENTRY(RULE_ID),
1676 			     NEXT_ENTRY(PORT_ID)),
1677 		.args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type),
1678 			     ARGS_ENTRY(struct buffer, args.query.rule),
1679 			     ARGS_ENTRY(struct buffer, port)),
1680 		.call = parse_query,
1681 	},
1682 	[LIST] = {
1683 		.name = "list",
1684 		.help = "list existing flow rules",
1685 		.next = NEXT(next_list_attr, NEXT_ENTRY(PORT_ID)),
1686 		.args = ARGS(ARGS_ENTRY(struct buffer, port)),
1687 		.call = parse_list,
1688 	},
1689 	[ISOLATE] = {
1690 		.name = "isolate",
1691 		.help = "restrict ingress traffic to the defined flow rules",
1692 		.next = NEXT(NEXT_ENTRY(BOOLEAN),
1693 			     NEXT_ENTRY(PORT_ID)),
1694 		.args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set),
1695 			     ARGS_ENTRY(struct buffer, port)),
1696 		.call = parse_isolate,
1697 	},
1698 	/* Destroy arguments. */
1699 	[DESTROY_RULE] = {
1700 		.name = "rule",
1701 		.help = "specify a rule identifier",
1702 		.next = NEXT(next_destroy_attr, NEXT_ENTRY(RULE_ID)),
1703 		.args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)),
1704 		.call = parse_destroy,
1705 	},
1706 	/* Query arguments. */
1707 	[QUERY_ACTION] = {
1708 		.name = "{action}",
1709 		.type = "ACTION",
1710 		.help = "action to query, must be part of the rule",
1711 		.call = parse_action,
1712 		.comp = comp_action,
1713 	},
1714 	/* List arguments. */
1715 	[LIST_GROUP] = {
1716 		.name = "group",
1717 		.help = "specify a group",
1718 		.next = NEXT(next_list_attr, NEXT_ENTRY(GROUP_ID)),
1719 		.args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)),
1720 		.call = parse_list,
1721 	},
1722 	/* Validate/create attributes. */
1723 	[GROUP] = {
1724 		.name = "group",
1725 		.help = "specify a group",
1726 		.next = NEXT(next_vc_attr, NEXT_ENTRY(GROUP_ID)),
1727 		.args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)),
1728 		.call = parse_vc,
1729 	},
1730 	[PRIORITY] = {
1731 		.name = "priority",
1732 		.help = "specify a priority level",
1733 		.next = NEXT(next_vc_attr, NEXT_ENTRY(PRIORITY_LEVEL)),
1734 		.args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)),
1735 		.call = parse_vc,
1736 	},
1737 	[INGRESS] = {
1738 		.name = "ingress",
1739 		.help = "affect rule to ingress",
1740 		.next = NEXT(next_vc_attr),
1741 		.call = parse_vc,
1742 	},
1743 	[EGRESS] = {
1744 		.name = "egress",
1745 		.help = "affect rule to egress",
1746 		.next = NEXT(next_vc_attr),
1747 		.call = parse_vc,
1748 	},
1749 	[TRANSFER] = {
1750 		.name = "transfer",
1751 		.help = "apply rule directly to endpoints found in pattern",
1752 		.next = NEXT(next_vc_attr),
1753 		.call = parse_vc,
1754 	},
1755 	/* Validate/create pattern. */
1756 	[PATTERN] = {
1757 		.name = "pattern",
1758 		.help = "submit a list of pattern items",
1759 		.next = NEXT(next_item),
1760 		.call = parse_vc,
1761 	},
1762 	[ITEM_PARAM_IS] = {
1763 		.name = "is",
1764 		.help = "match value perfectly (with full bit-mask)",
1765 		.call = parse_vc_spec,
1766 	},
1767 	[ITEM_PARAM_SPEC] = {
1768 		.name = "spec",
1769 		.help = "match value according to configured bit-mask",
1770 		.call = parse_vc_spec,
1771 	},
1772 	[ITEM_PARAM_LAST] = {
1773 		.name = "last",
1774 		.help = "specify upper bound to establish a range",
1775 		.call = parse_vc_spec,
1776 	},
1777 	[ITEM_PARAM_MASK] = {
1778 		.name = "mask",
1779 		.help = "specify bit-mask with relevant bits set to one",
1780 		.call = parse_vc_spec,
1781 	},
1782 	[ITEM_PARAM_PREFIX] = {
1783 		.name = "prefix",
1784 		.help = "generate bit-mask from a prefix length",
1785 		.call = parse_vc_spec,
1786 	},
1787 	[ITEM_NEXT] = {
1788 		.name = "/",
1789 		.help = "specify next pattern item",
1790 		.next = NEXT(next_item),
1791 	},
1792 	[ITEM_END] = {
1793 		.name = "end",
1794 		.help = "end list of pattern items",
1795 		.priv = PRIV_ITEM(END, 0),
1796 		.next = NEXT(NEXT_ENTRY(ACTIONS)),
1797 		.call = parse_vc,
1798 	},
1799 	[ITEM_VOID] = {
1800 		.name = "void",
1801 		.help = "no-op pattern item",
1802 		.priv = PRIV_ITEM(VOID, 0),
1803 		.next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
1804 		.call = parse_vc,
1805 	},
1806 	[ITEM_INVERT] = {
1807 		.name = "invert",
1808 		.help = "perform actions when pattern does not match",
1809 		.priv = PRIV_ITEM(INVERT, 0),
1810 		.next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
1811 		.call = parse_vc,
1812 	},
1813 	[ITEM_ANY] = {
1814 		.name = "any",
1815 		.help = "match any protocol for the current layer",
1816 		.priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)),
1817 		.next = NEXT(item_any),
1818 		.call = parse_vc,
1819 	},
1820 	[ITEM_ANY_NUM] = {
1821 		.name = "num",
1822 		.help = "number of layers covered",
1823 		.next = NEXT(item_any, NEXT_ENTRY(UNSIGNED), item_param),
1824 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)),
1825 	},
1826 	[ITEM_PF] = {
1827 		.name = "pf",
1828 		.help = "match traffic from/to the physical function",
1829 		.priv = PRIV_ITEM(PF, 0),
1830 		.next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
1831 		.call = parse_vc,
1832 	},
1833 	[ITEM_VF] = {
1834 		.name = "vf",
1835 		.help = "match traffic from/to a virtual function ID",
1836 		.priv = PRIV_ITEM(VF, sizeof(struct rte_flow_item_vf)),
1837 		.next = NEXT(item_vf),
1838 		.call = parse_vc,
1839 	},
1840 	[ITEM_VF_ID] = {
1841 		.name = "id",
1842 		.help = "VF ID",
1843 		.next = NEXT(item_vf, NEXT_ENTRY(UNSIGNED), item_param),
1844 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_vf, id)),
1845 	},
1846 	[ITEM_PHY_PORT] = {
1847 		.name = "phy_port",
1848 		.help = "match traffic from/to a specific physical port",
1849 		.priv = PRIV_ITEM(PHY_PORT,
1850 				  sizeof(struct rte_flow_item_phy_port)),
1851 		.next = NEXT(item_phy_port),
1852 		.call = parse_vc,
1853 	},
1854 	[ITEM_PHY_PORT_INDEX] = {
1855 		.name = "index",
1856 		.help = "physical port index",
1857 		.next = NEXT(item_phy_port, NEXT_ENTRY(UNSIGNED), item_param),
1858 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_phy_port, index)),
1859 	},
1860 	[ITEM_PORT_ID] = {
1861 		.name = "port_id",
1862 		.help = "match traffic from/to a given DPDK port ID",
1863 		.priv = PRIV_ITEM(PORT_ID,
1864 				  sizeof(struct rte_flow_item_port_id)),
1865 		.next = NEXT(item_port_id),
1866 		.call = parse_vc,
1867 	},
1868 	[ITEM_PORT_ID_ID] = {
1869 		.name = "id",
1870 		.help = "DPDK port ID",
1871 		.next = NEXT(item_port_id, NEXT_ENTRY(UNSIGNED), item_param),
1872 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)),
1873 	},
1874 	[ITEM_MARK] = {
1875 		.name = "mark",
1876 		.help = "match traffic against value set in previously matched rule",
1877 		.priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)),
1878 		.next = NEXT(item_mark),
1879 		.call = parse_vc,
1880 	},
1881 	[ITEM_MARK_ID] = {
1882 		.name = "id",
1883 		.help = "Integer value to match against",
1884 		.next = NEXT(item_mark, NEXT_ENTRY(UNSIGNED), item_param),
1885 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)),
1886 	},
1887 	[ITEM_RAW] = {
1888 		.name = "raw",
1889 		.help = "match an arbitrary byte string",
1890 		.priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE),
1891 		.next = NEXT(item_raw),
1892 		.call = parse_vc,
1893 	},
1894 	[ITEM_RAW_RELATIVE] = {
1895 		.name = "relative",
1896 		.help = "look for pattern after the previous item",
1897 		.next = NEXT(item_raw, NEXT_ENTRY(BOOLEAN), item_param),
1898 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
1899 					   relative, 1)),
1900 	},
1901 	[ITEM_RAW_SEARCH] = {
1902 		.name = "search",
1903 		.help = "search pattern from offset (see also limit)",
1904 		.next = NEXT(item_raw, NEXT_ENTRY(BOOLEAN), item_param),
1905 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
1906 					   search, 1)),
1907 	},
1908 	[ITEM_RAW_OFFSET] = {
1909 		.name = "offset",
1910 		.help = "absolute or relative offset for pattern",
1911 		.next = NEXT(item_raw, NEXT_ENTRY(INTEGER), item_param),
1912 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)),
1913 	},
1914 	[ITEM_RAW_LIMIT] = {
1915 		.name = "limit",
1916 		.help = "search area limit for start of pattern",
1917 		.next = NEXT(item_raw, NEXT_ENTRY(UNSIGNED), item_param),
1918 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)),
1919 	},
1920 	[ITEM_RAW_PATTERN] = {
1921 		.name = "pattern",
1922 		.help = "byte string to look for",
1923 		.next = NEXT(item_raw,
1924 			     NEXT_ENTRY(STRING),
1925 			     NEXT_ENTRY(ITEM_PARAM_IS,
1926 					ITEM_PARAM_SPEC,
1927 					ITEM_PARAM_MASK)),
1928 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern),
1929 			     ARGS_ENTRY(struct rte_flow_item_raw, length),
1930 			     ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw),
1931 					    ITEM_RAW_PATTERN_SIZE)),
1932 	},
1933 	[ITEM_ETH] = {
1934 		.name = "eth",
1935 		.help = "match Ethernet header",
1936 		.priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
1937 		.next = NEXT(item_eth),
1938 		.call = parse_vc,
1939 	},
1940 	[ITEM_ETH_DST] = {
1941 		.name = "dst",
1942 		.help = "destination MAC",
1943 		.next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param),
1944 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, dst)),
1945 	},
1946 	[ITEM_ETH_SRC] = {
1947 		.name = "src",
1948 		.help = "source MAC",
1949 		.next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param),
1950 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, src)),
1951 	},
1952 	[ITEM_ETH_TYPE] = {
1953 		.name = "type",
1954 		.help = "EtherType",
1955 		.next = NEXT(item_eth, NEXT_ENTRY(UNSIGNED), item_param),
1956 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, type)),
1957 	},
1958 	[ITEM_VLAN] = {
1959 		.name = "vlan",
1960 		.help = "match 802.1Q/ad VLAN tag",
1961 		.priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
1962 		.next = NEXT(item_vlan),
1963 		.call = parse_vc,
1964 	},
1965 	[ITEM_VLAN_TCI] = {
1966 		.name = "tci",
1967 		.help = "tag control information",
1968 		.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1969 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)),
1970 	},
1971 	[ITEM_VLAN_PCP] = {
1972 		.name = "pcp",
1973 		.help = "priority code point",
1974 		.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1975 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
1976 						  tci, "\xe0\x00")),
1977 	},
1978 	[ITEM_VLAN_DEI] = {
1979 		.name = "dei",
1980 		.help = "drop eligible indicator",
1981 		.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1982 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
1983 						  tci, "\x10\x00")),
1984 	},
1985 	[ITEM_VLAN_VID] = {
1986 		.name = "vid",
1987 		.help = "VLAN identifier",
1988 		.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1989 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
1990 						  tci, "\x0f\xff")),
1991 	},
1992 	[ITEM_VLAN_INNER_TYPE] = {
1993 		.name = "inner_type",
1994 		.help = "inner EtherType",
1995 		.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1996 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan,
1997 					     inner_type)),
1998 	},
1999 	[ITEM_IPV4] = {
2000 		.name = "ipv4",
2001 		.help = "match IPv4 header",
2002 		.priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
2003 		.next = NEXT(item_ipv4),
2004 		.call = parse_vc,
2005 	},
2006 	[ITEM_IPV4_TOS] = {
2007 		.name = "tos",
2008 		.help = "type of service",
2009 		.next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
2010 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2011 					     hdr.type_of_service)),
2012 	},
2013 	[ITEM_IPV4_TTL] = {
2014 		.name = "ttl",
2015 		.help = "time to live",
2016 		.next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
2017 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2018 					     hdr.time_to_live)),
2019 	},
2020 	[ITEM_IPV4_PROTO] = {
2021 		.name = "proto",
2022 		.help = "next protocol ID",
2023 		.next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
2024 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2025 					     hdr.next_proto_id)),
2026 	},
2027 	[ITEM_IPV4_SRC] = {
2028 		.name = "src",
2029 		.help = "source address",
2030 		.next = NEXT(item_ipv4, NEXT_ENTRY(IPV4_ADDR), item_param),
2031 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2032 					     hdr.src_addr)),
2033 	},
2034 	[ITEM_IPV4_DST] = {
2035 		.name = "dst",
2036 		.help = "destination address",
2037 		.next = NEXT(item_ipv4, NEXT_ENTRY(IPV4_ADDR), item_param),
2038 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2039 					     hdr.dst_addr)),
2040 	},
2041 	[ITEM_IPV6] = {
2042 		.name = "ipv6",
2043 		.help = "match IPv6 header",
2044 		.priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
2045 		.next = NEXT(item_ipv6),
2046 		.call = parse_vc,
2047 	},
2048 	[ITEM_IPV6_TC] = {
2049 		.name = "tc",
2050 		.help = "traffic class",
2051 		.next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
2052 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
2053 						  hdr.vtc_flow,
2054 						  "\x0f\xf0\x00\x00")),
2055 	},
2056 	[ITEM_IPV6_FLOW] = {
2057 		.name = "flow",
2058 		.help = "flow label",
2059 		.next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
2060 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
2061 						  hdr.vtc_flow,
2062 						  "\x00\x0f\xff\xff")),
2063 	},
2064 	[ITEM_IPV6_PROTO] = {
2065 		.name = "proto",
2066 		.help = "protocol (next header)",
2067 		.next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
2068 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2069 					     hdr.proto)),
2070 	},
2071 	[ITEM_IPV6_HOP] = {
2072 		.name = "hop",
2073 		.help = "hop limit",
2074 		.next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
2075 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2076 					     hdr.hop_limits)),
2077 	},
2078 	[ITEM_IPV6_SRC] = {
2079 		.name = "src",
2080 		.help = "source address",
2081 		.next = NEXT(item_ipv6, NEXT_ENTRY(IPV6_ADDR), item_param),
2082 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2083 					     hdr.src_addr)),
2084 	},
2085 	[ITEM_IPV6_DST] = {
2086 		.name = "dst",
2087 		.help = "destination address",
2088 		.next = NEXT(item_ipv6, NEXT_ENTRY(IPV6_ADDR), item_param),
2089 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2090 					     hdr.dst_addr)),
2091 	},
2092 	[ITEM_ICMP] = {
2093 		.name = "icmp",
2094 		.help = "match ICMP header",
2095 		.priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
2096 		.next = NEXT(item_icmp),
2097 		.call = parse_vc,
2098 	},
2099 	[ITEM_ICMP_TYPE] = {
2100 		.name = "type",
2101 		.help = "ICMP packet type",
2102 		.next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
2103 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
2104 					     hdr.icmp_type)),
2105 	},
2106 	[ITEM_ICMP_CODE] = {
2107 		.name = "code",
2108 		.help = "ICMP packet code",
2109 		.next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
2110 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
2111 					     hdr.icmp_code)),
2112 	},
2113 	[ITEM_UDP] = {
2114 		.name = "udp",
2115 		.help = "match UDP header",
2116 		.priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
2117 		.next = NEXT(item_udp),
2118 		.call = parse_vc,
2119 	},
2120 	[ITEM_UDP_SRC] = {
2121 		.name = "src",
2122 		.help = "UDP source port",
2123 		.next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
2124 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
2125 					     hdr.src_port)),
2126 	},
2127 	[ITEM_UDP_DST] = {
2128 		.name = "dst",
2129 		.help = "UDP destination port",
2130 		.next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
2131 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
2132 					     hdr.dst_port)),
2133 	},
2134 	[ITEM_TCP] = {
2135 		.name = "tcp",
2136 		.help = "match TCP header",
2137 		.priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
2138 		.next = NEXT(item_tcp),
2139 		.call = parse_vc,
2140 	},
2141 	[ITEM_TCP_SRC] = {
2142 		.name = "src",
2143 		.help = "TCP source port",
2144 		.next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
2145 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
2146 					     hdr.src_port)),
2147 	},
2148 	[ITEM_TCP_DST] = {
2149 		.name = "dst",
2150 		.help = "TCP destination port",
2151 		.next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
2152 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
2153 					     hdr.dst_port)),
2154 	},
2155 	[ITEM_TCP_FLAGS] = {
2156 		.name = "flags",
2157 		.help = "TCP flags",
2158 		.next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
2159 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
2160 					     hdr.tcp_flags)),
2161 	},
2162 	[ITEM_SCTP] = {
2163 		.name = "sctp",
2164 		.help = "match SCTP header",
2165 		.priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
2166 		.next = NEXT(item_sctp),
2167 		.call = parse_vc,
2168 	},
2169 	[ITEM_SCTP_SRC] = {
2170 		.name = "src",
2171 		.help = "SCTP source port",
2172 		.next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
2173 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2174 					     hdr.src_port)),
2175 	},
2176 	[ITEM_SCTP_DST] = {
2177 		.name = "dst",
2178 		.help = "SCTP destination port",
2179 		.next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
2180 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2181 					     hdr.dst_port)),
2182 	},
2183 	[ITEM_SCTP_TAG] = {
2184 		.name = "tag",
2185 		.help = "validation tag",
2186 		.next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
2187 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2188 					     hdr.tag)),
2189 	},
2190 	[ITEM_SCTP_CKSUM] = {
2191 		.name = "cksum",
2192 		.help = "checksum",
2193 		.next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
2194 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2195 					     hdr.cksum)),
2196 	},
2197 	[ITEM_VXLAN] = {
2198 		.name = "vxlan",
2199 		.help = "match VXLAN header",
2200 		.priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
2201 		.next = NEXT(item_vxlan),
2202 		.call = parse_vc,
2203 	},
2204 	[ITEM_VXLAN_VNI] = {
2205 		.name = "vni",
2206 		.help = "VXLAN identifier",
2207 		.next = NEXT(item_vxlan, NEXT_ENTRY(UNSIGNED), item_param),
2208 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)),
2209 	},
2210 	[ITEM_E_TAG] = {
2211 		.name = "e_tag",
2212 		.help = "match E-Tag header",
2213 		.priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
2214 		.next = NEXT(item_e_tag),
2215 		.call = parse_vc,
2216 	},
2217 	[ITEM_E_TAG_GRP_ECID_B] = {
2218 		.name = "grp_ecid_b",
2219 		.help = "GRP and E-CID base",
2220 		.next = NEXT(item_e_tag, NEXT_ENTRY(UNSIGNED), item_param),
2221 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag,
2222 						  rsvd_grp_ecid_b,
2223 						  "\x3f\xff")),
2224 	},
2225 	[ITEM_NVGRE] = {
2226 		.name = "nvgre",
2227 		.help = "match NVGRE header",
2228 		.priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
2229 		.next = NEXT(item_nvgre),
2230 		.call = parse_vc,
2231 	},
2232 	[ITEM_NVGRE_TNI] = {
2233 		.name = "tni",
2234 		.help = "virtual subnet ID",
2235 		.next = NEXT(item_nvgre, NEXT_ENTRY(UNSIGNED), item_param),
2236 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)),
2237 	},
2238 	[ITEM_MPLS] = {
2239 		.name = "mpls",
2240 		.help = "match MPLS header",
2241 		.priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
2242 		.next = NEXT(item_mpls),
2243 		.call = parse_vc,
2244 	},
2245 	[ITEM_MPLS_LABEL] = {
2246 		.name = "label",
2247 		.help = "MPLS label",
2248 		.next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param),
2249 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
2250 						  label_tc_s,
2251 						  "\xff\xff\xf0")),
2252 	},
2253 	[ITEM_MPLS_TC] = {
2254 		.name = "tc",
2255 		.help = "MPLS Traffic Class",
2256 		.next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param),
2257 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
2258 						  label_tc_s,
2259 						  "\x00\x00\x0e")),
2260 	},
2261 	[ITEM_MPLS_S] = {
2262 		.name = "s",
2263 		.help = "MPLS Bottom-of-Stack",
2264 		.next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param),
2265 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
2266 						  label_tc_s,
2267 						  "\x00\x00\x01")),
2268 	},
2269 	[ITEM_GRE] = {
2270 		.name = "gre",
2271 		.help = "match GRE header",
2272 		.priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
2273 		.next = NEXT(item_gre),
2274 		.call = parse_vc,
2275 	},
2276 	[ITEM_GRE_PROTO] = {
2277 		.name = "protocol",
2278 		.help = "GRE protocol type",
2279 		.next = NEXT(item_gre, NEXT_ENTRY(UNSIGNED), item_param),
2280 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
2281 					     protocol)),
2282 	},
2283 	[ITEM_GRE_C_RSVD0_VER] = {
2284 		.name = "c_rsvd0_ver",
2285 		.help =
2286 			"checksum (1b), undefined (1b), key bit (1b),"
2287 			" sequence number (1b), reserved 0 (9b),"
2288 			" version (3b)",
2289 		.next = NEXT(item_gre, NEXT_ENTRY(UNSIGNED), item_param),
2290 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
2291 					     c_rsvd0_ver)),
2292 	},
2293 	[ITEM_GRE_C_BIT] = {
2294 		.name = "c_bit",
2295 		.help = "checksum bit (C)",
2296 		.next = NEXT(item_gre, NEXT_ENTRY(BOOLEAN), item_param),
2297 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
2298 						  c_rsvd0_ver,
2299 						  "\x80\x00\x00\x00")),
2300 	},
2301 	[ITEM_GRE_S_BIT] = {
2302 		.name = "s_bit",
2303 		.help = "sequence number bit (S)",
2304 		.next = NEXT(item_gre, NEXT_ENTRY(BOOLEAN), item_param),
2305 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
2306 						  c_rsvd0_ver,
2307 						  "\x10\x00\x00\x00")),
2308 	},
2309 	[ITEM_GRE_K_BIT] = {
2310 		.name = "k_bit",
2311 		.help = "key bit (K)",
2312 		.next = NEXT(item_gre, NEXT_ENTRY(BOOLEAN), item_param),
2313 		.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
2314 						  c_rsvd0_ver,
2315 						  "\x20\x00\x00\x00")),
2316 	},
2317 	[ITEM_FUZZY] = {
2318 		.name = "fuzzy",
2319 		.help = "fuzzy pattern match, expect faster than default",
2320 		.priv = PRIV_ITEM(FUZZY,
2321 				sizeof(struct rte_flow_item_fuzzy)),
2322 		.next = NEXT(item_fuzzy),
2323 		.call = parse_vc,
2324 	},
2325 	[ITEM_FUZZY_THRESH] = {
2326 		.name = "thresh",
2327 		.help = "match accuracy threshold",
2328 		.next = NEXT(item_fuzzy, NEXT_ENTRY(UNSIGNED), item_param),
2329 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy,
2330 					thresh)),
2331 	},
2332 	[ITEM_GTP] = {
2333 		.name = "gtp",
2334 		.help = "match GTP header",
2335 		.priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)),
2336 		.next = NEXT(item_gtp),
2337 		.call = parse_vc,
2338 	},
2339 	[ITEM_GTP_MSG_TYPE] = {
2340 		.name = "msg_type",
2341 		.help = "GTP message type",
2342 		.next = NEXT(item_gtp, NEXT_ENTRY(UNSIGNED), item_param),
2343 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp,
2344 					     msg_type)),
2345 	},
2346 	[ITEM_GTP_TEID] = {
2347 		.name = "teid",
2348 		.help = "tunnel endpoint identifier",
2349 		.next = NEXT(item_gtp, NEXT_ENTRY(UNSIGNED), item_param),
2350 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, teid)),
2351 	},
2352 	[ITEM_GTPC] = {
2353 		.name = "gtpc",
2354 		.help = "match GTP header",
2355 		.priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
2356 		.next = NEXT(item_gtp),
2357 		.call = parse_vc,
2358 	},
2359 	[ITEM_GTPU] = {
2360 		.name = "gtpu",
2361 		.help = "match GTP header",
2362 		.priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)),
2363 		.next = NEXT(item_gtp),
2364 		.call = parse_vc,
2365 	},
2366 	[ITEM_GENEVE] = {
2367 		.name = "geneve",
2368 		.help = "match GENEVE header",
2369 		.priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
2370 		.next = NEXT(item_geneve),
2371 		.call = parse_vc,
2372 	},
2373 	[ITEM_GENEVE_VNI] = {
2374 		.name = "vni",
2375 		.help = "virtual network identifier",
2376 		.next = NEXT(item_geneve, NEXT_ENTRY(UNSIGNED), item_param),
2377 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)),
2378 	},
2379 	[ITEM_GENEVE_PROTO] = {
2380 		.name = "protocol",
2381 		.help = "GENEVE protocol type",
2382 		.next = NEXT(item_geneve, NEXT_ENTRY(UNSIGNED), item_param),
2383 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve,
2384 					     protocol)),
2385 	},
2386 	[ITEM_VXLAN_GPE] = {
2387 		.name = "vxlan-gpe",
2388 		.help = "match VXLAN-GPE header",
2389 		.priv = PRIV_ITEM(VXLAN_GPE,
2390 				  sizeof(struct rte_flow_item_vxlan_gpe)),
2391 		.next = NEXT(item_vxlan_gpe),
2392 		.call = parse_vc,
2393 	},
2394 	[ITEM_VXLAN_GPE_VNI] = {
2395 		.name = "vni",
2396 		.help = "VXLAN-GPE identifier",
2397 		.next = NEXT(item_vxlan_gpe, NEXT_ENTRY(UNSIGNED), item_param),
2398 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe,
2399 					     vni)),
2400 	},
2401 	[ITEM_ARP_ETH_IPV4] = {
2402 		.name = "arp_eth_ipv4",
2403 		.help = "match ARP header for Ethernet/IPv4",
2404 		.priv = PRIV_ITEM(ARP_ETH_IPV4,
2405 				  sizeof(struct rte_flow_item_arp_eth_ipv4)),
2406 		.next = NEXT(item_arp_eth_ipv4),
2407 		.call = parse_vc,
2408 	},
2409 	[ITEM_ARP_ETH_IPV4_SHA] = {
2410 		.name = "sha",
2411 		.help = "sender hardware address",
2412 		.next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(MAC_ADDR),
2413 			     item_param),
2414 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
2415 					     sha)),
2416 	},
2417 	[ITEM_ARP_ETH_IPV4_SPA] = {
2418 		.name = "spa",
2419 		.help = "sender IPv4 address",
2420 		.next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(IPV4_ADDR),
2421 			     item_param),
2422 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
2423 					     spa)),
2424 	},
2425 	[ITEM_ARP_ETH_IPV4_THA] = {
2426 		.name = "tha",
2427 		.help = "target hardware address",
2428 		.next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(MAC_ADDR),
2429 			     item_param),
2430 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
2431 					     tha)),
2432 	},
2433 	[ITEM_ARP_ETH_IPV4_TPA] = {
2434 		.name = "tpa",
2435 		.help = "target IPv4 address",
2436 		.next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(IPV4_ADDR),
2437 			     item_param),
2438 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
2439 					     tpa)),
2440 	},
2441 	[ITEM_IPV6_EXT] = {
2442 		.name = "ipv6_ext",
2443 		.help = "match presence of any IPv6 extension header",
2444 		.priv = PRIV_ITEM(IPV6_EXT,
2445 				  sizeof(struct rte_flow_item_ipv6_ext)),
2446 		.next = NEXT(item_ipv6_ext),
2447 		.call = parse_vc,
2448 	},
2449 	[ITEM_IPV6_EXT_NEXT_HDR] = {
2450 		.name = "next_hdr",
2451 		.help = "next header",
2452 		.next = NEXT(item_ipv6_ext, NEXT_ENTRY(UNSIGNED), item_param),
2453 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext,
2454 					     next_hdr)),
2455 	},
2456 	[ITEM_ICMP6] = {
2457 		.name = "icmp6",
2458 		.help = "match any ICMPv6 header",
2459 		.priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)),
2460 		.next = NEXT(item_icmp6),
2461 		.call = parse_vc,
2462 	},
2463 	[ITEM_ICMP6_TYPE] = {
2464 		.name = "type",
2465 		.help = "ICMPv6 type",
2466 		.next = NEXT(item_icmp6, NEXT_ENTRY(UNSIGNED), item_param),
2467 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6,
2468 					     type)),
2469 	},
2470 	[ITEM_ICMP6_CODE] = {
2471 		.name = "code",
2472 		.help = "ICMPv6 code",
2473 		.next = NEXT(item_icmp6, NEXT_ENTRY(UNSIGNED), item_param),
2474 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6,
2475 					     code)),
2476 	},
2477 	[ITEM_ICMP6_ND_NS] = {
2478 		.name = "icmp6_nd_ns",
2479 		.help = "match ICMPv6 neighbor discovery solicitation",
2480 		.priv = PRIV_ITEM(ICMP6_ND_NS,
2481 				  sizeof(struct rte_flow_item_icmp6_nd_ns)),
2482 		.next = NEXT(item_icmp6_nd_ns),
2483 		.call = parse_vc,
2484 	},
2485 	[ITEM_ICMP6_ND_NS_TARGET_ADDR] = {
2486 		.name = "target_addr",
2487 		.help = "target address",
2488 		.next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(IPV6_ADDR),
2489 			     item_param),
2490 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns,
2491 					     target_addr)),
2492 	},
2493 	[ITEM_ICMP6_ND_NA] = {
2494 		.name = "icmp6_nd_na",
2495 		.help = "match ICMPv6 neighbor discovery advertisement",
2496 		.priv = PRIV_ITEM(ICMP6_ND_NA,
2497 				  sizeof(struct rte_flow_item_icmp6_nd_na)),
2498 		.next = NEXT(item_icmp6_nd_na),
2499 		.call = parse_vc,
2500 	},
2501 	[ITEM_ICMP6_ND_NA_TARGET_ADDR] = {
2502 		.name = "target_addr",
2503 		.help = "target address",
2504 		.next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(IPV6_ADDR),
2505 			     item_param),
2506 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na,
2507 					     target_addr)),
2508 	},
2509 	[ITEM_ICMP6_ND_OPT] = {
2510 		.name = "icmp6_nd_opt",
2511 		.help = "match presence of any ICMPv6 neighbor discovery"
2512 			" option",
2513 		.priv = PRIV_ITEM(ICMP6_ND_OPT,
2514 				  sizeof(struct rte_flow_item_icmp6_nd_opt)),
2515 		.next = NEXT(item_icmp6_nd_opt),
2516 		.call = parse_vc,
2517 	},
2518 	[ITEM_ICMP6_ND_OPT_TYPE] = {
2519 		.name = "type",
2520 		.help = "ND option type",
2521 		.next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(UNSIGNED),
2522 			     item_param),
2523 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt,
2524 					     type)),
2525 	},
2526 	[ITEM_ICMP6_ND_OPT_SLA_ETH] = {
2527 		.name = "icmp6_nd_opt_sla_eth",
2528 		.help = "match ICMPv6 neighbor discovery source Ethernet"
2529 			" link-layer address option",
2530 		.priv = PRIV_ITEM
2531 			(ICMP6_ND_OPT_SLA_ETH,
2532 			 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)),
2533 		.next = NEXT(item_icmp6_nd_opt_sla_eth),
2534 		.call = parse_vc,
2535 	},
2536 	[ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = {
2537 		.name = "sla",
2538 		.help = "source Ethernet LLA",
2539 		.next = NEXT(item_icmp6_nd_opt_sla_eth, NEXT_ENTRY(MAC_ADDR),
2540 			     item_param),
2541 		.args = ARGS(ARGS_ENTRY_HTON
2542 			     (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)),
2543 	},
2544 	[ITEM_ICMP6_ND_OPT_TLA_ETH] = {
2545 		.name = "icmp6_nd_opt_tla_eth",
2546 		.help = "match ICMPv6 neighbor discovery target Ethernet"
2547 			" link-layer address option",
2548 		.priv = PRIV_ITEM
2549 			(ICMP6_ND_OPT_TLA_ETH,
2550 			 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)),
2551 		.next = NEXT(item_icmp6_nd_opt_tla_eth),
2552 		.call = parse_vc,
2553 	},
2554 	[ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = {
2555 		.name = "tla",
2556 		.help = "target Ethernet LLA",
2557 		.next = NEXT(item_icmp6_nd_opt_tla_eth, NEXT_ENTRY(MAC_ADDR),
2558 			     item_param),
2559 		.args = ARGS(ARGS_ENTRY_HTON
2560 			     (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)),
2561 	},
2562 	[ITEM_META] = {
2563 		.name = "meta",
2564 		.help = "match metadata header",
2565 		.priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)),
2566 		.next = NEXT(item_meta),
2567 		.call = parse_vc,
2568 	},
2569 	[ITEM_META_DATA] = {
2570 		.name = "data",
2571 		.help = "metadata value",
2572 		.next = NEXT(item_meta, NEXT_ENTRY(UNSIGNED), item_param),
2573 		.args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta,
2574 					     data, "\xff\xff\xff\xff")),
2575 	},
2576 	[ITEM_GRE_KEY] = {
2577 		.name = "gre_key",
2578 		.help = "match GRE key",
2579 		.priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)),
2580 		.next = NEXT(item_gre_key),
2581 		.call = parse_vc,
2582 	},
2583 	[ITEM_GRE_KEY_VALUE] = {
2584 		.name = "value",
2585 		.help = "key value",
2586 		.next = NEXT(item_gre_key, NEXT_ENTRY(UNSIGNED), item_param),
2587 		.args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
2588 	},
2589 	[ITEM_GTP_PSC] = {
2590 		.name = "gtp_psc",
2591 		.help = "match GTP extension header with type 0x85",
2592 		.priv = PRIV_ITEM(GTP_PSC,
2593 				sizeof(struct rte_flow_item_gtp_psc)),
2594 		.next = NEXT(item_gtp_psc),
2595 		.call = parse_vc,
2596 	},
2597 	[ITEM_GTP_PSC_QFI] = {
2598 		.name = "qfi",
2599 		.help = "QoS flow identifier",
2600 		.next = NEXT(item_gtp_psc, NEXT_ENTRY(UNSIGNED), item_param),
2601 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp_psc,
2602 					qfi)),
2603 	},
2604 	[ITEM_GTP_PSC_PDU_T] = {
2605 		.name = "pdu_t",
2606 		.help = "PDU type",
2607 		.next = NEXT(item_gtp_psc, NEXT_ENTRY(UNSIGNED), item_param),
2608 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp_psc,
2609 					pdu_type)),
2610 	},
2611 	[ITEM_PPPOES] = {
2612 		.name = "pppoes",
2613 		.help = "match PPPoE session header",
2614 		.priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)),
2615 		.next = NEXT(item_pppoes),
2616 		.call = parse_vc,
2617 	},
2618 	[ITEM_PPPOED] = {
2619 		.name = "pppoed",
2620 		.help = "match PPPoE discovery header",
2621 		.priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)),
2622 		.next = NEXT(item_pppoed),
2623 		.call = parse_vc,
2624 	},
2625 	[ITEM_PPPOE_SEID] = {
2626 		.name = "seid",
2627 		.help = "session identifier",
2628 		.next = NEXT(item_pppoes, NEXT_ENTRY(UNSIGNED), item_param),
2629 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe,
2630 					session_id)),
2631 	},
2632 	[ITEM_PPPOE_PROTO_ID] = {
2633 		.name = "proto_id",
2634 		.help = "match PPPoE session protocol identifier",
2635 		.priv = PRIV_ITEM(PPPOE_PROTO_ID,
2636 				sizeof(struct rte_flow_item_pppoe_proto_id)),
2637 		.next = NEXT(item_pppoe_proto_id),
2638 		.call = parse_vc,
2639 	},
2640 	[ITEM_HIGIG2] = {
2641 		.name = "higig2",
2642 		.help = "matches higig2 header",
2643 		.priv = PRIV_ITEM(HIGIG2,
2644 				sizeof(struct rte_flow_item_higig2_hdr)),
2645 		.next = NEXT(item_higig2),
2646 		.call = parse_vc,
2647 	},
2648 	[ITEM_HIGIG2_CLASSIFICATION] = {
2649 		.name = "classification",
2650 		.help = "matches classification of higig2 header",
2651 		.next = NEXT(item_higig2, NEXT_ENTRY(UNSIGNED), item_param),
2652 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr,
2653 					hdr.ppt1.classification)),
2654 	},
2655 	[ITEM_HIGIG2_VID] = {
2656 		.name = "vid",
2657 		.help = "matches vid of higig2 header",
2658 		.next = NEXT(item_higig2, NEXT_ENTRY(UNSIGNED), item_param),
2659 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr,
2660 					hdr.ppt1.vid)),
2661 	},
2662 	[ITEM_TAG] = {
2663 		.name = "tag",
2664 		.help = "match tag value",
2665 		.priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)),
2666 		.next = NEXT(item_tag),
2667 		.call = parse_vc,
2668 	},
2669 	[ITEM_TAG_DATA] = {
2670 		.name = "data",
2671 		.help = "tag value to match",
2672 		.next = NEXT(item_tag, NEXT_ENTRY(UNSIGNED), item_param),
2673 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)),
2674 	},
2675 	[ITEM_TAG_INDEX] = {
2676 		.name = "index",
2677 		.help = "index of tag array to match",
2678 		.next = NEXT(item_tag, NEXT_ENTRY(UNSIGNED),
2679 			     NEXT_ENTRY(ITEM_PARAM_IS)),
2680 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)),
2681 	},
2682 	[ITEM_L2TPV3OIP] = {
2683 		.name = "l2tpv3oip",
2684 		.help = "match L2TPv3 over IP header",
2685 		.priv = PRIV_ITEM(L2TPV3OIP,
2686 				  sizeof(struct rte_flow_item_l2tpv3oip)),
2687 		.next = NEXT(item_l2tpv3oip),
2688 		.call = parse_vc,
2689 	},
2690 	[ITEM_L2TPV3OIP_SESSION_ID] = {
2691 		.name = "session_id",
2692 		.help = "session identifier",
2693 		.next = NEXT(item_l2tpv3oip, NEXT_ENTRY(UNSIGNED), item_param),
2694 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip,
2695 					     session_id)),
2696 	},
2697 	[ITEM_ESP] = {
2698 		.name = "esp",
2699 		.help = "match ESP header",
2700 		.priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)),
2701 		.next = NEXT(item_esp),
2702 		.call = parse_vc,
2703 	},
2704 	[ITEM_ESP_SPI] = {
2705 		.name = "spi",
2706 		.help = "security policy index",
2707 		.next = NEXT(item_esp, NEXT_ENTRY(UNSIGNED), item_param),
2708 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp,
2709 				hdr.spi)),
2710 	},
2711 	[ITEM_AH] = {
2712 		.name = "ah",
2713 		.help = "match AH header",
2714 		.priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)),
2715 		.next = NEXT(item_ah),
2716 		.call = parse_vc,
2717 	},
2718 	[ITEM_AH_SPI] = {
2719 		.name = "spi",
2720 		.help = "security parameters index",
2721 		.next = NEXT(item_ah, NEXT_ENTRY(UNSIGNED), item_param),
2722 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)),
2723 	},
2724 	/* Validate/create actions. */
2725 	[ACTIONS] = {
2726 		.name = "actions",
2727 		.help = "submit a list of associated actions",
2728 		.next = NEXT(next_action),
2729 		.call = parse_vc,
2730 	},
2731 	[ACTION_NEXT] = {
2732 		.name = "/",
2733 		.help = "specify next action",
2734 		.next = NEXT(next_action),
2735 	},
2736 	[ACTION_END] = {
2737 		.name = "end",
2738 		.help = "end list of actions",
2739 		.priv = PRIV_ACTION(END, 0),
2740 		.call = parse_vc,
2741 	},
2742 	[ACTION_VOID] = {
2743 		.name = "void",
2744 		.help = "no-op action",
2745 		.priv = PRIV_ACTION(VOID, 0),
2746 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
2747 		.call = parse_vc,
2748 	},
2749 	[ACTION_PASSTHRU] = {
2750 		.name = "passthru",
2751 		.help = "let subsequent rule process matched packets",
2752 		.priv = PRIV_ACTION(PASSTHRU, 0),
2753 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
2754 		.call = parse_vc,
2755 	},
2756 	[ACTION_JUMP] = {
2757 		.name = "jump",
2758 		.help = "redirect traffic to a given group",
2759 		.priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)),
2760 		.next = NEXT(action_jump),
2761 		.call = parse_vc,
2762 	},
2763 	[ACTION_JUMP_GROUP] = {
2764 		.name = "group",
2765 		.help = "group to redirect traffic to",
2766 		.next = NEXT(action_jump, NEXT_ENTRY(UNSIGNED)),
2767 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)),
2768 		.call = parse_vc_conf,
2769 	},
2770 	[ACTION_MARK] = {
2771 		.name = "mark",
2772 		.help = "attach 32 bit value to packets",
2773 		.priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
2774 		.next = NEXT(action_mark),
2775 		.call = parse_vc,
2776 	},
2777 	[ACTION_MARK_ID] = {
2778 		.name = "id",
2779 		.help = "32 bit value to return with packets",
2780 		.next = NEXT(action_mark, NEXT_ENTRY(UNSIGNED)),
2781 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)),
2782 		.call = parse_vc_conf,
2783 	},
2784 	[ACTION_FLAG] = {
2785 		.name = "flag",
2786 		.help = "flag packets",
2787 		.priv = PRIV_ACTION(FLAG, 0),
2788 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
2789 		.call = parse_vc,
2790 	},
2791 	[ACTION_QUEUE] = {
2792 		.name = "queue",
2793 		.help = "assign packets to a given queue index",
2794 		.priv = PRIV_ACTION(QUEUE,
2795 				    sizeof(struct rte_flow_action_queue)),
2796 		.next = NEXT(action_queue),
2797 		.call = parse_vc,
2798 	},
2799 	[ACTION_QUEUE_INDEX] = {
2800 		.name = "index",
2801 		.help = "queue index to use",
2802 		.next = NEXT(action_queue, NEXT_ENTRY(UNSIGNED)),
2803 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
2804 		.call = parse_vc_conf,
2805 	},
2806 	[ACTION_DROP] = {
2807 		.name = "drop",
2808 		.help = "drop packets (note: passthru has priority)",
2809 		.priv = PRIV_ACTION(DROP, 0),
2810 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
2811 		.call = parse_vc,
2812 	},
2813 	[ACTION_COUNT] = {
2814 		.name = "count",
2815 		.help = "enable counters for this rule",
2816 		.priv = PRIV_ACTION(COUNT,
2817 				    sizeof(struct rte_flow_action_count)),
2818 		.next = NEXT(action_count),
2819 		.call = parse_vc,
2820 	},
2821 	[ACTION_COUNT_ID] = {
2822 		.name = "identifier",
2823 		.help = "counter identifier to use",
2824 		.next = NEXT(action_count, NEXT_ENTRY(UNSIGNED)),
2825 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)),
2826 		.call = parse_vc_conf,
2827 	},
2828 	[ACTION_COUNT_SHARED] = {
2829 		.name = "shared",
2830 		.help = "shared counter",
2831 		.next = NEXT(action_count, NEXT_ENTRY(BOOLEAN)),
2832 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_count,
2833 					   shared, 1)),
2834 		.call = parse_vc_conf,
2835 	},
2836 	[ACTION_RSS] = {
2837 		.name = "rss",
2838 		.help = "spread packets among several queues",
2839 		.priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)),
2840 		.next = NEXT(action_rss),
2841 		.call = parse_vc_action_rss,
2842 	},
2843 	[ACTION_RSS_FUNC] = {
2844 		.name = "func",
2845 		.help = "RSS hash function to apply",
2846 		.next = NEXT(action_rss,
2847 			     NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT,
2848 					ACTION_RSS_FUNC_TOEPLITZ,
2849 					ACTION_RSS_FUNC_SIMPLE_XOR,
2850 					ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)),
2851 	},
2852 	[ACTION_RSS_FUNC_DEFAULT] = {
2853 		.name = "default",
2854 		.help = "default hash function",
2855 		.call = parse_vc_action_rss_func,
2856 	},
2857 	[ACTION_RSS_FUNC_TOEPLITZ] = {
2858 		.name = "toeplitz",
2859 		.help = "Toeplitz hash function",
2860 		.call = parse_vc_action_rss_func,
2861 	},
2862 	[ACTION_RSS_FUNC_SIMPLE_XOR] = {
2863 		.name = "simple_xor",
2864 		.help = "simple XOR hash function",
2865 		.call = parse_vc_action_rss_func,
2866 	},
2867 	[ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = {
2868 		.name = "symmetric_toeplitz",
2869 		.help = "Symmetric Toeplitz hash function",
2870 		.call = parse_vc_action_rss_func,
2871 	},
2872 	[ACTION_RSS_LEVEL] = {
2873 		.name = "level",
2874 		.help = "encapsulation level for \"types\"",
2875 		.next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
2876 		.args = ARGS(ARGS_ENTRY_ARB
2877 			     (offsetof(struct action_rss_data, conf) +
2878 			      offsetof(struct rte_flow_action_rss, level),
2879 			      sizeof(((struct rte_flow_action_rss *)0)->
2880 				     level))),
2881 	},
2882 	[ACTION_RSS_TYPES] = {
2883 		.name = "types",
2884 		.help = "specific RSS hash types",
2885 		.next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)),
2886 	},
2887 	[ACTION_RSS_TYPE] = {
2888 		.name = "{type}",
2889 		.help = "RSS hash type",
2890 		.call = parse_vc_action_rss_type,
2891 		.comp = comp_vc_action_rss_type,
2892 	},
2893 	[ACTION_RSS_KEY] = {
2894 		.name = "key",
2895 		.help = "RSS hash key",
2896 		.next = NEXT(action_rss, NEXT_ENTRY(HEX)),
2897 		.args = ARGS(ARGS_ENTRY_ARB(0, 0),
2898 			     ARGS_ENTRY_ARB
2899 			     (offsetof(struct action_rss_data, conf) +
2900 			      offsetof(struct rte_flow_action_rss, key_len),
2901 			      sizeof(((struct rte_flow_action_rss *)0)->
2902 				     key_len)),
2903 			     ARGS_ENTRY(struct action_rss_data, key)),
2904 	},
2905 	[ACTION_RSS_KEY_LEN] = {
2906 		.name = "key_len",
2907 		.help = "RSS hash key length in bytes",
2908 		.next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
2909 		.args = ARGS(ARGS_ENTRY_ARB_BOUNDED
2910 			     (offsetof(struct action_rss_data, conf) +
2911 			      offsetof(struct rte_flow_action_rss, key_len),
2912 			      sizeof(((struct rte_flow_action_rss *)0)->
2913 				     key_len),
2914 			      0,
2915 			      RSS_HASH_KEY_LENGTH)),
2916 	},
2917 	[ACTION_RSS_QUEUES] = {
2918 		.name = "queues",
2919 		.help = "queue indices to use",
2920 		.next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)),
2921 		.call = parse_vc_conf,
2922 	},
2923 	[ACTION_RSS_QUEUE] = {
2924 		.name = "{queue}",
2925 		.help = "queue index",
2926 		.call = parse_vc_action_rss_queue,
2927 		.comp = comp_vc_action_rss_queue,
2928 	},
2929 	[ACTION_PF] = {
2930 		.name = "pf",
2931 		.help = "direct traffic to physical function",
2932 		.priv = PRIV_ACTION(PF, 0),
2933 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
2934 		.call = parse_vc,
2935 	},
2936 	[ACTION_VF] = {
2937 		.name = "vf",
2938 		.help = "direct traffic to a virtual function ID",
2939 		.priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)),
2940 		.next = NEXT(action_vf),
2941 		.call = parse_vc,
2942 	},
2943 	[ACTION_VF_ORIGINAL] = {
2944 		.name = "original",
2945 		.help = "use original VF ID if possible",
2946 		.next = NEXT(action_vf, NEXT_ENTRY(BOOLEAN)),
2947 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf,
2948 					   original, 1)),
2949 		.call = parse_vc_conf,
2950 	},
2951 	[ACTION_VF_ID] = {
2952 		.name = "id",
2953 		.help = "VF ID",
2954 		.next = NEXT(action_vf, NEXT_ENTRY(UNSIGNED)),
2955 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)),
2956 		.call = parse_vc_conf,
2957 	},
2958 	[ACTION_PHY_PORT] = {
2959 		.name = "phy_port",
2960 		.help = "direct packets to physical port index",
2961 		.priv = PRIV_ACTION(PHY_PORT,
2962 				    sizeof(struct rte_flow_action_phy_port)),
2963 		.next = NEXT(action_phy_port),
2964 		.call = parse_vc,
2965 	},
2966 	[ACTION_PHY_PORT_ORIGINAL] = {
2967 		.name = "original",
2968 		.help = "use original port index if possible",
2969 		.next = NEXT(action_phy_port, NEXT_ENTRY(BOOLEAN)),
2970 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_phy_port,
2971 					   original, 1)),
2972 		.call = parse_vc_conf,
2973 	},
2974 	[ACTION_PHY_PORT_INDEX] = {
2975 		.name = "index",
2976 		.help = "physical port index",
2977 		.next = NEXT(action_phy_port, NEXT_ENTRY(UNSIGNED)),
2978 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_phy_port,
2979 					index)),
2980 		.call = parse_vc_conf,
2981 	},
2982 	[ACTION_PORT_ID] = {
2983 		.name = "port_id",
2984 		.help = "direct matching traffic to a given DPDK port ID",
2985 		.priv = PRIV_ACTION(PORT_ID,
2986 				    sizeof(struct rte_flow_action_port_id)),
2987 		.next = NEXT(action_port_id),
2988 		.call = parse_vc,
2989 	},
2990 	[ACTION_PORT_ID_ORIGINAL] = {
2991 		.name = "original",
2992 		.help = "use original DPDK port ID if possible",
2993 		.next = NEXT(action_port_id, NEXT_ENTRY(BOOLEAN)),
2994 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id,
2995 					   original, 1)),
2996 		.call = parse_vc_conf,
2997 	},
2998 	[ACTION_PORT_ID_ID] = {
2999 		.name = "id",
3000 		.help = "DPDK port ID",
3001 		.next = NEXT(action_port_id, NEXT_ENTRY(UNSIGNED)),
3002 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)),
3003 		.call = parse_vc_conf,
3004 	},
3005 	[ACTION_METER] = {
3006 		.name = "meter",
3007 		.help = "meter the directed packets at given id",
3008 		.priv = PRIV_ACTION(METER,
3009 				    sizeof(struct rte_flow_action_meter)),
3010 		.next = NEXT(action_meter),
3011 		.call = parse_vc,
3012 	},
3013 	[ACTION_METER_ID] = {
3014 		.name = "mtr_id",
3015 		.help = "meter id to use",
3016 		.next = NEXT(action_meter, NEXT_ENTRY(UNSIGNED)),
3017 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)),
3018 		.call = parse_vc_conf,
3019 	},
3020 	[ACTION_OF_SET_MPLS_TTL] = {
3021 		.name = "of_set_mpls_ttl",
3022 		.help = "OpenFlow's OFPAT_SET_MPLS_TTL",
3023 		.priv = PRIV_ACTION
3024 			(OF_SET_MPLS_TTL,
3025 			 sizeof(struct rte_flow_action_of_set_mpls_ttl)),
3026 		.next = NEXT(action_of_set_mpls_ttl),
3027 		.call = parse_vc,
3028 	},
3029 	[ACTION_OF_SET_MPLS_TTL_MPLS_TTL] = {
3030 		.name = "mpls_ttl",
3031 		.help = "MPLS TTL",
3032 		.next = NEXT(action_of_set_mpls_ttl, NEXT_ENTRY(UNSIGNED)),
3033 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_set_mpls_ttl,
3034 					mpls_ttl)),
3035 		.call = parse_vc_conf,
3036 	},
3037 	[ACTION_OF_DEC_MPLS_TTL] = {
3038 		.name = "of_dec_mpls_ttl",
3039 		.help = "OpenFlow's OFPAT_DEC_MPLS_TTL",
3040 		.priv = PRIV_ACTION(OF_DEC_MPLS_TTL, 0),
3041 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3042 		.call = parse_vc,
3043 	},
3044 	[ACTION_OF_SET_NW_TTL] = {
3045 		.name = "of_set_nw_ttl",
3046 		.help = "OpenFlow's OFPAT_SET_NW_TTL",
3047 		.priv = PRIV_ACTION
3048 			(OF_SET_NW_TTL,
3049 			 sizeof(struct rte_flow_action_of_set_nw_ttl)),
3050 		.next = NEXT(action_of_set_nw_ttl),
3051 		.call = parse_vc,
3052 	},
3053 	[ACTION_OF_SET_NW_TTL_NW_TTL] = {
3054 		.name = "nw_ttl",
3055 		.help = "IP TTL",
3056 		.next = NEXT(action_of_set_nw_ttl, NEXT_ENTRY(UNSIGNED)),
3057 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_set_nw_ttl,
3058 					nw_ttl)),
3059 		.call = parse_vc_conf,
3060 	},
3061 	[ACTION_OF_DEC_NW_TTL] = {
3062 		.name = "of_dec_nw_ttl",
3063 		.help = "OpenFlow's OFPAT_DEC_NW_TTL",
3064 		.priv = PRIV_ACTION(OF_DEC_NW_TTL, 0),
3065 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3066 		.call = parse_vc,
3067 	},
3068 	[ACTION_OF_COPY_TTL_OUT] = {
3069 		.name = "of_copy_ttl_out",
3070 		.help = "OpenFlow's OFPAT_COPY_TTL_OUT",
3071 		.priv = PRIV_ACTION(OF_COPY_TTL_OUT, 0),
3072 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3073 		.call = parse_vc,
3074 	},
3075 	[ACTION_OF_COPY_TTL_IN] = {
3076 		.name = "of_copy_ttl_in",
3077 		.help = "OpenFlow's OFPAT_COPY_TTL_IN",
3078 		.priv = PRIV_ACTION(OF_COPY_TTL_IN, 0),
3079 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3080 		.call = parse_vc,
3081 	},
3082 	[ACTION_OF_POP_VLAN] = {
3083 		.name = "of_pop_vlan",
3084 		.help = "OpenFlow's OFPAT_POP_VLAN",
3085 		.priv = PRIV_ACTION(OF_POP_VLAN, 0),
3086 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3087 		.call = parse_vc,
3088 	},
3089 	[ACTION_OF_PUSH_VLAN] = {
3090 		.name = "of_push_vlan",
3091 		.help = "OpenFlow's OFPAT_PUSH_VLAN",
3092 		.priv = PRIV_ACTION
3093 			(OF_PUSH_VLAN,
3094 			 sizeof(struct rte_flow_action_of_push_vlan)),
3095 		.next = NEXT(action_of_push_vlan),
3096 		.call = parse_vc,
3097 	},
3098 	[ACTION_OF_PUSH_VLAN_ETHERTYPE] = {
3099 		.name = "ethertype",
3100 		.help = "EtherType",
3101 		.next = NEXT(action_of_push_vlan, NEXT_ENTRY(UNSIGNED)),
3102 		.args = ARGS(ARGS_ENTRY_HTON
3103 			     (struct rte_flow_action_of_push_vlan,
3104 			      ethertype)),
3105 		.call = parse_vc_conf,
3106 	},
3107 	[ACTION_OF_SET_VLAN_VID] = {
3108 		.name = "of_set_vlan_vid",
3109 		.help = "OpenFlow's OFPAT_SET_VLAN_VID",
3110 		.priv = PRIV_ACTION
3111 			(OF_SET_VLAN_VID,
3112 			 sizeof(struct rte_flow_action_of_set_vlan_vid)),
3113 		.next = NEXT(action_of_set_vlan_vid),
3114 		.call = parse_vc,
3115 	},
3116 	[ACTION_OF_SET_VLAN_VID_VLAN_VID] = {
3117 		.name = "vlan_vid",
3118 		.help = "VLAN id",
3119 		.next = NEXT(action_of_set_vlan_vid, NEXT_ENTRY(UNSIGNED)),
3120 		.args = ARGS(ARGS_ENTRY_HTON
3121 			     (struct rte_flow_action_of_set_vlan_vid,
3122 			      vlan_vid)),
3123 		.call = parse_vc_conf,
3124 	},
3125 	[ACTION_OF_SET_VLAN_PCP] = {
3126 		.name = "of_set_vlan_pcp",
3127 		.help = "OpenFlow's OFPAT_SET_VLAN_PCP",
3128 		.priv = PRIV_ACTION
3129 			(OF_SET_VLAN_PCP,
3130 			 sizeof(struct rte_flow_action_of_set_vlan_pcp)),
3131 		.next = NEXT(action_of_set_vlan_pcp),
3132 		.call = parse_vc,
3133 	},
3134 	[ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = {
3135 		.name = "vlan_pcp",
3136 		.help = "VLAN priority",
3137 		.next = NEXT(action_of_set_vlan_pcp, NEXT_ENTRY(UNSIGNED)),
3138 		.args = ARGS(ARGS_ENTRY_HTON
3139 			     (struct rte_flow_action_of_set_vlan_pcp,
3140 			      vlan_pcp)),
3141 		.call = parse_vc_conf,
3142 	},
3143 	[ACTION_OF_POP_MPLS] = {
3144 		.name = "of_pop_mpls",
3145 		.help = "OpenFlow's OFPAT_POP_MPLS",
3146 		.priv = PRIV_ACTION(OF_POP_MPLS,
3147 				    sizeof(struct rte_flow_action_of_pop_mpls)),
3148 		.next = NEXT(action_of_pop_mpls),
3149 		.call = parse_vc,
3150 	},
3151 	[ACTION_OF_POP_MPLS_ETHERTYPE] = {
3152 		.name = "ethertype",
3153 		.help = "EtherType",
3154 		.next = NEXT(action_of_pop_mpls, NEXT_ENTRY(UNSIGNED)),
3155 		.args = ARGS(ARGS_ENTRY_HTON
3156 			     (struct rte_flow_action_of_pop_mpls,
3157 			      ethertype)),
3158 		.call = parse_vc_conf,
3159 	},
3160 	[ACTION_OF_PUSH_MPLS] = {
3161 		.name = "of_push_mpls",
3162 		.help = "OpenFlow's OFPAT_PUSH_MPLS",
3163 		.priv = PRIV_ACTION
3164 			(OF_PUSH_MPLS,
3165 			 sizeof(struct rte_flow_action_of_push_mpls)),
3166 		.next = NEXT(action_of_push_mpls),
3167 		.call = parse_vc,
3168 	},
3169 	[ACTION_OF_PUSH_MPLS_ETHERTYPE] = {
3170 		.name = "ethertype",
3171 		.help = "EtherType",
3172 		.next = NEXT(action_of_push_mpls, NEXT_ENTRY(UNSIGNED)),
3173 		.args = ARGS(ARGS_ENTRY_HTON
3174 			     (struct rte_flow_action_of_push_mpls,
3175 			      ethertype)),
3176 		.call = parse_vc_conf,
3177 	},
3178 	[ACTION_VXLAN_ENCAP] = {
3179 		.name = "vxlan_encap",
3180 		.help = "VXLAN encapsulation, uses configuration set by \"set"
3181 			" vxlan\"",
3182 		.priv = PRIV_ACTION(VXLAN_ENCAP,
3183 				    sizeof(struct action_vxlan_encap_data)),
3184 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3185 		.call = parse_vc_action_vxlan_encap,
3186 	},
3187 	[ACTION_VXLAN_DECAP] = {
3188 		.name = "vxlan_decap",
3189 		.help = "Performs a decapsulation action by stripping all"
3190 			" headers of the VXLAN tunnel network overlay from the"
3191 			" matched flow.",
3192 		.priv = PRIV_ACTION(VXLAN_DECAP, 0),
3193 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3194 		.call = parse_vc,
3195 	},
3196 	[ACTION_NVGRE_ENCAP] = {
3197 		.name = "nvgre_encap",
3198 		.help = "NVGRE encapsulation, uses configuration set by \"set"
3199 			" nvgre\"",
3200 		.priv = PRIV_ACTION(NVGRE_ENCAP,
3201 				    sizeof(struct action_nvgre_encap_data)),
3202 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3203 		.call = parse_vc_action_nvgre_encap,
3204 	},
3205 	[ACTION_NVGRE_DECAP] = {
3206 		.name = "nvgre_decap",
3207 		.help = "Performs a decapsulation action by stripping all"
3208 			" headers of the NVGRE tunnel network overlay from the"
3209 			" matched flow.",
3210 		.priv = PRIV_ACTION(NVGRE_DECAP, 0),
3211 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3212 		.call = parse_vc,
3213 	},
3214 	[ACTION_L2_ENCAP] = {
3215 		.name = "l2_encap",
3216 		.help = "l2 encap, uses configuration set by"
3217 			" \"set l2_encap\"",
3218 		.priv = PRIV_ACTION(RAW_ENCAP,
3219 				    sizeof(struct action_raw_encap_data)),
3220 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3221 		.call = parse_vc_action_l2_encap,
3222 	},
3223 	[ACTION_L2_DECAP] = {
3224 		.name = "l2_decap",
3225 		.help = "l2 decap, uses configuration set by"
3226 			" \"set l2_decap\"",
3227 		.priv = PRIV_ACTION(RAW_DECAP,
3228 				    sizeof(struct action_raw_decap_data)),
3229 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3230 		.call = parse_vc_action_l2_decap,
3231 	},
3232 	[ACTION_MPLSOGRE_ENCAP] = {
3233 		.name = "mplsogre_encap",
3234 		.help = "mplsogre encapsulation, uses configuration set by"
3235 			" \"set mplsogre_encap\"",
3236 		.priv = PRIV_ACTION(RAW_ENCAP,
3237 				    sizeof(struct action_raw_encap_data)),
3238 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3239 		.call = parse_vc_action_mplsogre_encap,
3240 	},
3241 	[ACTION_MPLSOGRE_DECAP] = {
3242 		.name = "mplsogre_decap",
3243 		.help = "mplsogre decapsulation, uses configuration set by"
3244 			" \"set mplsogre_decap\"",
3245 		.priv = PRIV_ACTION(RAW_DECAP,
3246 				    sizeof(struct action_raw_decap_data)),
3247 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3248 		.call = parse_vc_action_mplsogre_decap,
3249 	},
3250 	[ACTION_MPLSOUDP_ENCAP] = {
3251 		.name = "mplsoudp_encap",
3252 		.help = "mplsoudp encapsulation, uses configuration set by"
3253 			" \"set mplsoudp_encap\"",
3254 		.priv = PRIV_ACTION(RAW_ENCAP,
3255 				    sizeof(struct action_raw_encap_data)),
3256 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3257 		.call = parse_vc_action_mplsoudp_encap,
3258 	},
3259 	[ACTION_MPLSOUDP_DECAP] = {
3260 		.name = "mplsoudp_decap",
3261 		.help = "mplsoudp decapsulation, uses configuration set by"
3262 			" \"set mplsoudp_decap\"",
3263 		.priv = PRIV_ACTION(RAW_DECAP,
3264 				    sizeof(struct action_raw_decap_data)),
3265 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3266 		.call = parse_vc_action_mplsoudp_decap,
3267 	},
3268 	[ACTION_SET_IPV4_SRC] = {
3269 		.name = "set_ipv4_src",
3270 		.help = "Set a new IPv4 source address in the outermost"
3271 			" IPv4 header",
3272 		.priv = PRIV_ACTION(SET_IPV4_SRC,
3273 			sizeof(struct rte_flow_action_set_ipv4)),
3274 		.next = NEXT(action_set_ipv4_src),
3275 		.call = parse_vc,
3276 	},
3277 	[ACTION_SET_IPV4_SRC_IPV4_SRC] = {
3278 		.name = "ipv4_addr",
3279 		.help = "new IPv4 source address to set",
3280 		.next = NEXT(action_set_ipv4_src, NEXT_ENTRY(IPV4_ADDR)),
3281 		.args = ARGS(ARGS_ENTRY_HTON
3282 			(struct rte_flow_action_set_ipv4, ipv4_addr)),
3283 		.call = parse_vc_conf,
3284 	},
3285 	[ACTION_SET_IPV4_DST] = {
3286 		.name = "set_ipv4_dst",
3287 		.help = "Set a new IPv4 destination address in the outermost"
3288 			" IPv4 header",
3289 		.priv = PRIV_ACTION(SET_IPV4_DST,
3290 			sizeof(struct rte_flow_action_set_ipv4)),
3291 		.next = NEXT(action_set_ipv4_dst),
3292 		.call = parse_vc,
3293 	},
3294 	[ACTION_SET_IPV4_DST_IPV4_DST] = {
3295 		.name = "ipv4_addr",
3296 		.help = "new IPv4 destination address to set",
3297 		.next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(IPV4_ADDR)),
3298 		.args = ARGS(ARGS_ENTRY_HTON
3299 			(struct rte_flow_action_set_ipv4, ipv4_addr)),
3300 		.call = parse_vc_conf,
3301 	},
3302 	[ACTION_SET_IPV6_SRC] = {
3303 		.name = "set_ipv6_src",
3304 		.help = "Set a new IPv6 source address in the outermost"
3305 			" IPv6 header",
3306 		.priv = PRIV_ACTION(SET_IPV6_SRC,
3307 			sizeof(struct rte_flow_action_set_ipv6)),
3308 		.next = NEXT(action_set_ipv6_src),
3309 		.call = parse_vc,
3310 	},
3311 	[ACTION_SET_IPV6_SRC_IPV6_SRC] = {
3312 		.name = "ipv6_addr",
3313 		.help = "new IPv6 source address to set",
3314 		.next = NEXT(action_set_ipv6_src, NEXT_ENTRY(IPV6_ADDR)),
3315 		.args = ARGS(ARGS_ENTRY_HTON
3316 			(struct rte_flow_action_set_ipv6, ipv6_addr)),
3317 		.call = parse_vc_conf,
3318 	},
3319 	[ACTION_SET_IPV6_DST] = {
3320 		.name = "set_ipv6_dst",
3321 		.help = "Set a new IPv6 destination address in the outermost"
3322 			" IPv6 header",
3323 		.priv = PRIV_ACTION(SET_IPV6_DST,
3324 			sizeof(struct rte_flow_action_set_ipv6)),
3325 		.next = NEXT(action_set_ipv6_dst),
3326 		.call = parse_vc,
3327 	},
3328 	[ACTION_SET_IPV6_DST_IPV6_DST] = {
3329 		.name = "ipv6_addr",
3330 		.help = "new IPv6 destination address to set",
3331 		.next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(IPV6_ADDR)),
3332 		.args = ARGS(ARGS_ENTRY_HTON
3333 			(struct rte_flow_action_set_ipv6, ipv6_addr)),
3334 		.call = parse_vc_conf,
3335 	},
3336 	[ACTION_SET_TP_SRC] = {
3337 		.name = "set_tp_src",
3338 		.help = "set a new source port number in the outermost"
3339 			" TCP/UDP header",
3340 		.priv = PRIV_ACTION(SET_TP_SRC,
3341 			sizeof(struct rte_flow_action_set_tp)),
3342 		.next = NEXT(action_set_tp_src),
3343 		.call = parse_vc,
3344 	},
3345 	[ACTION_SET_TP_SRC_TP_SRC] = {
3346 		.name = "port",
3347 		.help = "new source port number to set",
3348 		.next = NEXT(action_set_tp_src, NEXT_ENTRY(UNSIGNED)),
3349 		.args = ARGS(ARGS_ENTRY_HTON
3350 			     (struct rte_flow_action_set_tp, port)),
3351 		.call = parse_vc_conf,
3352 	},
3353 	[ACTION_SET_TP_DST] = {
3354 		.name = "set_tp_dst",
3355 		.help = "set a new destination port number in the outermost"
3356 			" TCP/UDP header",
3357 		.priv = PRIV_ACTION(SET_TP_DST,
3358 			sizeof(struct rte_flow_action_set_tp)),
3359 		.next = NEXT(action_set_tp_dst),
3360 		.call = parse_vc,
3361 	},
3362 	[ACTION_SET_TP_DST_TP_DST] = {
3363 		.name = "port",
3364 		.help = "new destination port number to set",
3365 		.next = NEXT(action_set_tp_dst, NEXT_ENTRY(UNSIGNED)),
3366 		.args = ARGS(ARGS_ENTRY_HTON
3367 			     (struct rte_flow_action_set_tp, port)),
3368 		.call = parse_vc_conf,
3369 	},
3370 	[ACTION_MAC_SWAP] = {
3371 		.name = "mac_swap",
3372 		.help = "Swap the source and destination MAC addresses"
3373 			" in the outermost Ethernet header",
3374 		.priv = PRIV_ACTION(MAC_SWAP, 0),
3375 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3376 		.call = parse_vc,
3377 	},
3378 	[ACTION_DEC_TTL] = {
3379 		.name = "dec_ttl",
3380 		.help = "decrease network TTL if available",
3381 		.priv = PRIV_ACTION(DEC_TTL, 0),
3382 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3383 		.call = parse_vc,
3384 	},
3385 	[ACTION_SET_TTL] = {
3386 		.name = "set_ttl",
3387 		.help = "set ttl value",
3388 		.priv = PRIV_ACTION(SET_TTL,
3389 			sizeof(struct rte_flow_action_set_ttl)),
3390 		.next = NEXT(action_set_ttl),
3391 		.call = parse_vc,
3392 	},
3393 	[ACTION_SET_TTL_TTL] = {
3394 		.name = "ttl_value",
3395 		.help = "new ttl value to set",
3396 		.next = NEXT(action_set_ttl, NEXT_ENTRY(UNSIGNED)),
3397 		.args = ARGS(ARGS_ENTRY_HTON
3398 			     (struct rte_flow_action_set_ttl, ttl_value)),
3399 		.call = parse_vc_conf,
3400 	},
3401 	[ACTION_SET_MAC_SRC] = {
3402 		.name = "set_mac_src",
3403 		.help = "set source mac address",
3404 		.priv = PRIV_ACTION(SET_MAC_SRC,
3405 			sizeof(struct rte_flow_action_set_mac)),
3406 		.next = NEXT(action_set_mac_src),
3407 		.call = parse_vc,
3408 	},
3409 	[ACTION_SET_MAC_SRC_MAC_SRC] = {
3410 		.name = "mac_addr",
3411 		.help = "new source mac address",
3412 		.next = NEXT(action_set_mac_src, NEXT_ENTRY(MAC_ADDR)),
3413 		.args = ARGS(ARGS_ENTRY_HTON
3414 			     (struct rte_flow_action_set_mac, mac_addr)),
3415 		.call = parse_vc_conf,
3416 	},
3417 	[ACTION_SET_MAC_DST] = {
3418 		.name = "set_mac_dst",
3419 		.help = "set destination mac address",
3420 		.priv = PRIV_ACTION(SET_MAC_DST,
3421 			sizeof(struct rte_flow_action_set_mac)),
3422 		.next = NEXT(action_set_mac_dst),
3423 		.call = parse_vc,
3424 	},
3425 	[ACTION_SET_MAC_DST_MAC_DST] = {
3426 		.name = "mac_addr",
3427 		.help = "new destination mac address to set",
3428 		.next = NEXT(action_set_mac_dst, NEXT_ENTRY(MAC_ADDR)),
3429 		.args = ARGS(ARGS_ENTRY_HTON
3430 			     (struct rte_flow_action_set_mac, mac_addr)),
3431 		.call = parse_vc_conf,
3432 	},
3433 	[ACTION_INC_TCP_SEQ] = {
3434 		.name = "inc_tcp_seq",
3435 		.help = "increase TCP sequence number",
3436 		.priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)),
3437 		.next = NEXT(action_inc_tcp_seq),
3438 		.call = parse_vc,
3439 	},
3440 	[ACTION_INC_TCP_SEQ_VALUE] = {
3441 		.name = "value",
3442 		.help = "the value to increase TCP sequence number by",
3443 		.next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(UNSIGNED)),
3444 		.args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
3445 		.call = parse_vc_conf,
3446 	},
3447 	[ACTION_DEC_TCP_SEQ] = {
3448 		.name = "dec_tcp_seq",
3449 		.help = "decrease TCP sequence number",
3450 		.priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)),
3451 		.next = NEXT(action_dec_tcp_seq),
3452 		.call = parse_vc,
3453 	},
3454 	[ACTION_DEC_TCP_SEQ_VALUE] = {
3455 		.name = "value",
3456 		.help = "the value to decrease TCP sequence number by",
3457 		.next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(UNSIGNED)),
3458 		.args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
3459 		.call = parse_vc_conf,
3460 	},
3461 	[ACTION_INC_TCP_ACK] = {
3462 		.name = "inc_tcp_ack",
3463 		.help = "increase TCP acknowledgment number",
3464 		.priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)),
3465 		.next = NEXT(action_inc_tcp_ack),
3466 		.call = parse_vc,
3467 	},
3468 	[ACTION_INC_TCP_ACK_VALUE] = {
3469 		.name = "value",
3470 		.help = "the value to increase TCP acknowledgment number by",
3471 		.next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(UNSIGNED)),
3472 		.args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
3473 		.call = parse_vc_conf,
3474 	},
3475 	[ACTION_DEC_TCP_ACK] = {
3476 		.name = "dec_tcp_ack",
3477 		.help = "decrease TCP acknowledgment number",
3478 		.priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
3479 		.next = NEXT(action_dec_tcp_ack),
3480 		.call = parse_vc,
3481 	},
3482 	[ACTION_DEC_TCP_ACK_VALUE] = {
3483 		.name = "value",
3484 		.help = "the value to decrease TCP acknowledgment number by",
3485 		.next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(UNSIGNED)),
3486 		.args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
3487 		.call = parse_vc_conf,
3488 	},
3489 	[ACTION_RAW_ENCAP] = {
3490 		.name = "raw_encap",
3491 		.help = "encapsulation data, defined by set raw_encap",
3492 		.priv = PRIV_ACTION(RAW_ENCAP,
3493 			sizeof(struct action_raw_encap_data)),
3494 		.next = NEXT(action_raw_encap),
3495 		.call = parse_vc_action_raw_encap,
3496 	},
3497 	[ACTION_RAW_ENCAP_INDEX] = {
3498 		.name = "index",
3499 		.help = "the index of raw_encap_confs",
3500 		.next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)),
3501 	},
3502 	[ACTION_RAW_ENCAP_INDEX_VALUE] = {
3503 		.name = "{index}",
3504 		.type = "UNSIGNED",
3505 		.help = "unsigned integer value",
3506 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3507 		.call = parse_vc_action_raw_encap_index,
3508 		.comp = comp_set_raw_index,
3509 	},
3510 	[ACTION_RAW_DECAP] = {
3511 		.name = "raw_decap",
3512 		.help = "decapsulation data, defined by set raw_encap",
3513 		.priv = PRIV_ACTION(RAW_DECAP,
3514 			sizeof(struct action_raw_decap_data)),
3515 		.next = NEXT(action_raw_decap),
3516 		.call = parse_vc_action_raw_decap,
3517 	},
3518 	[ACTION_RAW_DECAP_INDEX] = {
3519 		.name = "index",
3520 		.help = "the index of raw_encap_confs",
3521 		.next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)),
3522 	},
3523 	[ACTION_RAW_DECAP_INDEX_VALUE] = {
3524 		.name = "{index}",
3525 		.type = "UNSIGNED",
3526 		.help = "unsigned integer value",
3527 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3528 		.call = parse_vc_action_raw_decap_index,
3529 		.comp = comp_set_raw_index,
3530 	},
3531 	/* Top level command. */
3532 	[SET] = {
3533 		.name = "set",
3534 		.help = "set raw encap/decap data",
3535 		.type = "set raw_encap|raw_decap <index> <pattern>",
3536 		.next = NEXT(NEXT_ENTRY
3537 			     (SET_RAW_ENCAP,
3538 			      SET_RAW_DECAP)),
3539 		.call = parse_set_init,
3540 	},
3541 	/* Sub-level commands. */
3542 	[SET_RAW_ENCAP] = {
3543 		.name = "raw_encap",
3544 		.help = "set raw encap data",
3545 		.next = NEXT(next_set_raw),
3546 		.args = ARGS(ARGS_ENTRY_ARB_BOUNDED
3547 				(offsetof(struct buffer, port),
3548 				 sizeof(((struct buffer *)0)->port),
3549 				 0, RAW_ENCAP_CONFS_MAX_NUM - 1)),
3550 		.call = parse_set_raw_encap_decap,
3551 	},
3552 	[SET_RAW_DECAP] = {
3553 		.name = "raw_decap",
3554 		.help = "set raw decap data",
3555 		.next = NEXT(next_set_raw),
3556 		.args = ARGS(ARGS_ENTRY_ARB_BOUNDED
3557 				(offsetof(struct buffer, port),
3558 				 sizeof(((struct buffer *)0)->port),
3559 				 0, RAW_ENCAP_CONFS_MAX_NUM - 1)),
3560 		.call = parse_set_raw_encap_decap,
3561 	},
3562 	[SET_RAW_INDEX] = {
3563 		.name = "{index}",
3564 		.type = "UNSIGNED",
3565 		.help = "index of raw_encap/raw_decap data",
3566 		.next = NEXT(next_item),
3567 		.call = parse_port,
3568 	},
3569 	[ACTION_SET_TAG] = {
3570 		.name = "set_tag",
3571 		.help = "set tag",
3572 		.priv = PRIV_ACTION(SET_TAG,
3573 			sizeof(struct rte_flow_action_set_tag)),
3574 		.next = NEXT(action_set_tag),
3575 		.call = parse_vc,
3576 	},
3577 	[ACTION_SET_TAG_INDEX] = {
3578 		.name = "index",
3579 		.help = "index of tag array",
3580 		.next = NEXT(action_set_tag, NEXT_ENTRY(UNSIGNED)),
3581 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)),
3582 		.call = parse_vc_conf,
3583 	},
3584 	[ACTION_SET_TAG_DATA] = {
3585 		.name = "data",
3586 		.help = "tag value",
3587 		.next = NEXT(action_set_tag, NEXT_ENTRY(UNSIGNED)),
3588 		.args = ARGS(ARGS_ENTRY
3589 			     (struct rte_flow_action_set_tag, data)),
3590 		.call = parse_vc_conf,
3591 	},
3592 	[ACTION_SET_TAG_MASK] = {
3593 		.name = "mask",
3594 		.help = "mask for tag value",
3595 		.next = NEXT(action_set_tag, NEXT_ENTRY(UNSIGNED)),
3596 		.args = ARGS(ARGS_ENTRY
3597 			     (struct rte_flow_action_set_tag, mask)),
3598 		.call = parse_vc_conf,
3599 	},
3600 	[ACTION_SET_META] = {
3601 		.name = "set_meta",
3602 		.help = "set metadata",
3603 		.priv = PRIV_ACTION(SET_META,
3604 			sizeof(struct rte_flow_action_set_meta)),
3605 		.next = NEXT(action_set_meta),
3606 		.call = parse_vc_action_set_meta,
3607 	},
3608 	[ACTION_SET_META_DATA] = {
3609 		.name = "data",
3610 		.help = "metadata value",
3611 		.next = NEXT(action_set_meta, NEXT_ENTRY(UNSIGNED)),
3612 		.args = ARGS(ARGS_ENTRY
3613 			     (struct rte_flow_action_set_meta, data)),
3614 		.call = parse_vc_conf,
3615 	},
3616 	[ACTION_SET_META_MASK] = {
3617 		.name = "mask",
3618 		.help = "mask for metadata value",
3619 		.next = NEXT(action_set_meta, NEXT_ENTRY(UNSIGNED)),
3620 		.args = ARGS(ARGS_ENTRY
3621 			     (struct rte_flow_action_set_meta, mask)),
3622 		.call = parse_vc_conf,
3623 	},
3624 	[ACTION_SET_IPV4_DSCP] = {
3625 		.name = "set_ipv4_dscp",
3626 		.help = "set DSCP value",
3627 		.priv = PRIV_ACTION(SET_IPV4_DSCP,
3628 			sizeof(struct rte_flow_action_set_dscp)),
3629 		.next = NEXT(action_set_ipv4_dscp),
3630 		.call = parse_vc,
3631 	},
3632 	[ACTION_SET_IPV4_DSCP_VALUE] = {
3633 		.name = "dscp_value",
3634 		.help = "new IPv4 DSCP value to set",
3635 		.next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(UNSIGNED)),
3636 		.args = ARGS(ARGS_ENTRY
3637 			     (struct rte_flow_action_set_dscp, dscp)),
3638 		.call = parse_vc_conf,
3639 	},
3640 	[ACTION_SET_IPV6_DSCP] = {
3641 		.name = "set_ipv6_dscp",
3642 		.help = "set DSCP value",
3643 		.priv = PRIV_ACTION(SET_IPV6_DSCP,
3644 			sizeof(struct rte_flow_action_set_dscp)),
3645 		.next = NEXT(action_set_ipv6_dscp),
3646 		.call = parse_vc,
3647 	},
3648 	[ACTION_SET_IPV6_DSCP_VALUE] = {
3649 		.name = "dscp_value",
3650 		.help = "new IPv6 DSCP value to set",
3651 		.next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(UNSIGNED)),
3652 		.args = ARGS(ARGS_ENTRY
3653 			     (struct rte_flow_action_set_dscp, dscp)),
3654 		.call = parse_vc_conf,
3655 	},
3656 };
3657 
3658 /** Remove and return last entry from argument stack. */
3659 static const struct arg *
3660 pop_args(struct context *ctx)
3661 {
3662 	return ctx->args_num ? ctx->args[--ctx->args_num] : NULL;
3663 }
3664 
3665 /** Add entry on top of the argument stack. */
3666 static int
3667 push_args(struct context *ctx, const struct arg *arg)
3668 {
3669 	if (ctx->args_num == CTX_STACK_SIZE)
3670 		return -1;
3671 	ctx->args[ctx->args_num++] = arg;
3672 	return 0;
3673 }
3674 
3675 /** Spread value into buffer according to bit-mask. */
3676 static size_t
3677 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg)
3678 {
3679 	uint32_t i = arg->size;
3680 	uint32_t end = 0;
3681 	int sub = 1;
3682 	int add = 0;
3683 	size_t len = 0;
3684 
3685 	if (!arg->mask)
3686 		return 0;
3687 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
3688 	if (!arg->hton) {
3689 		i = 0;
3690 		end = arg->size;
3691 		sub = 0;
3692 		add = 1;
3693 	}
3694 #endif
3695 	while (i != end) {
3696 		unsigned int shift = 0;
3697 		uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub);
3698 
3699 		for (shift = 0; arg->mask[i] >> shift; ++shift) {
3700 			if (!(arg->mask[i] & (1 << shift)))
3701 				continue;
3702 			++len;
3703 			if (!dst)
3704 				continue;
3705 			*buf &= ~(1 << shift);
3706 			*buf |= (val & 1) << shift;
3707 			val >>= 1;
3708 		}
3709 		i += add;
3710 	}
3711 	return len;
3712 }
3713 
3714 /** Compare a string with a partial one of a given length. */
3715 static int
3716 strcmp_partial(const char *full, const char *partial, size_t partial_len)
3717 {
3718 	int r = strncmp(full, partial, partial_len);
3719 
3720 	if (r)
3721 		return r;
3722 	if (strlen(full) <= partial_len)
3723 		return 0;
3724 	return full[partial_len];
3725 }
3726 
3727 /**
3728  * Parse a prefix length and generate a bit-mask.
3729  *
3730  * Last argument (ctx->args) is retrieved to determine mask size, storage
3731  * location and whether the result must use network byte ordering.
3732  */
3733 static int
3734 parse_prefix(struct context *ctx, const struct token *token,
3735 	     const char *str, unsigned int len,
3736 	     void *buf, unsigned int size)
3737 {
3738 	const struct arg *arg = pop_args(ctx);
3739 	static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff";
3740 	char *end;
3741 	uintmax_t u;
3742 	unsigned int bytes;
3743 	unsigned int extra;
3744 
3745 	(void)token;
3746 	/* Argument is expected. */
3747 	if (!arg)
3748 		return -1;
3749 	errno = 0;
3750 	u = strtoumax(str, &end, 0);
3751 	if (errno || (size_t)(end - str) != len)
3752 		goto error;
3753 	if (arg->mask) {
3754 		uintmax_t v = 0;
3755 
3756 		extra = arg_entry_bf_fill(NULL, 0, arg);
3757 		if (u > extra)
3758 			goto error;
3759 		if (!ctx->object)
3760 			return len;
3761 		extra -= u;
3762 		while (u--)
3763 			(v <<= 1, v |= 1);
3764 		v <<= extra;
3765 		if (!arg_entry_bf_fill(ctx->object, v, arg) ||
3766 		    !arg_entry_bf_fill(ctx->objmask, -1, arg))
3767 			goto error;
3768 		return len;
3769 	}
3770 	bytes = u / 8;
3771 	extra = u % 8;
3772 	size = arg->size;
3773 	if (bytes > size || bytes + !!extra > size)
3774 		goto error;
3775 	if (!ctx->object)
3776 		return len;
3777 	buf = (uint8_t *)ctx->object + arg->offset;
3778 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
3779 	if (!arg->hton) {
3780 		memset((uint8_t *)buf + size - bytes, 0xff, bytes);
3781 		memset(buf, 0x00, size - bytes);
3782 		if (extra)
3783 			((uint8_t *)buf)[size - bytes - 1] = conv[extra];
3784 	} else
3785 #endif
3786 	{
3787 		memset(buf, 0xff, bytes);
3788 		memset((uint8_t *)buf + bytes, 0x00, size - bytes);
3789 		if (extra)
3790 			((uint8_t *)buf)[bytes] = conv[extra];
3791 	}
3792 	if (ctx->objmask)
3793 		memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
3794 	return len;
3795 error:
3796 	push_args(ctx, arg);
3797 	return -1;
3798 }
3799 
3800 /** Default parsing function for token name matching. */
3801 static int
3802 parse_default(struct context *ctx, const struct token *token,
3803 	      const char *str, unsigned int len,
3804 	      void *buf, unsigned int size)
3805 {
3806 	(void)ctx;
3807 	(void)buf;
3808 	(void)size;
3809 	if (strcmp_partial(token->name, str, len))
3810 		return -1;
3811 	return len;
3812 }
3813 
3814 /** Parse flow command, initialize output buffer for subsequent tokens. */
3815 static int
3816 parse_init(struct context *ctx, const struct token *token,
3817 	   const char *str, unsigned int len,
3818 	   void *buf, unsigned int size)
3819 {
3820 	struct buffer *out = buf;
3821 
3822 	/* Token name must match. */
3823 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
3824 		return -1;
3825 	/* Nothing else to do if there is no buffer. */
3826 	if (!out)
3827 		return len;
3828 	/* Make sure buffer is large enough. */
3829 	if (size < sizeof(*out))
3830 		return -1;
3831 	/* Initialize buffer. */
3832 	memset(out, 0x00, sizeof(*out));
3833 	memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out));
3834 	ctx->objdata = 0;
3835 	ctx->object = out;
3836 	ctx->objmask = NULL;
3837 	return len;
3838 }
3839 
3840 /** Parse tokens for validate/create commands. */
3841 static int
3842 parse_vc(struct context *ctx, const struct token *token,
3843 	 const char *str, unsigned int len,
3844 	 void *buf, unsigned int size)
3845 {
3846 	struct buffer *out = buf;
3847 	uint8_t *data;
3848 	uint32_t data_size;
3849 
3850 	/* Token name must match. */
3851 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
3852 		return -1;
3853 	/* Nothing else to do if there is no buffer. */
3854 	if (!out)
3855 		return len;
3856 	if (!out->command) {
3857 		if (ctx->curr != VALIDATE && ctx->curr != CREATE)
3858 			return -1;
3859 		if (sizeof(*out) > size)
3860 			return -1;
3861 		out->command = ctx->curr;
3862 		ctx->objdata = 0;
3863 		ctx->object = out;
3864 		ctx->objmask = NULL;
3865 		out->args.vc.data = (uint8_t *)out + size;
3866 		return len;
3867 	}
3868 	ctx->objdata = 0;
3869 	ctx->object = &out->args.vc.attr;
3870 	ctx->objmask = NULL;
3871 	switch (ctx->curr) {
3872 	case GROUP:
3873 	case PRIORITY:
3874 		return len;
3875 	case INGRESS:
3876 		out->args.vc.attr.ingress = 1;
3877 		return len;
3878 	case EGRESS:
3879 		out->args.vc.attr.egress = 1;
3880 		return len;
3881 	case TRANSFER:
3882 		out->args.vc.attr.transfer = 1;
3883 		return len;
3884 	case PATTERN:
3885 		out->args.vc.pattern =
3886 			(void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
3887 					       sizeof(double));
3888 		ctx->object = out->args.vc.pattern;
3889 		ctx->objmask = NULL;
3890 		return len;
3891 	case ACTIONS:
3892 		out->args.vc.actions =
3893 			(void *)RTE_ALIGN_CEIL((uintptr_t)
3894 					       (out->args.vc.pattern +
3895 						out->args.vc.pattern_n),
3896 					       sizeof(double));
3897 		ctx->object = out->args.vc.actions;
3898 		ctx->objmask = NULL;
3899 		return len;
3900 	default:
3901 		if (!token->priv)
3902 			return -1;
3903 		break;
3904 	}
3905 	if (!out->args.vc.actions) {
3906 		const struct parse_item_priv *priv = token->priv;
3907 		struct rte_flow_item *item =
3908 			out->args.vc.pattern + out->args.vc.pattern_n;
3909 
3910 		data_size = priv->size * 3; /* spec, last, mask */
3911 		data = (void *)RTE_ALIGN_FLOOR((uintptr_t)
3912 					       (out->args.vc.data - data_size),
3913 					       sizeof(double));
3914 		if ((uint8_t *)item + sizeof(*item) > data)
3915 			return -1;
3916 		*item = (struct rte_flow_item){
3917 			.type = priv->type,
3918 		};
3919 		++out->args.vc.pattern_n;
3920 		ctx->object = item;
3921 		ctx->objmask = NULL;
3922 	} else {
3923 		const struct parse_action_priv *priv = token->priv;
3924 		struct rte_flow_action *action =
3925 			out->args.vc.actions + out->args.vc.actions_n;
3926 
3927 		data_size = priv->size; /* configuration */
3928 		data = (void *)RTE_ALIGN_FLOOR((uintptr_t)
3929 					       (out->args.vc.data - data_size),
3930 					       sizeof(double));
3931 		if ((uint8_t *)action + sizeof(*action) > data)
3932 			return -1;
3933 		*action = (struct rte_flow_action){
3934 			.type = priv->type,
3935 			.conf = data_size ? data : NULL,
3936 		};
3937 		++out->args.vc.actions_n;
3938 		ctx->object = action;
3939 		ctx->objmask = NULL;
3940 	}
3941 	memset(data, 0, data_size);
3942 	out->args.vc.data = data;
3943 	ctx->objdata = data_size;
3944 	return len;
3945 }
3946 
3947 /** Parse pattern item parameter type. */
3948 static int
3949 parse_vc_spec(struct context *ctx, const struct token *token,
3950 	      const char *str, unsigned int len,
3951 	      void *buf, unsigned int size)
3952 {
3953 	struct buffer *out = buf;
3954 	struct rte_flow_item *item;
3955 	uint32_t data_size;
3956 	int index;
3957 	int objmask = 0;
3958 
3959 	(void)size;
3960 	/* Token name must match. */
3961 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
3962 		return -1;
3963 	/* Parse parameter types. */
3964 	switch (ctx->curr) {
3965 		static const enum index prefix[] = NEXT_ENTRY(PREFIX);
3966 
3967 	case ITEM_PARAM_IS:
3968 		index = 0;
3969 		objmask = 1;
3970 		break;
3971 	case ITEM_PARAM_SPEC:
3972 		index = 0;
3973 		break;
3974 	case ITEM_PARAM_LAST:
3975 		index = 1;
3976 		break;
3977 	case ITEM_PARAM_PREFIX:
3978 		/* Modify next token to expect a prefix. */
3979 		if (ctx->next_num < 2)
3980 			return -1;
3981 		ctx->next[ctx->next_num - 2] = prefix;
3982 		/* Fall through. */
3983 	case ITEM_PARAM_MASK:
3984 		index = 2;
3985 		break;
3986 	default:
3987 		return -1;
3988 	}
3989 	/* Nothing else to do if there is no buffer. */
3990 	if (!out)
3991 		return len;
3992 	if (!out->args.vc.pattern_n)
3993 		return -1;
3994 	item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
3995 	data_size = ctx->objdata / 3; /* spec, last, mask */
3996 	/* Point to selected object. */
3997 	ctx->object = out->args.vc.data + (data_size * index);
3998 	if (objmask) {
3999 		ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */
4000 		item->mask = ctx->objmask;
4001 	} else
4002 		ctx->objmask = NULL;
4003 	/* Update relevant item pointer. */
4004 	*((const void **[]){ &item->spec, &item->last, &item->mask })[index] =
4005 		ctx->object;
4006 	return len;
4007 }
4008 
4009 /** Parse action configuration field. */
4010 static int
4011 parse_vc_conf(struct context *ctx, const struct token *token,
4012 	      const char *str, unsigned int len,
4013 	      void *buf, unsigned int size)
4014 {
4015 	struct buffer *out = buf;
4016 
4017 	(void)size;
4018 	/* Token name must match. */
4019 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
4020 		return -1;
4021 	/* Nothing else to do if there is no buffer. */
4022 	if (!out)
4023 		return len;
4024 	/* Point to selected object. */
4025 	ctx->object = out->args.vc.data;
4026 	ctx->objmask = NULL;
4027 	return len;
4028 }
4029 
4030 /** Parse RSS action. */
4031 static int
4032 parse_vc_action_rss(struct context *ctx, const struct token *token,
4033 		    const char *str, unsigned int len,
4034 		    void *buf, unsigned int size)
4035 {
4036 	struct buffer *out = buf;
4037 	struct rte_flow_action *action;
4038 	struct action_rss_data *action_rss_data;
4039 	unsigned int i;
4040 	int ret;
4041 
4042 	ret = parse_vc(ctx, token, str, len, buf, size);
4043 	if (ret < 0)
4044 		return ret;
4045 	/* Nothing else to do if there is no buffer. */
4046 	if (!out)
4047 		return ret;
4048 	if (!out->args.vc.actions_n)
4049 		return -1;
4050 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4051 	/* Point to selected object. */
4052 	ctx->object = out->args.vc.data;
4053 	ctx->objmask = NULL;
4054 	/* Set up default configuration. */
4055 	action_rss_data = ctx->object;
4056 	*action_rss_data = (struct action_rss_data){
4057 		.conf = (struct rte_flow_action_rss){
4058 			.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
4059 			.level = 0,
4060 			.types = rss_hf,
4061 			.key_len = sizeof(action_rss_data->key),
4062 			.queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
4063 			.key = action_rss_data->key,
4064 			.queue = action_rss_data->queue,
4065 		},
4066 		.key = "testpmd's default RSS hash key, "
4067 			"override it for better balancing",
4068 		.queue = { 0 },
4069 	};
4070 	for (i = 0; i < action_rss_data->conf.queue_num; ++i)
4071 		action_rss_data->queue[i] = i;
4072 	if (!port_id_is_invalid(ctx->port, DISABLED_WARN) &&
4073 	    ctx->port != (portid_t)RTE_PORT_ALL) {
4074 		struct rte_eth_dev_info info;
4075 		int ret2;
4076 
4077 		ret2 = rte_eth_dev_info_get(ctx->port, &info);
4078 		if (ret2 != 0)
4079 			return ret2;
4080 
4081 		action_rss_data->conf.key_len =
4082 			RTE_MIN(sizeof(action_rss_data->key),
4083 				info.hash_key_size);
4084 	}
4085 	action->conf = &action_rss_data->conf;
4086 	return ret;
4087 }
4088 
4089 /**
4090  * Parse func field for RSS action.
4091  *
4092  * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the
4093  * ACTION_RSS_FUNC_* index that called this function.
4094  */
4095 static int
4096 parse_vc_action_rss_func(struct context *ctx, const struct token *token,
4097 			 const char *str, unsigned int len,
4098 			 void *buf, unsigned int size)
4099 {
4100 	struct action_rss_data *action_rss_data;
4101 	enum rte_eth_hash_function func;
4102 
4103 	(void)buf;
4104 	(void)size;
4105 	/* Token name must match. */
4106 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
4107 		return -1;
4108 	switch (ctx->curr) {
4109 	case ACTION_RSS_FUNC_DEFAULT:
4110 		func = RTE_ETH_HASH_FUNCTION_DEFAULT;
4111 		break;
4112 	case ACTION_RSS_FUNC_TOEPLITZ:
4113 		func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
4114 		break;
4115 	case ACTION_RSS_FUNC_SIMPLE_XOR:
4116 		func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
4117 		break;
4118 	case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ:
4119 		func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ;
4120 		break;
4121 	default:
4122 		return -1;
4123 	}
4124 	if (!ctx->object)
4125 		return len;
4126 	action_rss_data = ctx->object;
4127 	action_rss_data->conf.func = func;
4128 	return len;
4129 }
4130 
4131 /**
4132  * Parse type field for RSS action.
4133  *
4134  * Valid tokens are type field names and the "end" token.
4135  */
4136 static int
4137 parse_vc_action_rss_type(struct context *ctx, const struct token *token,
4138 			  const char *str, unsigned int len,
4139 			  void *buf, unsigned int size)
4140 {
4141 	static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE);
4142 	struct action_rss_data *action_rss_data;
4143 	unsigned int i;
4144 
4145 	(void)token;
4146 	(void)buf;
4147 	(void)size;
4148 	if (ctx->curr != ACTION_RSS_TYPE)
4149 		return -1;
4150 	if (!(ctx->objdata >> 16) && ctx->object) {
4151 		action_rss_data = ctx->object;
4152 		action_rss_data->conf.types = 0;
4153 	}
4154 	if (!strcmp_partial("end", str, len)) {
4155 		ctx->objdata &= 0xffff;
4156 		return len;
4157 	}
4158 	for (i = 0; rss_type_table[i].str; ++i)
4159 		if (!strcmp_partial(rss_type_table[i].str, str, len))
4160 			break;
4161 	if (!rss_type_table[i].str)
4162 		return -1;
4163 	ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff);
4164 	/* Repeat token. */
4165 	if (ctx->next_num == RTE_DIM(ctx->next))
4166 		return -1;
4167 	ctx->next[ctx->next_num++] = next;
4168 	if (!ctx->object)
4169 		return len;
4170 	action_rss_data = ctx->object;
4171 	action_rss_data->conf.types |= rss_type_table[i].rss_type;
4172 	return len;
4173 }
4174 
4175 /**
4176  * Parse queue field for RSS action.
4177  *
4178  * Valid tokens are queue indices and the "end" token.
4179  */
4180 static int
4181 parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
4182 			  const char *str, unsigned int len,
4183 			  void *buf, unsigned int size)
4184 {
4185 	static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE);
4186 	struct action_rss_data *action_rss_data;
4187 	const struct arg *arg;
4188 	int ret;
4189 	int i;
4190 
4191 	(void)token;
4192 	(void)buf;
4193 	(void)size;
4194 	if (ctx->curr != ACTION_RSS_QUEUE)
4195 		return -1;
4196 	i = ctx->objdata >> 16;
4197 	if (!strcmp_partial("end", str, len)) {
4198 		ctx->objdata &= 0xffff;
4199 		goto end;
4200 	}
4201 	if (i >= ACTION_RSS_QUEUE_NUM)
4202 		return -1;
4203 	arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) +
4204 			     i * sizeof(action_rss_data->queue[i]),
4205 			     sizeof(action_rss_data->queue[i]));
4206 	if (push_args(ctx, arg))
4207 		return -1;
4208 	ret = parse_int(ctx, token, str, len, NULL, 0);
4209 	if (ret < 0) {
4210 		pop_args(ctx);
4211 		return -1;
4212 	}
4213 	++i;
4214 	ctx->objdata = i << 16 | (ctx->objdata & 0xffff);
4215 	/* Repeat token. */
4216 	if (ctx->next_num == RTE_DIM(ctx->next))
4217 		return -1;
4218 	ctx->next[ctx->next_num++] = next;
4219 end:
4220 	if (!ctx->object)
4221 		return len;
4222 	action_rss_data = ctx->object;
4223 	action_rss_data->conf.queue_num = i;
4224 	action_rss_data->conf.queue = i ? action_rss_data->queue : NULL;
4225 	return len;
4226 }
4227 
4228 /** Parse VXLAN encap action. */
4229 static int
4230 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token,
4231 			    const char *str, unsigned int len,
4232 			    void *buf, unsigned int size)
4233 {
4234 	struct buffer *out = buf;
4235 	struct rte_flow_action *action;
4236 	struct action_vxlan_encap_data *action_vxlan_encap_data;
4237 	int ret;
4238 
4239 	ret = parse_vc(ctx, token, str, len, buf, size);
4240 	if (ret < 0)
4241 		return ret;
4242 	/* Nothing else to do if there is no buffer. */
4243 	if (!out)
4244 		return ret;
4245 	if (!out->args.vc.actions_n)
4246 		return -1;
4247 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4248 	/* Point to selected object. */
4249 	ctx->object = out->args.vc.data;
4250 	ctx->objmask = NULL;
4251 	/* Set up default configuration. */
4252 	action_vxlan_encap_data = ctx->object;
4253 	*action_vxlan_encap_data = (struct action_vxlan_encap_data){
4254 		.conf = (struct rte_flow_action_vxlan_encap){
4255 			.definition = action_vxlan_encap_data->items,
4256 		},
4257 		.items = {
4258 			{
4259 				.type = RTE_FLOW_ITEM_TYPE_ETH,
4260 				.spec = &action_vxlan_encap_data->item_eth,
4261 				.mask = &rte_flow_item_eth_mask,
4262 			},
4263 			{
4264 				.type = RTE_FLOW_ITEM_TYPE_VLAN,
4265 				.spec = &action_vxlan_encap_data->item_vlan,
4266 				.mask = &rte_flow_item_vlan_mask,
4267 			},
4268 			{
4269 				.type = RTE_FLOW_ITEM_TYPE_IPV4,
4270 				.spec = &action_vxlan_encap_data->item_ipv4,
4271 				.mask = &rte_flow_item_ipv4_mask,
4272 			},
4273 			{
4274 				.type = RTE_FLOW_ITEM_TYPE_UDP,
4275 				.spec = &action_vxlan_encap_data->item_udp,
4276 				.mask = &rte_flow_item_udp_mask,
4277 			},
4278 			{
4279 				.type = RTE_FLOW_ITEM_TYPE_VXLAN,
4280 				.spec = &action_vxlan_encap_data->item_vxlan,
4281 				.mask = &rte_flow_item_vxlan_mask,
4282 			},
4283 			{
4284 				.type = RTE_FLOW_ITEM_TYPE_END,
4285 			},
4286 		},
4287 		.item_eth.type = 0,
4288 		.item_vlan = {
4289 			.tci = vxlan_encap_conf.vlan_tci,
4290 			.inner_type = 0,
4291 		},
4292 		.item_ipv4.hdr = {
4293 			.src_addr = vxlan_encap_conf.ipv4_src,
4294 			.dst_addr = vxlan_encap_conf.ipv4_dst,
4295 		},
4296 		.item_udp.hdr = {
4297 			.src_port = vxlan_encap_conf.udp_src,
4298 			.dst_port = vxlan_encap_conf.udp_dst,
4299 		},
4300 		.item_vxlan.flags = 0,
4301 	};
4302 	memcpy(action_vxlan_encap_data->item_eth.dst.addr_bytes,
4303 	       vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4304 	memcpy(action_vxlan_encap_data->item_eth.src.addr_bytes,
4305 	       vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4306 	if (!vxlan_encap_conf.select_ipv4) {
4307 		memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr,
4308 		       &vxlan_encap_conf.ipv6_src,
4309 		       sizeof(vxlan_encap_conf.ipv6_src));
4310 		memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr,
4311 		       &vxlan_encap_conf.ipv6_dst,
4312 		       sizeof(vxlan_encap_conf.ipv6_dst));
4313 		action_vxlan_encap_data->items[2] = (struct rte_flow_item){
4314 			.type = RTE_FLOW_ITEM_TYPE_IPV6,
4315 			.spec = &action_vxlan_encap_data->item_ipv6,
4316 			.mask = &rte_flow_item_ipv6_mask,
4317 		};
4318 	}
4319 	if (!vxlan_encap_conf.select_vlan)
4320 		action_vxlan_encap_data->items[1].type =
4321 			RTE_FLOW_ITEM_TYPE_VOID;
4322 	if (vxlan_encap_conf.select_tos_ttl) {
4323 		if (vxlan_encap_conf.select_ipv4) {
4324 			static struct rte_flow_item_ipv4 ipv4_mask_tos;
4325 
4326 			memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask,
4327 			       sizeof(ipv4_mask_tos));
4328 			ipv4_mask_tos.hdr.type_of_service = 0xff;
4329 			ipv4_mask_tos.hdr.time_to_live = 0xff;
4330 			action_vxlan_encap_data->item_ipv4.hdr.type_of_service =
4331 					vxlan_encap_conf.ip_tos;
4332 			action_vxlan_encap_data->item_ipv4.hdr.time_to_live =
4333 					vxlan_encap_conf.ip_ttl;
4334 			action_vxlan_encap_data->items[2].mask =
4335 							&ipv4_mask_tos;
4336 		} else {
4337 			static struct rte_flow_item_ipv6 ipv6_mask_tos;
4338 
4339 			memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask,
4340 			       sizeof(ipv6_mask_tos));
4341 			ipv6_mask_tos.hdr.vtc_flow |=
4342 				RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT);
4343 			ipv6_mask_tos.hdr.hop_limits = 0xff;
4344 			action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |=
4345 				rte_cpu_to_be_32
4346 					((uint32_t)vxlan_encap_conf.ip_tos <<
4347 					 RTE_IPV6_HDR_TC_SHIFT);
4348 			action_vxlan_encap_data->item_ipv6.hdr.hop_limits =
4349 					vxlan_encap_conf.ip_ttl;
4350 			action_vxlan_encap_data->items[2].mask =
4351 							&ipv6_mask_tos;
4352 		}
4353 	}
4354 	memcpy(action_vxlan_encap_data->item_vxlan.vni, vxlan_encap_conf.vni,
4355 	       RTE_DIM(vxlan_encap_conf.vni));
4356 	action->conf = &action_vxlan_encap_data->conf;
4357 	return ret;
4358 }
4359 
4360 /** Parse NVGRE encap action. */
4361 static int
4362 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token,
4363 			    const char *str, unsigned int len,
4364 			    void *buf, unsigned int size)
4365 {
4366 	struct buffer *out = buf;
4367 	struct rte_flow_action *action;
4368 	struct action_nvgre_encap_data *action_nvgre_encap_data;
4369 	int ret;
4370 
4371 	ret = parse_vc(ctx, token, str, len, buf, size);
4372 	if (ret < 0)
4373 		return ret;
4374 	/* Nothing else to do if there is no buffer. */
4375 	if (!out)
4376 		return ret;
4377 	if (!out->args.vc.actions_n)
4378 		return -1;
4379 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4380 	/* Point to selected object. */
4381 	ctx->object = out->args.vc.data;
4382 	ctx->objmask = NULL;
4383 	/* Set up default configuration. */
4384 	action_nvgre_encap_data = ctx->object;
4385 	*action_nvgre_encap_data = (struct action_nvgre_encap_data){
4386 		.conf = (struct rte_flow_action_nvgre_encap){
4387 			.definition = action_nvgre_encap_data->items,
4388 		},
4389 		.items = {
4390 			{
4391 				.type = RTE_FLOW_ITEM_TYPE_ETH,
4392 				.spec = &action_nvgre_encap_data->item_eth,
4393 				.mask = &rte_flow_item_eth_mask,
4394 			},
4395 			{
4396 				.type = RTE_FLOW_ITEM_TYPE_VLAN,
4397 				.spec = &action_nvgre_encap_data->item_vlan,
4398 				.mask = &rte_flow_item_vlan_mask,
4399 			},
4400 			{
4401 				.type = RTE_FLOW_ITEM_TYPE_IPV4,
4402 				.spec = &action_nvgre_encap_data->item_ipv4,
4403 				.mask = &rte_flow_item_ipv4_mask,
4404 			},
4405 			{
4406 				.type = RTE_FLOW_ITEM_TYPE_NVGRE,
4407 				.spec = &action_nvgre_encap_data->item_nvgre,
4408 				.mask = &rte_flow_item_nvgre_mask,
4409 			},
4410 			{
4411 				.type = RTE_FLOW_ITEM_TYPE_END,
4412 			},
4413 		},
4414 		.item_eth.type = 0,
4415 		.item_vlan = {
4416 			.tci = nvgre_encap_conf.vlan_tci,
4417 			.inner_type = 0,
4418 		},
4419 		.item_ipv4.hdr = {
4420 		       .src_addr = nvgre_encap_conf.ipv4_src,
4421 		       .dst_addr = nvgre_encap_conf.ipv4_dst,
4422 		},
4423 		.item_nvgre.flow_id = 0,
4424 	};
4425 	memcpy(action_nvgre_encap_data->item_eth.dst.addr_bytes,
4426 	       nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4427 	memcpy(action_nvgre_encap_data->item_eth.src.addr_bytes,
4428 	       nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4429 	if (!nvgre_encap_conf.select_ipv4) {
4430 		memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr,
4431 		       &nvgre_encap_conf.ipv6_src,
4432 		       sizeof(nvgre_encap_conf.ipv6_src));
4433 		memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr,
4434 		       &nvgre_encap_conf.ipv6_dst,
4435 		       sizeof(nvgre_encap_conf.ipv6_dst));
4436 		action_nvgre_encap_data->items[2] = (struct rte_flow_item){
4437 			.type = RTE_FLOW_ITEM_TYPE_IPV6,
4438 			.spec = &action_nvgre_encap_data->item_ipv6,
4439 			.mask = &rte_flow_item_ipv6_mask,
4440 		};
4441 	}
4442 	if (!nvgre_encap_conf.select_vlan)
4443 		action_nvgre_encap_data->items[1].type =
4444 			RTE_FLOW_ITEM_TYPE_VOID;
4445 	memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni,
4446 	       RTE_DIM(nvgre_encap_conf.tni));
4447 	action->conf = &action_nvgre_encap_data->conf;
4448 	return ret;
4449 }
4450 
4451 /** Parse l2 encap action. */
4452 static int
4453 parse_vc_action_l2_encap(struct context *ctx, const struct token *token,
4454 			 const char *str, unsigned int len,
4455 			 void *buf, unsigned int size)
4456 {
4457 	struct buffer *out = buf;
4458 	struct rte_flow_action *action;
4459 	struct action_raw_encap_data *action_encap_data;
4460 	struct rte_flow_item_eth eth = { .type = 0, };
4461 	struct rte_flow_item_vlan vlan = {
4462 		.tci = mplsoudp_encap_conf.vlan_tci,
4463 		.inner_type = 0,
4464 	};
4465 	uint8_t *header;
4466 	int ret;
4467 
4468 	ret = parse_vc(ctx, token, str, len, buf, size);
4469 	if (ret < 0)
4470 		return ret;
4471 	/* Nothing else to do if there is no buffer. */
4472 	if (!out)
4473 		return ret;
4474 	if (!out->args.vc.actions_n)
4475 		return -1;
4476 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4477 	/* Point to selected object. */
4478 	ctx->object = out->args.vc.data;
4479 	ctx->objmask = NULL;
4480 	/* Copy the headers to the buffer. */
4481 	action_encap_data = ctx->object;
4482 	*action_encap_data = (struct action_raw_encap_data) {
4483 		.conf = (struct rte_flow_action_raw_encap){
4484 			.data = action_encap_data->data,
4485 		},
4486 		.data = {},
4487 	};
4488 	header = action_encap_data->data;
4489 	if (l2_encap_conf.select_vlan)
4490 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4491 	else if (l2_encap_conf.select_ipv4)
4492 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4493 	else
4494 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4495 	memcpy(eth.dst.addr_bytes,
4496 	       l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4497 	memcpy(eth.src.addr_bytes,
4498 	       l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4499 	memcpy(header, &eth, sizeof(eth));
4500 	header += sizeof(eth);
4501 	if (l2_encap_conf.select_vlan) {
4502 		if (l2_encap_conf.select_ipv4)
4503 			vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4504 		else
4505 			vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4506 		memcpy(header, &vlan, sizeof(vlan));
4507 		header += sizeof(vlan);
4508 	}
4509 	action_encap_data->conf.size = header -
4510 		action_encap_data->data;
4511 	action->conf = &action_encap_data->conf;
4512 	return ret;
4513 }
4514 
4515 /** Parse l2 decap action. */
4516 static int
4517 parse_vc_action_l2_decap(struct context *ctx, const struct token *token,
4518 			 const char *str, unsigned int len,
4519 			 void *buf, unsigned int size)
4520 {
4521 	struct buffer *out = buf;
4522 	struct rte_flow_action *action;
4523 	struct action_raw_decap_data *action_decap_data;
4524 	struct rte_flow_item_eth eth = { .type = 0, };
4525 	struct rte_flow_item_vlan vlan = {
4526 		.tci = mplsoudp_encap_conf.vlan_tci,
4527 		.inner_type = 0,
4528 	};
4529 	uint8_t *header;
4530 	int ret;
4531 
4532 	ret = parse_vc(ctx, token, str, len, buf, size);
4533 	if (ret < 0)
4534 		return ret;
4535 	/* Nothing else to do if there is no buffer. */
4536 	if (!out)
4537 		return ret;
4538 	if (!out->args.vc.actions_n)
4539 		return -1;
4540 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4541 	/* Point to selected object. */
4542 	ctx->object = out->args.vc.data;
4543 	ctx->objmask = NULL;
4544 	/* Copy the headers to the buffer. */
4545 	action_decap_data = ctx->object;
4546 	*action_decap_data = (struct action_raw_decap_data) {
4547 		.conf = (struct rte_flow_action_raw_decap){
4548 			.data = action_decap_data->data,
4549 		},
4550 		.data = {},
4551 	};
4552 	header = action_decap_data->data;
4553 	if (l2_decap_conf.select_vlan)
4554 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4555 	memcpy(header, &eth, sizeof(eth));
4556 	header += sizeof(eth);
4557 	if (l2_decap_conf.select_vlan) {
4558 		memcpy(header, &vlan, sizeof(vlan));
4559 		header += sizeof(vlan);
4560 	}
4561 	action_decap_data->conf.size = header -
4562 		action_decap_data->data;
4563 	action->conf = &action_decap_data->conf;
4564 	return ret;
4565 }
4566 
4567 #define ETHER_TYPE_MPLS_UNICAST 0x8847
4568 
4569 /** Parse MPLSOGRE encap action. */
4570 static int
4571 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token,
4572 			       const char *str, unsigned int len,
4573 			       void *buf, unsigned int size)
4574 {
4575 	struct buffer *out = buf;
4576 	struct rte_flow_action *action;
4577 	struct action_raw_encap_data *action_encap_data;
4578 	struct rte_flow_item_eth eth = { .type = 0, };
4579 	struct rte_flow_item_vlan vlan = {
4580 		.tci = mplsogre_encap_conf.vlan_tci,
4581 		.inner_type = 0,
4582 	};
4583 	struct rte_flow_item_ipv4 ipv4 = {
4584 		.hdr =  {
4585 			.src_addr = mplsogre_encap_conf.ipv4_src,
4586 			.dst_addr = mplsogre_encap_conf.ipv4_dst,
4587 			.next_proto_id = IPPROTO_GRE,
4588 			.version_ihl = RTE_IPV4_VHL_DEF,
4589 			.time_to_live = IPDEFTTL,
4590 		},
4591 	};
4592 	struct rte_flow_item_ipv6 ipv6 = {
4593 		.hdr =  {
4594 			.proto = IPPROTO_GRE,
4595 			.hop_limits = IPDEFTTL,
4596 		},
4597 	};
4598 	struct rte_flow_item_gre gre = {
4599 		.protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST),
4600 	};
4601 	struct rte_flow_item_mpls mpls = {
4602 		.ttl = 0,
4603 	};
4604 	uint8_t *header;
4605 	int ret;
4606 
4607 	ret = parse_vc(ctx, token, str, len, buf, size);
4608 	if (ret < 0)
4609 		return ret;
4610 	/* Nothing else to do if there is no buffer. */
4611 	if (!out)
4612 		return ret;
4613 	if (!out->args.vc.actions_n)
4614 		return -1;
4615 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4616 	/* Point to selected object. */
4617 	ctx->object = out->args.vc.data;
4618 	ctx->objmask = NULL;
4619 	/* Copy the headers to the buffer. */
4620 	action_encap_data = ctx->object;
4621 	*action_encap_data = (struct action_raw_encap_data) {
4622 		.conf = (struct rte_flow_action_raw_encap){
4623 			.data = action_encap_data->data,
4624 		},
4625 		.data = {},
4626 		.preserve = {},
4627 	};
4628 	header = action_encap_data->data;
4629 	if (mplsogre_encap_conf.select_vlan)
4630 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4631 	else if (mplsogre_encap_conf.select_ipv4)
4632 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4633 	else
4634 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4635 	memcpy(eth.dst.addr_bytes,
4636 	       mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4637 	memcpy(eth.src.addr_bytes,
4638 	       mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4639 	memcpy(header, &eth, sizeof(eth));
4640 	header += sizeof(eth);
4641 	if (mplsogre_encap_conf.select_vlan) {
4642 		if (mplsogre_encap_conf.select_ipv4)
4643 			vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4644 		else
4645 			vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4646 		memcpy(header, &vlan, sizeof(vlan));
4647 		header += sizeof(vlan);
4648 	}
4649 	if (mplsogre_encap_conf.select_ipv4) {
4650 		memcpy(header, &ipv4, sizeof(ipv4));
4651 		header += sizeof(ipv4);
4652 	} else {
4653 		memcpy(&ipv6.hdr.src_addr,
4654 		       &mplsogre_encap_conf.ipv6_src,
4655 		       sizeof(mplsogre_encap_conf.ipv6_src));
4656 		memcpy(&ipv6.hdr.dst_addr,
4657 		       &mplsogre_encap_conf.ipv6_dst,
4658 		       sizeof(mplsogre_encap_conf.ipv6_dst));
4659 		memcpy(header, &ipv6, sizeof(ipv6));
4660 		header += sizeof(ipv6);
4661 	}
4662 	memcpy(header, &gre, sizeof(gre));
4663 	header += sizeof(gre);
4664 	memcpy(mpls.label_tc_s, mplsogre_encap_conf.label,
4665 	       RTE_DIM(mplsogre_encap_conf.label));
4666 	mpls.label_tc_s[2] |= 0x1;
4667 	memcpy(header, &mpls, sizeof(mpls));
4668 	header += sizeof(mpls);
4669 	action_encap_data->conf.size = header -
4670 		action_encap_data->data;
4671 	action->conf = &action_encap_data->conf;
4672 	return ret;
4673 }
4674 
4675 /** Parse MPLSOGRE decap action. */
4676 static int
4677 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token,
4678 			       const char *str, unsigned int len,
4679 			       void *buf, unsigned int size)
4680 {
4681 	struct buffer *out = buf;
4682 	struct rte_flow_action *action;
4683 	struct action_raw_decap_data *action_decap_data;
4684 	struct rte_flow_item_eth eth = { .type = 0, };
4685 	struct rte_flow_item_vlan vlan = {.tci = 0};
4686 	struct rte_flow_item_ipv4 ipv4 = {
4687 		.hdr =  {
4688 			.next_proto_id = IPPROTO_GRE,
4689 		},
4690 	};
4691 	struct rte_flow_item_ipv6 ipv6 = {
4692 		.hdr =  {
4693 			.proto = IPPROTO_GRE,
4694 		},
4695 	};
4696 	struct rte_flow_item_gre gre = {
4697 		.protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST),
4698 	};
4699 	struct rte_flow_item_mpls mpls;
4700 	uint8_t *header;
4701 	int ret;
4702 
4703 	ret = parse_vc(ctx, token, str, len, buf, size);
4704 	if (ret < 0)
4705 		return ret;
4706 	/* Nothing else to do if there is no buffer. */
4707 	if (!out)
4708 		return ret;
4709 	if (!out->args.vc.actions_n)
4710 		return -1;
4711 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4712 	/* Point to selected object. */
4713 	ctx->object = out->args.vc.data;
4714 	ctx->objmask = NULL;
4715 	/* Copy the headers to the buffer. */
4716 	action_decap_data = ctx->object;
4717 	*action_decap_data = (struct action_raw_decap_data) {
4718 		.conf = (struct rte_flow_action_raw_decap){
4719 			.data = action_decap_data->data,
4720 		},
4721 		.data = {},
4722 	};
4723 	header = action_decap_data->data;
4724 	if (mplsogre_decap_conf.select_vlan)
4725 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4726 	else if (mplsogre_encap_conf.select_ipv4)
4727 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4728 	else
4729 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4730 	memcpy(eth.dst.addr_bytes,
4731 	       mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4732 	memcpy(eth.src.addr_bytes,
4733 	       mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4734 	memcpy(header, &eth, sizeof(eth));
4735 	header += sizeof(eth);
4736 	if (mplsogre_encap_conf.select_vlan) {
4737 		if (mplsogre_encap_conf.select_ipv4)
4738 			vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4739 		else
4740 			vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4741 		memcpy(header, &vlan, sizeof(vlan));
4742 		header += sizeof(vlan);
4743 	}
4744 	if (mplsogre_encap_conf.select_ipv4) {
4745 		memcpy(header, &ipv4, sizeof(ipv4));
4746 		header += sizeof(ipv4);
4747 	} else {
4748 		memcpy(header, &ipv6, sizeof(ipv6));
4749 		header += sizeof(ipv6);
4750 	}
4751 	memcpy(header, &gre, sizeof(gre));
4752 	header += sizeof(gre);
4753 	memset(&mpls, 0, sizeof(mpls));
4754 	memcpy(header, &mpls, sizeof(mpls));
4755 	header += sizeof(mpls);
4756 	action_decap_data->conf.size = header -
4757 		action_decap_data->data;
4758 	action->conf = &action_decap_data->conf;
4759 	return ret;
4760 }
4761 
4762 /** Parse MPLSOUDP encap action. */
4763 static int
4764 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token,
4765 			       const char *str, unsigned int len,
4766 			       void *buf, unsigned int size)
4767 {
4768 	struct buffer *out = buf;
4769 	struct rte_flow_action *action;
4770 	struct action_raw_encap_data *action_encap_data;
4771 	struct rte_flow_item_eth eth = { .type = 0, };
4772 	struct rte_flow_item_vlan vlan = {
4773 		.tci = mplsoudp_encap_conf.vlan_tci,
4774 		.inner_type = 0,
4775 	};
4776 	struct rte_flow_item_ipv4 ipv4 = {
4777 		.hdr =  {
4778 			.src_addr = mplsoudp_encap_conf.ipv4_src,
4779 			.dst_addr = mplsoudp_encap_conf.ipv4_dst,
4780 			.next_proto_id = IPPROTO_UDP,
4781 			.version_ihl = RTE_IPV4_VHL_DEF,
4782 			.time_to_live = IPDEFTTL,
4783 		},
4784 	};
4785 	struct rte_flow_item_ipv6 ipv6 = {
4786 		.hdr =  {
4787 			.proto = IPPROTO_UDP,
4788 			.hop_limits = IPDEFTTL,
4789 		},
4790 	};
4791 	struct rte_flow_item_udp udp = {
4792 		.hdr = {
4793 			.src_port = mplsoudp_encap_conf.udp_src,
4794 			.dst_port = mplsoudp_encap_conf.udp_dst,
4795 		},
4796 	};
4797 	struct rte_flow_item_mpls mpls;
4798 	uint8_t *header;
4799 	int ret;
4800 
4801 	ret = parse_vc(ctx, token, str, len, buf, size);
4802 	if (ret < 0)
4803 		return ret;
4804 	/* Nothing else to do if there is no buffer. */
4805 	if (!out)
4806 		return ret;
4807 	if (!out->args.vc.actions_n)
4808 		return -1;
4809 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4810 	/* Point to selected object. */
4811 	ctx->object = out->args.vc.data;
4812 	ctx->objmask = NULL;
4813 	/* Copy the headers to the buffer. */
4814 	action_encap_data = ctx->object;
4815 	*action_encap_data = (struct action_raw_encap_data) {
4816 		.conf = (struct rte_flow_action_raw_encap){
4817 			.data = action_encap_data->data,
4818 		},
4819 		.data = {},
4820 		.preserve = {},
4821 	};
4822 	header = action_encap_data->data;
4823 	if (mplsoudp_encap_conf.select_vlan)
4824 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4825 	else if (mplsoudp_encap_conf.select_ipv4)
4826 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4827 	else
4828 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4829 	memcpy(eth.dst.addr_bytes,
4830 	       mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4831 	memcpy(eth.src.addr_bytes,
4832 	       mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4833 	memcpy(header, &eth, sizeof(eth));
4834 	header += sizeof(eth);
4835 	if (mplsoudp_encap_conf.select_vlan) {
4836 		if (mplsoudp_encap_conf.select_ipv4)
4837 			vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4838 		else
4839 			vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4840 		memcpy(header, &vlan, sizeof(vlan));
4841 		header += sizeof(vlan);
4842 	}
4843 	if (mplsoudp_encap_conf.select_ipv4) {
4844 		memcpy(header, &ipv4, sizeof(ipv4));
4845 		header += sizeof(ipv4);
4846 	} else {
4847 		memcpy(&ipv6.hdr.src_addr,
4848 		       &mplsoudp_encap_conf.ipv6_src,
4849 		       sizeof(mplsoudp_encap_conf.ipv6_src));
4850 		memcpy(&ipv6.hdr.dst_addr,
4851 		       &mplsoudp_encap_conf.ipv6_dst,
4852 		       sizeof(mplsoudp_encap_conf.ipv6_dst));
4853 		memcpy(header, &ipv6, sizeof(ipv6));
4854 		header += sizeof(ipv6);
4855 	}
4856 	memcpy(header, &udp, sizeof(udp));
4857 	header += sizeof(udp);
4858 	memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label,
4859 	       RTE_DIM(mplsoudp_encap_conf.label));
4860 	mpls.label_tc_s[2] |= 0x1;
4861 	memcpy(header, &mpls, sizeof(mpls));
4862 	header += sizeof(mpls);
4863 	action_encap_data->conf.size = header -
4864 		action_encap_data->data;
4865 	action->conf = &action_encap_data->conf;
4866 	return ret;
4867 }
4868 
4869 /** Parse MPLSOUDP decap action. */
4870 static int
4871 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token,
4872 			       const char *str, unsigned int len,
4873 			       void *buf, unsigned int size)
4874 {
4875 	struct buffer *out = buf;
4876 	struct rte_flow_action *action;
4877 	struct action_raw_decap_data *action_decap_data;
4878 	struct rte_flow_item_eth eth = { .type = 0, };
4879 	struct rte_flow_item_vlan vlan = {.tci = 0};
4880 	struct rte_flow_item_ipv4 ipv4 = {
4881 		.hdr =  {
4882 			.next_proto_id = IPPROTO_UDP,
4883 		},
4884 	};
4885 	struct rte_flow_item_ipv6 ipv6 = {
4886 		.hdr =  {
4887 			.proto = IPPROTO_UDP,
4888 		},
4889 	};
4890 	struct rte_flow_item_udp udp = {
4891 		.hdr = {
4892 			.dst_port = rte_cpu_to_be_16(6635),
4893 		},
4894 	};
4895 	struct rte_flow_item_mpls mpls;
4896 	uint8_t *header;
4897 	int ret;
4898 
4899 	ret = parse_vc(ctx, token, str, len, buf, size);
4900 	if (ret < 0)
4901 		return ret;
4902 	/* Nothing else to do if there is no buffer. */
4903 	if (!out)
4904 		return ret;
4905 	if (!out->args.vc.actions_n)
4906 		return -1;
4907 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4908 	/* Point to selected object. */
4909 	ctx->object = out->args.vc.data;
4910 	ctx->objmask = NULL;
4911 	/* Copy the headers to the buffer. */
4912 	action_decap_data = ctx->object;
4913 	*action_decap_data = (struct action_raw_decap_data) {
4914 		.conf = (struct rte_flow_action_raw_decap){
4915 			.data = action_decap_data->data,
4916 		},
4917 		.data = {},
4918 	};
4919 	header = action_decap_data->data;
4920 	if (mplsoudp_decap_conf.select_vlan)
4921 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4922 	else if (mplsoudp_encap_conf.select_ipv4)
4923 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4924 	else
4925 		eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4926 	memcpy(eth.dst.addr_bytes,
4927 	       mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
4928 	memcpy(eth.src.addr_bytes,
4929 	       mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
4930 	memcpy(header, &eth, sizeof(eth));
4931 	header += sizeof(eth);
4932 	if (mplsoudp_encap_conf.select_vlan) {
4933 		if (mplsoudp_encap_conf.select_ipv4)
4934 			vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
4935 		else
4936 			vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
4937 		memcpy(header, &vlan, sizeof(vlan));
4938 		header += sizeof(vlan);
4939 	}
4940 	if (mplsoudp_encap_conf.select_ipv4) {
4941 		memcpy(header, &ipv4, sizeof(ipv4));
4942 		header += sizeof(ipv4);
4943 	} else {
4944 		memcpy(header, &ipv6, sizeof(ipv6));
4945 		header += sizeof(ipv6);
4946 	}
4947 	memcpy(header, &udp, sizeof(udp));
4948 	header += sizeof(udp);
4949 	memset(&mpls, 0, sizeof(mpls));
4950 	memcpy(header, &mpls, sizeof(mpls));
4951 	header += sizeof(mpls);
4952 	action_decap_data->conf.size = header -
4953 		action_decap_data->data;
4954 	action->conf = &action_decap_data->conf;
4955 	return ret;
4956 }
4957 
4958 static int
4959 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token,
4960 				const char *str, unsigned int len, void *buf,
4961 				unsigned int size)
4962 {
4963 	struct action_raw_decap_data *action_raw_decap_data;
4964 	struct rte_flow_action *action;
4965 	const struct arg *arg;
4966 	struct buffer *out = buf;
4967 	int ret;
4968 	uint16_t idx;
4969 
4970 	RTE_SET_USED(token);
4971 	RTE_SET_USED(buf);
4972 	RTE_SET_USED(size);
4973 	arg = ARGS_ENTRY_ARB_BOUNDED
4974 		(offsetof(struct action_raw_decap_data, idx),
4975 		 sizeof(((struct action_raw_decap_data *)0)->idx),
4976 		 0, RAW_ENCAP_CONFS_MAX_NUM - 1);
4977 	if (push_args(ctx, arg))
4978 		return -1;
4979 	ret = parse_int(ctx, token, str, len, NULL, 0);
4980 	if (ret < 0) {
4981 		pop_args(ctx);
4982 		return -1;
4983 	}
4984 	if (!ctx->object)
4985 		return len;
4986 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
4987 	action_raw_decap_data = ctx->object;
4988 	idx = action_raw_decap_data->idx;
4989 	action_raw_decap_data->conf.data = raw_decap_confs[idx].data;
4990 	action_raw_decap_data->conf.size = raw_decap_confs[idx].size;
4991 	action->conf = &action_raw_decap_data->conf;
4992 	return len;
4993 }
4994 
4995 
4996 static int
4997 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token,
4998 				const char *str, unsigned int len, void *buf,
4999 				unsigned int size)
5000 {
5001 	struct action_raw_encap_data *action_raw_encap_data;
5002 	struct rte_flow_action *action;
5003 	const struct arg *arg;
5004 	struct buffer *out = buf;
5005 	int ret;
5006 	uint16_t idx;
5007 
5008 	RTE_SET_USED(token);
5009 	RTE_SET_USED(buf);
5010 	RTE_SET_USED(size);
5011 	if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE)
5012 		return -1;
5013 	arg = ARGS_ENTRY_ARB_BOUNDED
5014 		(offsetof(struct action_raw_encap_data, idx),
5015 		 sizeof(((struct action_raw_encap_data *)0)->idx),
5016 		 0, RAW_ENCAP_CONFS_MAX_NUM - 1);
5017 	if (push_args(ctx, arg))
5018 		return -1;
5019 	ret = parse_int(ctx, token, str, len, NULL, 0);
5020 	if (ret < 0) {
5021 		pop_args(ctx);
5022 		return -1;
5023 	}
5024 	if (!ctx->object)
5025 		return len;
5026 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
5027 	action_raw_encap_data = ctx->object;
5028 	idx = action_raw_encap_data->idx;
5029 	action_raw_encap_data->conf.data = raw_encap_confs[idx].data;
5030 	action_raw_encap_data->conf.size = raw_encap_confs[idx].size;
5031 	action_raw_encap_data->conf.preserve = NULL;
5032 	action->conf = &action_raw_encap_data->conf;
5033 	return len;
5034 }
5035 
5036 static int
5037 parse_vc_action_raw_encap(struct context *ctx, const struct token *token,
5038 			  const char *str, unsigned int len, void *buf,
5039 			  unsigned int size)
5040 {
5041 	struct buffer *out = buf;
5042 	struct rte_flow_action *action;
5043 	struct action_raw_encap_data *action_raw_encap_data = NULL;
5044 	int ret;
5045 
5046 	ret = parse_vc(ctx, token, str, len, buf, size);
5047 	if (ret < 0)
5048 		return ret;
5049 	/* Nothing else to do if there is no buffer. */
5050 	if (!out)
5051 		return ret;
5052 	if (!out->args.vc.actions_n)
5053 		return -1;
5054 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
5055 	/* Point to selected object. */
5056 	ctx->object = out->args.vc.data;
5057 	ctx->objmask = NULL;
5058 	/* Copy the headers to the buffer. */
5059 	action_raw_encap_data = ctx->object;
5060 	action_raw_encap_data->conf.data = raw_encap_confs[0].data;
5061 	action_raw_encap_data->conf.preserve = NULL;
5062 	action_raw_encap_data->conf.size = raw_encap_confs[0].size;
5063 	action->conf = &action_raw_encap_data->conf;
5064 	return ret;
5065 }
5066 
5067 static int
5068 parse_vc_action_raw_decap(struct context *ctx, const struct token *token,
5069 			  const char *str, unsigned int len, void *buf,
5070 			  unsigned int size)
5071 {
5072 	struct buffer *out = buf;
5073 	struct rte_flow_action *action;
5074 	struct action_raw_decap_data *action_raw_decap_data = NULL;
5075 	int ret;
5076 
5077 	ret = parse_vc(ctx, token, str, len, buf, size);
5078 	if (ret < 0)
5079 		return ret;
5080 	/* Nothing else to do if there is no buffer. */
5081 	if (!out)
5082 		return ret;
5083 	if (!out->args.vc.actions_n)
5084 		return -1;
5085 	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
5086 	/* Point to selected object. */
5087 	ctx->object = out->args.vc.data;
5088 	ctx->objmask = NULL;
5089 	/* Copy the headers to the buffer. */
5090 	action_raw_decap_data = ctx->object;
5091 	action_raw_decap_data->conf.data = raw_decap_confs[0].data;
5092 	action_raw_decap_data->conf.size = raw_decap_confs[0].size;
5093 	action->conf = &action_raw_decap_data->conf;
5094 	return ret;
5095 }
5096 
5097 static int
5098 parse_vc_action_set_meta(struct context *ctx, const struct token *token,
5099 			 const char *str, unsigned int len, void *buf,
5100 			 unsigned int size)
5101 {
5102 	int ret;
5103 
5104 	ret = parse_vc(ctx, token, str, len, buf, size);
5105 	if (ret < 0)
5106 		return ret;
5107 	ret = rte_flow_dynf_metadata_register();
5108 	if (ret < 0)
5109 		return -1;
5110 	return len;
5111 }
5112 
5113 /** Parse tokens for destroy command. */
5114 static int
5115 parse_destroy(struct context *ctx, const struct token *token,
5116 	      const char *str, unsigned int len,
5117 	      void *buf, unsigned int size)
5118 {
5119 	struct buffer *out = buf;
5120 
5121 	/* Token name must match. */
5122 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5123 		return -1;
5124 	/* Nothing else to do if there is no buffer. */
5125 	if (!out)
5126 		return len;
5127 	if (!out->command) {
5128 		if (ctx->curr != DESTROY)
5129 			return -1;
5130 		if (sizeof(*out) > size)
5131 			return -1;
5132 		out->command = ctx->curr;
5133 		ctx->objdata = 0;
5134 		ctx->object = out;
5135 		ctx->objmask = NULL;
5136 		out->args.destroy.rule =
5137 			(void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
5138 					       sizeof(double));
5139 		return len;
5140 	}
5141 	if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) +
5142 	     sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size)
5143 		return -1;
5144 	ctx->objdata = 0;
5145 	ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++;
5146 	ctx->objmask = NULL;
5147 	return len;
5148 }
5149 
5150 /** Parse tokens for flush command. */
5151 static int
5152 parse_flush(struct context *ctx, const struct token *token,
5153 	    const char *str, unsigned int len,
5154 	    void *buf, unsigned int size)
5155 {
5156 	struct buffer *out = buf;
5157 
5158 	/* Token name must match. */
5159 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5160 		return -1;
5161 	/* Nothing else to do if there is no buffer. */
5162 	if (!out)
5163 		return len;
5164 	if (!out->command) {
5165 		if (ctx->curr != FLUSH)
5166 			return -1;
5167 		if (sizeof(*out) > size)
5168 			return -1;
5169 		out->command = ctx->curr;
5170 		ctx->objdata = 0;
5171 		ctx->object = out;
5172 		ctx->objmask = NULL;
5173 	}
5174 	return len;
5175 }
5176 
5177 /** Parse tokens for dump command. */
5178 static int
5179 parse_dump(struct context *ctx, const struct token *token,
5180 	    const char *str, unsigned int len,
5181 	    void *buf, unsigned int size)
5182 {
5183 	struct buffer *out = buf;
5184 
5185 	/* Token name must match. */
5186 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5187 		return -1;
5188 	/* Nothing else to do if there is no buffer. */
5189 	if (!out)
5190 		return len;
5191 	if (!out->command) {
5192 		if (ctx->curr != DUMP)
5193 			return -1;
5194 		if (sizeof(*out) > size)
5195 			return -1;
5196 		out->command = ctx->curr;
5197 		ctx->objdata = 0;
5198 		ctx->object = out;
5199 		ctx->objmask = NULL;
5200 	}
5201 	return len;
5202 }
5203 
5204 /** Parse tokens for query command. */
5205 static int
5206 parse_query(struct context *ctx, const struct token *token,
5207 	    const char *str, unsigned int len,
5208 	    void *buf, unsigned int size)
5209 {
5210 	struct buffer *out = buf;
5211 
5212 	/* Token name must match. */
5213 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5214 		return -1;
5215 	/* Nothing else to do if there is no buffer. */
5216 	if (!out)
5217 		return len;
5218 	if (!out->command) {
5219 		if (ctx->curr != QUERY)
5220 			return -1;
5221 		if (sizeof(*out) > size)
5222 			return -1;
5223 		out->command = ctx->curr;
5224 		ctx->objdata = 0;
5225 		ctx->object = out;
5226 		ctx->objmask = NULL;
5227 	}
5228 	return len;
5229 }
5230 
5231 /** Parse action names. */
5232 static int
5233 parse_action(struct context *ctx, const struct token *token,
5234 	     const char *str, unsigned int len,
5235 	     void *buf, unsigned int size)
5236 {
5237 	struct buffer *out = buf;
5238 	const struct arg *arg = pop_args(ctx);
5239 	unsigned int i;
5240 
5241 	(void)size;
5242 	/* Argument is expected. */
5243 	if (!arg)
5244 		return -1;
5245 	/* Parse action name. */
5246 	for (i = 0; next_action[i]; ++i) {
5247 		const struct parse_action_priv *priv;
5248 
5249 		token = &token_list[next_action[i]];
5250 		if (strcmp_partial(token->name, str, len))
5251 			continue;
5252 		priv = token->priv;
5253 		if (!priv)
5254 			goto error;
5255 		if (out)
5256 			memcpy((uint8_t *)ctx->object + arg->offset,
5257 			       &priv->type,
5258 			       arg->size);
5259 		return len;
5260 	}
5261 error:
5262 	push_args(ctx, arg);
5263 	return -1;
5264 }
5265 
5266 /** Parse tokens for list command. */
5267 static int
5268 parse_list(struct context *ctx, const struct token *token,
5269 	   const char *str, unsigned int len,
5270 	   void *buf, unsigned int size)
5271 {
5272 	struct buffer *out = buf;
5273 
5274 	/* Token name must match. */
5275 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5276 		return -1;
5277 	/* Nothing else to do if there is no buffer. */
5278 	if (!out)
5279 		return len;
5280 	if (!out->command) {
5281 		if (ctx->curr != LIST)
5282 			return -1;
5283 		if (sizeof(*out) > size)
5284 			return -1;
5285 		out->command = ctx->curr;
5286 		ctx->objdata = 0;
5287 		ctx->object = out;
5288 		ctx->objmask = NULL;
5289 		out->args.list.group =
5290 			(void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
5291 					       sizeof(double));
5292 		return len;
5293 	}
5294 	if (((uint8_t *)(out->args.list.group + out->args.list.group_n) +
5295 	     sizeof(*out->args.list.group)) > (uint8_t *)out + size)
5296 		return -1;
5297 	ctx->objdata = 0;
5298 	ctx->object = out->args.list.group + out->args.list.group_n++;
5299 	ctx->objmask = NULL;
5300 	return len;
5301 }
5302 
5303 /** Parse tokens for isolate command. */
5304 static int
5305 parse_isolate(struct context *ctx, const struct token *token,
5306 	      const char *str, unsigned int len,
5307 	      void *buf, unsigned int size)
5308 {
5309 	struct buffer *out = buf;
5310 
5311 	/* Token name must match. */
5312 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5313 		return -1;
5314 	/* Nothing else to do if there is no buffer. */
5315 	if (!out)
5316 		return len;
5317 	if (!out->command) {
5318 		if (ctx->curr != ISOLATE)
5319 			return -1;
5320 		if (sizeof(*out) > size)
5321 			return -1;
5322 		out->command = ctx->curr;
5323 		ctx->objdata = 0;
5324 		ctx->object = out;
5325 		ctx->objmask = NULL;
5326 	}
5327 	return len;
5328 }
5329 
5330 /**
5331  * Parse signed/unsigned integers 8 to 64-bit long.
5332  *
5333  * Last argument (ctx->args) is retrieved to determine integer type and
5334  * storage location.
5335  */
5336 static int
5337 parse_int(struct context *ctx, const struct token *token,
5338 	  const char *str, unsigned int len,
5339 	  void *buf, unsigned int size)
5340 {
5341 	const struct arg *arg = pop_args(ctx);
5342 	uintmax_t u;
5343 	char *end;
5344 
5345 	(void)token;
5346 	/* Argument is expected. */
5347 	if (!arg)
5348 		return -1;
5349 	errno = 0;
5350 	u = arg->sign ?
5351 		(uintmax_t)strtoimax(str, &end, 0) :
5352 		strtoumax(str, &end, 0);
5353 	if (errno || (size_t)(end - str) != len)
5354 		goto error;
5355 	if (arg->bounded &&
5356 	    ((arg->sign && ((intmax_t)u < (intmax_t)arg->min ||
5357 			    (intmax_t)u > (intmax_t)arg->max)) ||
5358 	     (!arg->sign && (u < arg->min || u > arg->max))))
5359 		goto error;
5360 	if (!ctx->object)
5361 		return len;
5362 	if (arg->mask) {
5363 		if (!arg_entry_bf_fill(ctx->object, u, arg) ||
5364 		    !arg_entry_bf_fill(ctx->objmask, -1, arg))
5365 			goto error;
5366 		return len;
5367 	}
5368 	buf = (uint8_t *)ctx->object + arg->offset;
5369 	size = arg->size;
5370 	if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t))
5371 		return -1;
5372 objmask:
5373 	switch (size) {
5374 	case sizeof(uint8_t):
5375 		*(uint8_t *)buf = u;
5376 		break;
5377 	case sizeof(uint16_t):
5378 		*(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u;
5379 		break;
5380 	case sizeof(uint8_t [3]):
5381 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
5382 		if (!arg->hton) {
5383 			((uint8_t *)buf)[0] = u;
5384 			((uint8_t *)buf)[1] = u >> 8;
5385 			((uint8_t *)buf)[2] = u >> 16;
5386 			break;
5387 		}
5388 #endif
5389 		((uint8_t *)buf)[0] = u >> 16;
5390 		((uint8_t *)buf)[1] = u >> 8;
5391 		((uint8_t *)buf)[2] = u;
5392 		break;
5393 	case sizeof(uint32_t):
5394 		*(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u;
5395 		break;
5396 	case sizeof(uint64_t):
5397 		*(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u;
5398 		break;
5399 	default:
5400 		goto error;
5401 	}
5402 	if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) {
5403 		u = -1;
5404 		buf = (uint8_t *)ctx->objmask + arg->offset;
5405 		goto objmask;
5406 	}
5407 	return len;
5408 error:
5409 	push_args(ctx, arg);
5410 	return -1;
5411 }
5412 
5413 /**
5414  * Parse a string.
5415  *
5416  * Three arguments (ctx->args) are retrieved from the stack to store data,
5417  * its actual length and address (in that order).
5418  */
5419 static int
5420 parse_string(struct context *ctx, const struct token *token,
5421 	     const char *str, unsigned int len,
5422 	     void *buf, unsigned int size)
5423 {
5424 	const struct arg *arg_data = pop_args(ctx);
5425 	const struct arg *arg_len = pop_args(ctx);
5426 	const struct arg *arg_addr = pop_args(ctx);
5427 	char tmp[16]; /* Ought to be enough. */
5428 	int ret;
5429 
5430 	/* Arguments are expected. */
5431 	if (!arg_data)
5432 		return -1;
5433 	if (!arg_len) {
5434 		push_args(ctx, arg_data);
5435 		return -1;
5436 	}
5437 	if (!arg_addr) {
5438 		push_args(ctx, arg_len);
5439 		push_args(ctx, arg_data);
5440 		return -1;
5441 	}
5442 	size = arg_data->size;
5443 	/* Bit-mask fill is not supported. */
5444 	if (arg_data->mask || size < len)
5445 		goto error;
5446 	if (!ctx->object)
5447 		return len;
5448 	/* Let parse_int() fill length information first. */
5449 	ret = snprintf(tmp, sizeof(tmp), "%u", len);
5450 	if (ret < 0)
5451 		goto error;
5452 	push_args(ctx, arg_len);
5453 	ret = parse_int(ctx, token, tmp, ret, NULL, 0);
5454 	if (ret < 0) {
5455 		pop_args(ctx);
5456 		goto error;
5457 	}
5458 	buf = (uint8_t *)ctx->object + arg_data->offset;
5459 	/* Output buffer is not necessarily NUL-terminated. */
5460 	memcpy(buf, str, len);
5461 	memset((uint8_t *)buf + len, 0x00, size - len);
5462 	if (ctx->objmask)
5463 		memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len);
5464 	/* Save address if requested. */
5465 	if (arg_addr->size) {
5466 		memcpy((uint8_t *)ctx->object + arg_addr->offset,
5467 		       (void *[]){
5468 			(uint8_t *)ctx->object + arg_data->offset
5469 		       },
5470 		       arg_addr->size);
5471 		if (ctx->objmask)
5472 			memcpy((uint8_t *)ctx->objmask + arg_addr->offset,
5473 			       (void *[]){
5474 				(uint8_t *)ctx->objmask + arg_data->offset
5475 			       },
5476 			       arg_addr->size);
5477 	}
5478 	return len;
5479 error:
5480 	push_args(ctx, arg_addr);
5481 	push_args(ctx, arg_len);
5482 	push_args(ctx, arg_data);
5483 	return -1;
5484 }
5485 
5486 static int
5487 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size)
5488 {
5489 	char *c = NULL;
5490 	uint32_t i, len;
5491 	char tmp[3];
5492 
5493 	/* Check input parameters */
5494 	if ((src == NULL) ||
5495 		(dst == NULL) ||
5496 		(size == NULL) ||
5497 		(*size == 0))
5498 		return -1;
5499 
5500 	/* Convert chars to bytes */
5501 	for (i = 0, len = 0; i < *size; i += 2) {
5502 		snprintf(tmp, 3, "%s", src + i);
5503 		dst[len++] = strtoul(tmp, &c, 16);
5504 		if (*c != 0) {
5505 			len--;
5506 			dst[len] = 0;
5507 			*size = len;
5508 			return -1;
5509 		}
5510 	}
5511 	dst[len] = 0;
5512 	*size = len;
5513 
5514 	return 0;
5515 }
5516 
5517 static int
5518 parse_hex(struct context *ctx, const struct token *token,
5519 		const char *str, unsigned int len,
5520 		void *buf, unsigned int size)
5521 {
5522 	const struct arg *arg_data = pop_args(ctx);
5523 	const struct arg *arg_len = pop_args(ctx);
5524 	const struct arg *arg_addr = pop_args(ctx);
5525 	char tmp[16]; /* Ought to be enough. */
5526 	int ret;
5527 	unsigned int hexlen = len;
5528 	unsigned int length = 256;
5529 	uint8_t hex_tmp[length];
5530 
5531 	/* Arguments are expected. */
5532 	if (!arg_data)
5533 		return -1;
5534 	if (!arg_len) {
5535 		push_args(ctx, arg_data);
5536 		return -1;
5537 	}
5538 	if (!arg_addr) {
5539 		push_args(ctx, arg_len);
5540 		push_args(ctx, arg_data);
5541 		return -1;
5542 	}
5543 	size = arg_data->size;
5544 	/* Bit-mask fill is not supported. */
5545 	if (arg_data->mask)
5546 		goto error;
5547 	if (!ctx->object)
5548 		return len;
5549 
5550 	/* translate bytes string to array. */
5551 	if (str[0] == '0' && ((str[1] == 'x') ||
5552 			(str[1] == 'X'))) {
5553 		str += 2;
5554 		hexlen -= 2;
5555 	}
5556 	if (hexlen > length)
5557 		return -1;
5558 	ret = parse_hex_string(str, hex_tmp, &hexlen);
5559 	if (ret < 0)
5560 		goto error;
5561 	/* Let parse_int() fill length information first. */
5562 	ret = snprintf(tmp, sizeof(tmp), "%u", hexlen);
5563 	if (ret < 0)
5564 		goto error;
5565 	push_args(ctx, arg_len);
5566 	ret = parse_int(ctx, token, tmp, ret, NULL, 0);
5567 	if (ret < 0) {
5568 		pop_args(ctx);
5569 		goto error;
5570 	}
5571 	buf = (uint8_t *)ctx->object + arg_data->offset;
5572 	/* Output buffer is not necessarily NUL-terminated. */
5573 	memcpy(buf, hex_tmp, hexlen);
5574 	memset((uint8_t *)buf + hexlen, 0x00, size - hexlen);
5575 	if (ctx->objmask)
5576 		memset((uint8_t *)ctx->objmask + arg_data->offset,
5577 					0xff, hexlen);
5578 	/* Save address if requested. */
5579 	if (arg_addr->size) {
5580 		memcpy((uint8_t *)ctx->object + arg_addr->offset,
5581 		       (void *[]){
5582 			(uint8_t *)ctx->object + arg_data->offset
5583 		       },
5584 		       arg_addr->size);
5585 		if (ctx->objmask)
5586 			memcpy((uint8_t *)ctx->objmask + arg_addr->offset,
5587 			       (void *[]){
5588 				(uint8_t *)ctx->objmask + arg_data->offset
5589 			       },
5590 			       arg_addr->size);
5591 	}
5592 	return len;
5593 error:
5594 	push_args(ctx, arg_addr);
5595 	push_args(ctx, arg_len);
5596 	push_args(ctx, arg_data);
5597 	return -1;
5598 
5599 }
5600 
5601 /**
5602  * Parse a zero-ended string.
5603  */
5604 static int
5605 parse_string0(struct context *ctx, const struct token *token __rte_unused,
5606 	     const char *str, unsigned int len,
5607 	     void *buf, unsigned int size)
5608 {
5609 	const struct arg *arg_data = pop_args(ctx);
5610 
5611 	/* Arguments are expected. */
5612 	if (!arg_data)
5613 		return -1;
5614 	size = arg_data->size;
5615 	/* Bit-mask fill is not supported. */
5616 	if (arg_data->mask || size < len + 1)
5617 		goto error;
5618 	if (!ctx->object)
5619 		return len;
5620 	buf = (uint8_t *)ctx->object + arg_data->offset;
5621 	strncpy(buf, str, len);
5622 	if (ctx->objmask)
5623 		memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len);
5624 	return len;
5625 error:
5626 	push_args(ctx, arg_data);
5627 	return -1;
5628 }
5629 
5630 /**
5631  * Parse a MAC address.
5632  *
5633  * Last argument (ctx->args) is retrieved to determine storage size and
5634  * location.
5635  */
5636 static int
5637 parse_mac_addr(struct context *ctx, const struct token *token,
5638 	       const char *str, unsigned int len,
5639 	       void *buf, unsigned int size)
5640 {
5641 	const struct arg *arg = pop_args(ctx);
5642 	struct rte_ether_addr tmp;
5643 	int ret;
5644 
5645 	(void)token;
5646 	/* Argument is expected. */
5647 	if (!arg)
5648 		return -1;
5649 	size = arg->size;
5650 	/* Bit-mask fill is not supported. */
5651 	if (arg->mask || size != sizeof(tmp))
5652 		goto error;
5653 	/* Only network endian is supported. */
5654 	if (!arg->hton)
5655 		goto error;
5656 	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
5657 	if (ret < 0 || (unsigned int)ret != len)
5658 		goto error;
5659 	if (!ctx->object)
5660 		return len;
5661 	buf = (uint8_t *)ctx->object + arg->offset;
5662 	memcpy(buf, &tmp, size);
5663 	if (ctx->objmask)
5664 		memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
5665 	return len;
5666 error:
5667 	push_args(ctx, arg);
5668 	return -1;
5669 }
5670 
5671 /**
5672  * Parse an IPv4 address.
5673  *
5674  * Last argument (ctx->args) is retrieved to determine storage size and
5675  * location.
5676  */
5677 static int
5678 parse_ipv4_addr(struct context *ctx, const struct token *token,
5679 		const char *str, unsigned int len,
5680 		void *buf, unsigned int size)
5681 {
5682 	const struct arg *arg = pop_args(ctx);
5683 	char str2[len + 1];
5684 	struct in_addr tmp;
5685 	int ret;
5686 
5687 	/* Argument is expected. */
5688 	if (!arg)
5689 		return -1;
5690 	size = arg->size;
5691 	/* Bit-mask fill is not supported. */
5692 	if (arg->mask || size != sizeof(tmp))
5693 		goto error;
5694 	/* Only network endian is supported. */
5695 	if (!arg->hton)
5696 		goto error;
5697 	memcpy(str2, str, len);
5698 	str2[len] = '\0';
5699 	ret = inet_pton(AF_INET, str2, &tmp);
5700 	if (ret != 1) {
5701 		/* Attempt integer parsing. */
5702 		push_args(ctx, arg);
5703 		return parse_int(ctx, token, str, len, buf, size);
5704 	}
5705 	if (!ctx->object)
5706 		return len;
5707 	buf = (uint8_t *)ctx->object + arg->offset;
5708 	memcpy(buf, &tmp, size);
5709 	if (ctx->objmask)
5710 		memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
5711 	return len;
5712 error:
5713 	push_args(ctx, arg);
5714 	return -1;
5715 }
5716 
5717 /**
5718  * Parse an IPv6 address.
5719  *
5720  * Last argument (ctx->args) is retrieved to determine storage size and
5721  * location.
5722  */
5723 static int
5724 parse_ipv6_addr(struct context *ctx, const struct token *token,
5725 		const char *str, unsigned int len,
5726 		void *buf, unsigned int size)
5727 {
5728 	const struct arg *arg = pop_args(ctx);
5729 	char str2[len + 1];
5730 	struct in6_addr tmp;
5731 	int ret;
5732 
5733 	(void)token;
5734 	/* Argument is expected. */
5735 	if (!arg)
5736 		return -1;
5737 	size = arg->size;
5738 	/* Bit-mask fill is not supported. */
5739 	if (arg->mask || size != sizeof(tmp))
5740 		goto error;
5741 	/* Only network endian is supported. */
5742 	if (!arg->hton)
5743 		goto error;
5744 	memcpy(str2, str, len);
5745 	str2[len] = '\0';
5746 	ret = inet_pton(AF_INET6, str2, &tmp);
5747 	if (ret != 1)
5748 		goto error;
5749 	if (!ctx->object)
5750 		return len;
5751 	buf = (uint8_t *)ctx->object + arg->offset;
5752 	memcpy(buf, &tmp, size);
5753 	if (ctx->objmask)
5754 		memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
5755 	return len;
5756 error:
5757 	push_args(ctx, arg);
5758 	return -1;
5759 }
5760 
5761 /** Boolean values (even indices stand for false). */
5762 static const char *const boolean_name[] = {
5763 	"0", "1",
5764 	"false", "true",
5765 	"no", "yes",
5766 	"N", "Y",
5767 	"off", "on",
5768 	NULL,
5769 };
5770 
5771 /**
5772  * Parse a boolean value.
5773  *
5774  * Last argument (ctx->args) is retrieved to determine storage size and
5775  * location.
5776  */
5777 static int
5778 parse_boolean(struct context *ctx, const struct token *token,
5779 	      const char *str, unsigned int len,
5780 	      void *buf, unsigned int size)
5781 {
5782 	const struct arg *arg = pop_args(ctx);
5783 	unsigned int i;
5784 	int ret;
5785 
5786 	/* Argument is expected. */
5787 	if (!arg)
5788 		return -1;
5789 	for (i = 0; boolean_name[i]; ++i)
5790 		if (!strcmp_partial(boolean_name[i], str, len))
5791 			break;
5792 	/* Process token as integer. */
5793 	if (boolean_name[i])
5794 		str = i & 1 ? "1" : "0";
5795 	push_args(ctx, arg);
5796 	ret = parse_int(ctx, token, str, strlen(str), buf, size);
5797 	return ret > 0 ? (int)len : ret;
5798 }
5799 
5800 /** Parse port and update context. */
5801 static int
5802 parse_port(struct context *ctx, const struct token *token,
5803 	   const char *str, unsigned int len,
5804 	   void *buf, unsigned int size)
5805 {
5806 	struct buffer *out = &(struct buffer){ .port = 0 };
5807 	int ret;
5808 
5809 	if (buf)
5810 		out = buf;
5811 	else {
5812 		ctx->objdata = 0;
5813 		ctx->object = out;
5814 		ctx->objmask = NULL;
5815 		size = sizeof(*out);
5816 	}
5817 	ret = parse_int(ctx, token, str, len, out, size);
5818 	if (ret >= 0)
5819 		ctx->port = out->port;
5820 	if (!buf)
5821 		ctx->object = NULL;
5822 	return ret;
5823 }
5824 
5825 /** Parse set command, initialize output buffer for subsequent tokens. */
5826 static int
5827 parse_set_raw_encap_decap(struct context *ctx, const struct token *token,
5828 			  const char *str, unsigned int len,
5829 			  void *buf, unsigned int size)
5830 {
5831 	struct buffer *out = buf;
5832 
5833 	/* Token name must match. */
5834 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5835 		return -1;
5836 	/* Nothing else to do if there is no buffer. */
5837 	if (!out)
5838 		return len;
5839 	/* Make sure buffer is large enough. */
5840 	if (size < sizeof(*out))
5841 		return -1;
5842 	ctx->objdata = 0;
5843 	ctx->objmask = NULL;
5844 	ctx->object = out;
5845 	if (!out->command)
5846 		return -1;
5847 	out->command = ctx->curr;
5848 	return len;
5849 }
5850 
5851 /**
5852  * Parse set raw_encap/raw_decap command,
5853  * initialize output buffer for subsequent tokens.
5854  */
5855 static int
5856 parse_set_init(struct context *ctx, const struct token *token,
5857 	       const char *str, unsigned int len,
5858 	       void *buf, unsigned int size)
5859 {
5860 	struct buffer *out = buf;
5861 
5862 	/* Token name must match. */
5863 	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5864 		return -1;
5865 	/* Nothing else to do if there is no buffer. */
5866 	if (!out)
5867 		return len;
5868 	/* Make sure buffer is large enough. */
5869 	if (size < sizeof(*out))
5870 		return -1;
5871 	/* Initialize buffer. */
5872 	memset(out, 0x00, sizeof(*out));
5873 	memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out));
5874 	ctx->objdata = 0;
5875 	ctx->object = out;
5876 	ctx->objmask = NULL;
5877 	if (!out->command) {
5878 		if (ctx->curr != SET)
5879 			return -1;
5880 		if (sizeof(*out) > size)
5881 			return -1;
5882 		out->command = ctx->curr;
5883 		out->args.vc.data = (uint8_t *)out + size;
5884 		/* All we need is pattern */
5885 		out->args.vc.pattern =
5886 			(void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
5887 					       sizeof(double));
5888 		ctx->object = out->args.vc.pattern;
5889 	}
5890 	return len;
5891 }
5892 
5893 /** No completion. */
5894 static int
5895 comp_none(struct context *ctx, const struct token *token,
5896 	  unsigned int ent, char *buf, unsigned int size)
5897 {
5898 	(void)ctx;
5899 	(void)token;
5900 	(void)ent;
5901 	(void)buf;
5902 	(void)size;
5903 	return 0;
5904 }
5905 
5906 /** Complete boolean values. */
5907 static int
5908 comp_boolean(struct context *ctx, const struct token *token,
5909 	     unsigned int ent, char *buf, unsigned int size)
5910 {
5911 	unsigned int i;
5912 
5913 	(void)ctx;
5914 	(void)token;
5915 	for (i = 0; boolean_name[i]; ++i)
5916 		if (buf && i == ent)
5917 			return strlcpy(buf, boolean_name[i], size);
5918 	if (buf)
5919 		return -1;
5920 	return i;
5921 }
5922 
5923 /** Complete action names. */
5924 static int
5925 comp_action(struct context *ctx, const struct token *token,
5926 	    unsigned int ent, char *buf, unsigned int size)
5927 {
5928 	unsigned int i;
5929 
5930 	(void)ctx;
5931 	(void)token;
5932 	for (i = 0; next_action[i]; ++i)
5933 		if (buf && i == ent)
5934 			return strlcpy(buf, token_list[next_action[i]].name,
5935 				       size);
5936 	if (buf)
5937 		return -1;
5938 	return i;
5939 }
5940 
5941 /** Complete available ports. */
5942 static int
5943 comp_port(struct context *ctx, const struct token *token,
5944 	  unsigned int ent, char *buf, unsigned int size)
5945 {
5946 	unsigned int i = 0;
5947 	portid_t p;
5948 
5949 	(void)ctx;
5950 	(void)token;
5951 	RTE_ETH_FOREACH_DEV(p) {
5952 		if (buf && i == ent)
5953 			return snprintf(buf, size, "%u", p);
5954 		++i;
5955 	}
5956 	if (buf)
5957 		return -1;
5958 	return i;
5959 }
5960 
5961 /** Complete available rule IDs. */
5962 static int
5963 comp_rule_id(struct context *ctx, const struct token *token,
5964 	     unsigned int ent, char *buf, unsigned int size)
5965 {
5966 	unsigned int i = 0;
5967 	struct rte_port *port;
5968 	struct port_flow *pf;
5969 
5970 	(void)token;
5971 	if (port_id_is_invalid(ctx->port, DISABLED_WARN) ||
5972 	    ctx->port == (portid_t)RTE_PORT_ALL)
5973 		return -1;
5974 	port = &ports[ctx->port];
5975 	for (pf = port->flow_list; pf != NULL; pf = pf->next) {
5976 		if (buf && i == ent)
5977 			return snprintf(buf, size, "%u", pf->id);
5978 		++i;
5979 	}
5980 	if (buf)
5981 		return -1;
5982 	return i;
5983 }
5984 
5985 /** Complete type field for RSS action. */
5986 static int
5987 comp_vc_action_rss_type(struct context *ctx, const struct token *token,
5988 			unsigned int ent, char *buf, unsigned int size)
5989 {
5990 	unsigned int i;
5991 
5992 	(void)ctx;
5993 	(void)token;
5994 	for (i = 0; rss_type_table[i].str; ++i)
5995 		;
5996 	if (!buf)
5997 		return i + 1;
5998 	if (ent < i)
5999 		return strlcpy(buf, rss_type_table[ent].str, size);
6000 	if (ent == i)
6001 		return snprintf(buf, size, "end");
6002 	return -1;
6003 }
6004 
6005 /** Complete queue field for RSS action. */
6006 static int
6007 comp_vc_action_rss_queue(struct context *ctx, const struct token *token,
6008 			 unsigned int ent, char *buf, unsigned int size)
6009 {
6010 	(void)ctx;
6011 	(void)token;
6012 	if (!buf)
6013 		return nb_rxq + 1;
6014 	if (ent < nb_rxq)
6015 		return snprintf(buf, size, "%u", ent);
6016 	if (ent == nb_rxq)
6017 		return snprintf(buf, size, "end");
6018 	return -1;
6019 }
6020 
6021 /** Complete index number for set raw_encap/raw_decap commands. */
6022 static int
6023 comp_set_raw_index(struct context *ctx, const struct token *token,
6024 		   unsigned int ent, char *buf, unsigned int size)
6025 {
6026 	uint16_t idx = 0;
6027 	uint16_t nb = 0;
6028 
6029 	RTE_SET_USED(ctx);
6030 	RTE_SET_USED(token);
6031 	for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) {
6032 		if (buf && idx == ent)
6033 			return snprintf(buf, size, "%u", idx);
6034 		++nb;
6035 	}
6036 	return nb;
6037 }
6038 
6039 /** Internal context. */
6040 static struct context cmd_flow_context;
6041 
6042 /** Global parser instance (cmdline API). */
6043 cmdline_parse_inst_t cmd_flow;
6044 cmdline_parse_inst_t cmd_set_raw;
6045 
6046 /** Initialize context. */
6047 static void
6048 cmd_flow_context_init(struct context *ctx)
6049 {
6050 	/* A full memset() is not necessary. */
6051 	ctx->curr = ZERO;
6052 	ctx->prev = ZERO;
6053 	ctx->next_num = 0;
6054 	ctx->args_num = 0;
6055 	ctx->eol = 0;
6056 	ctx->last = 0;
6057 	ctx->port = 0;
6058 	ctx->objdata = 0;
6059 	ctx->object = NULL;
6060 	ctx->objmask = NULL;
6061 }
6062 
6063 /** Parse a token (cmdline API). */
6064 static int
6065 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result,
6066 	       unsigned int size)
6067 {
6068 	struct context *ctx = &cmd_flow_context;
6069 	const struct token *token;
6070 	const enum index *list;
6071 	int len;
6072 	int i;
6073 
6074 	(void)hdr;
6075 	token = &token_list[ctx->curr];
6076 	/* Check argument length. */
6077 	ctx->eol = 0;
6078 	ctx->last = 1;
6079 	for (len = 0; src[len]; ++len)
6080 		if (src[len] == '#' || isspace(src[len]))
6081 			break;
6082 	if (!len)
6083 		return -1;
6084 	/* Last argument and EOL detection. */
6085 	for (i = len; src[i]; ++i)
6086 		if (src[i] == '#' || src[i] == '\r' || src[i] == '\n')
6087 			break;
6088 		else if (!isspace(src[i])) {
6089 			ctx->last = 0;
6090 			break;
6091 		}
6092 	for (; src[i]; ++i)
6093 		if (src[i] == '\r' || src[i] == '\n') {
6094 			ctx->eol = 1;
6095 			break;
6096 		}
6097 	/* Initialize context if necessary. */
6098 	if (!ctx->next_num) {
6099 		if (!token->next)
6100 			return 0;
6101 		ctx->next[ctx->next_num++] = token->next[0];
6102 	}
6103 	/* Process argument through candidates. */
6104 	ctx->prev = ctx->curr;
6105 	list = ctx->next[ctx->next_num - 1];
6106 	for (i = 0; list[i]; ++i) {
6107 		const struct token *next = &token_list[list[i]];
6108 		int tmp;
6109 
6110 		ctx->curr = list[i];
6111 		if (next->call)
6112 			tmp = next->call(ctx, next, src, len, result, size);
6113 		else
6114 			tmp = parse_default(ctx, next, src, len, result, size);
6115 		if (tmp == -1 || tmp != len)
6116 			continue;
6117 		token = next;
6118 		break;
6119 	}
6120 	if (!list[i])
6121 		return -1;
6122 	--ctx->next_num;
6123 	/* Push subsequent tokens if any. */
6124 	if (token->next)
6125 		for (i = 0; token->next[i]; ++i) {
6126 			if (ctx->next_num == RTE_DIM(ctx->next))
6127 				return -1;
6128 			ctx->next[ctx->next_num++] = token->next[i];
6129 		}
6130 	/* Push arguments if any. */
6131 	if (token->args)
6132 		for (i = 0; token->args[i]; ++i) {
6133 			if (ctx->args_num == RTE_DIM(ctx->args))
6134 				return -1;
6135 			ctx->args[ctx->args_num++] = token->args[i];
6136 		}
6137 	return len;
6138 }
6139 
6140 /** Return number of completion entries (cmdline API). */
6141 static int
6142 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr)
6143 {
6144 	struct context *ctx = &cmd_flow_context;
6145 	const struct token *token = &token_list[ctx->curr];
6146 	const enum index *list;
6147 	int i;
6148 
6149 	(void)hdr;
6150 	/* Count number of tokens in current list. */
6151 	if (ctx->next_num)
6152 		list = ctx->next[ctx->next_num - 1];
6153 	else
6154 		list = token->next[0];
6155 	for (i = 0; list[i]; ++i)
6156 		;
6157 	if (!i)
6158 		return 0;
6159 	/*
6160 	 * If there is a single token, use its completion callback, otherwise
6161 	 * return the number of entries.
6162 	 */
6163 	token = &token_list[list[0]];
6164 	if (i == 1 && token->comp) {
6165 		/* Save index for cmd_flow_get_help(). */
6166 		ctx->prev = list[0];
6167 		return token->comp(ctx, token, 0, NULL, 0);
6168 	}
6169 	return i;
6170 }
6171 
6172 /** Return a completion entry (cmdline API). */
6173 static int
6174 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index,
6175 			  char *dst, unsigned int size)
6176 {
6177 	struct context *ctx = &cmd_flow_context;
6178 	const struct token *token = &token_list[ctx->curr];
6179 	const enum index *list;
6180 	int i;
6181 
6182 	(void)hdr;
6183 	/* Count number of tokens in current list. */
6184 	if (ctx->next_num)
6185 		list = ctx->next[ctx->next_num - 1];
6186 	else
6187 		list = token->next[0];
6188 	for (i = 0; list[i]; ++i)
6189 		;
6190 	if (!i)
6191 		return -1;
6192 	/* If there is a single token, use its completion callback. */
6193 	token = &token_list[list[0]];
6194 	if (i == 1 && token->comp) {
6195 		/* Save index for cmd_flow_get_help(). */
6196 		ctx->prev = list[0];
6197 		return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0;
6198 	}
6199 	/* Otherwise make sure the index is valid and use defaults. */
6200 	if (index >= i)
6201 		return -1;
6202 	token = &token_list[list[index]];
6203 	strlcpy(dst, token->name, size);
6204 	/* Save index for cmd_flow_get_help(). */
6205 	ctx->prev = list[index];
6206 	return 0;
6207 }
6208 
6209 /** Populate help strings for current token (cmdline API). */
6210 static int
6211 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size)
6212 {
6213 	struct context *ctx = &cmd_flow_context;
6214 	const struct token *token = &token_list[ctx->prev];
6215 
6216 	(void)hdr;
6217 	if (!size)
6218 		return -1;
6219 	/* Set token type and update global help with details. */
6220 	strlcpy(dst, (token->type ? token->type : "TOKEN"), size);
6221 	if (token->help)
6222 		cmd_flow.help_str = token->help;
6223 	else
6224 		cmd_flow.help_str = token->name;
6225 	return 0;
6226 }
6227 
6228 /** Token definition template (cmdline API). */
6229 static struct cmdline_token_hdr cmd_flow_token_hdr = {
6230 	.ops = &(struct cmdline_token_ops){
6231 		.parse = cmd_flow_parse,
6232 		.complete_get_nb = cmd_flow_complete_get_nb,
6233 		.complete_get_elt = cmd_flow_complete_get_elt,
6234 		.get_help = cmd_flow_get_help,
6235 	},
6236 	.offset = 0,
6237 };
6238 
6239 /** Populate the next dynamic token. */
6240 static void
6241 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr,
6242 	     cmdline_parse_token_hdr_t **hdr_inst)
6243 {
6244 	struct context *ctx = &cmd_flow_context;
6245 
6246 	/* Always reinitialize context before requesting the first token. */
6247 	if (!(hdr_inst - cmd_flow.tokens))
6248 		cmd_flow_context_init(ctx);
6249 	/* Return NULL when no more tokens are expected. */
6250 	if (!ctx->next_num && ctx->curr) {
6251 		*hdr = NULL;
6252 		return;
6253 	}
6254 	/* Determine if command should end here. */
6255 	if (ctx->eol && ctx->last && ctx->next_num) {
6256 		const enum index *list = ctx->next[ctx->next_num - 1];
6257 		int i;
6258 
6259 		for (i = 0; list[i]; ++i) {
6260 			if (list[i] != END)
6261 				continue;
6262 			*hdr = NULL;
6263 			return;
6264 		}
6265 	}
6266 	*hdr = &cmd_flow_token_hdr;
6267 }
6268 
6269 /** Dispatch parsed buffer to function calls. */
6270 static void
6271 cmd_flow_parsed(const struct buffer *in)
6272 {
6273 	switch (in->command) {
6274 	case VALIDATE:
6275 		port_flow_validate(in->port, &in->args.vc.attr,
6276 				   in->args.vc.pattern, in->args.vc.actions);
6277 		break;
6278 	case CREATE:
6279 		port_flow_create(in->port, &in->args.vc.attr,
6280 				 in->args.vc.pattern, in->args.vc.actions);
6281 		break;
6282 	case DESTROY:
6283 		port_flow_destroy(in->port, in->args.destroy.rule_n,
6284 				  in->args.destroy.rule);
6285 		break;
6286 	case FLUSH:
6287 		port_flow_flush(in->port);
6288 		break;
6289 	case DUMP:
6290 		port_flow_dump(in->port, in->args.dump.file);
6291 		break;
6292 	case QUERY:
6293 		port_flow_query(in->port, in->args.query.rule,
6294 				&in->args.query.action);
6295 		break;
6296 	case LIST:
6297 		port_flow_list(in->port, in->args.list.group_n,
6298 			       in->args.list.group);
6299 		break;
6300 	case ISOLATE:
6301 		port_flow_isolate(in->port, in->args.isolate.set);
6302 		break;
6303 	default:
6304 		break;
6305 	}
6306 }
6307 
6308 /** Token generator and output processing callback (cmdline API). */
6309 static void
6310 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2)
6311 {
6312 	if (cl == NULL)
6313 		cmd_flow_tok(arg0, arg2);
6314 	else
6315 		cmd_flow_parsed(arg0);
6316 }
6317 
6318 /** Global parser instance (cmdline API). */
6319 cmdline_parse_inst_t cmd_flow = {
6320 	.f = cmd_flow_cb,
6321 	.data = NULL, /**< Unused. */
6322 	.help_str = NULL, /**< Updated by cmd_flow_get_help(). */
6323 	.tokens = {
6324 		NULL,
6325 	}, /**< Tokens are returned by cmd_flow_tok(). */
6326 };
6327 
6328 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */
6329 
6330 static void
6331 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto)
6332 {
6333 	struct rte_flow_item_ipv4 *ipv4;
6334 	struct rte_flow_item_eth *eth;
6335 	struct rte_flow_item_ipv6 *ipv6;
6336 	struct rte_flow_item_vxlan *vxlan;
6337 	struct rte_flow_item_vxlan_gpe *gpe;
6338 	struct rte_flow_item_nvgre *nvgre;
6339 	uint32_t ipv6_vtc_flow;
6340 
6341 	switch (item->type) {
6342 	case RTE_FLOW_ITEM_TYPE_ETH:
6343 		eth = (struct rte_flow_item_eth *)buf;
6344 		if (next_proto)
6345 			eth->type = rte_cpu_to_be_16(next_proto);
6346 		break;
6347 	case RTE_FLOW_ITEM_TYPE_IPV4:
6348 		ipv4 = (struct rte_flow_item_ipv4 *)buf;
6349 		ipv4->hdr.version_ihl = 0x45;
6350 		if (next_proto && ipv4->hdr.next_proto_id == 0)
6351 			ipv4->hdr.next_proto_id = (uint8_t)next_proto;
6352 		break;
6353 	case RTE_FLOW_ITEM_TYPE_IPV6:
6354 		ipv6 = (struct rte_flow_item_ipv6 *)buf;
6355 		if (next_proto && ipv6->hdr.proto == 0)
6356 			ipv6->hdr.proto = (uint8_t)next_proto;
6357 		ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->hdr.vtc_flow);
6358 		ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */
6359 		ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */
6360 		ipv6->hdr.vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow);
6361 		break;
6362 	case RTE_FLOW_ITEM_TYPE_VXLAN:
6363 		vxlan = (struct rte_flow_item_vxlan *)buf;
6364 		vxlan->flags = 0x08;
6365 		break;
6366 	case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
6367 		gpe = (struct rte_flow_item_vxlan_gpe *)buf;
6368 		gpe->flags = 0x0C;
6369 		break;
6370 	case RTE_FLOW_ITEM_TYPE_NVGRE:
6371 		nvgre = (struct rte_flow_item_nvgre *)buf;
6372 		nvgre->protocol = rte_cpu_to_be_16(0x6558);
6373 		nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000);
6374 		break;
6375 	default:
6376 		break;
6377 	}
6378 }
6379 
6380 /** Helper of get item's default mask. */
6381 static const void *
6382 flow_item_default_mask(const struct rte_flow_item *item)
6383 {
6384 	const void *mask = NULL;
6385 	static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX);
6386 
6387 	switch (item->type) {
6388 	case RTE_FLOW_ITEM_TYPE_ANY:
6389 		mask = &rte_flow_item_any_mask;
6390 		break;
6391 	case RTE_FLOW_ITEM_TYPE_VF:
6392 		mask = &rte_flow_item_vf_mask;
6393 		break;
6394 	case RTE_FLOW_ITEM_TYPE_PORT_ID:
6395 		mask = &rte_flow_item_port_id_mask;
6396 		break;
6397 	case RTE_FLOW_ITEM_TYPE_RAW:
6398 		mask = &rte_flow_item_raw_mask;
6399 		break;
6400 	case RTE_FLOW_ITEM_TYPE_ETH:
6401 		mask = &rte_flow_item_eth_mask;
6402 		break;
6403 	case RTE_FLOW_ITEM_TYPE_VLAN:
6404 		mask = &rte_flow_item_vlan_mask;
6405 		break;
6406 	case RTE_FLOW_ITEM_TYPE_IPV4:
6407 		mask = &rte_flow_item_ipv4_mask;
6408 		break;
6409 	case RTE_FLOW_ITEM_TYPE_IPV6:
6410 		mask = &rte_flow_item_ipv6_mask;
6411 		break;
6412 	case RTE_FLOW_ITEM_TYPE_ICMP:
6413 		mask = &rte_flow_item_icmp_mask;
6414 		break;
6415 	case RTE_FLOW_ITEM_TYPE_UDP:
6416 		mask = &rte_flow_item_udp_mask;
6417 		break;
6418 	case RTE_FLOW_ITEM_TYPE_TCP:
6419 		mask = &rte_flow_item_tcp_mask;
6420 		break;
6421 	case RTE_FLOW_ITEM_TYPE_SCTP:
6422 		mask = &rte_flow_item_sctp_mask;
6423 		break;
6424 	case RTE_FLOW_ITEM_TYPE_VXLAN:
6425 		mask = &rte_flow_item_vxlan_mask;
6426 		break;
6427 	case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
6428 		mask = &rte_flow_item_vxlan_gpe_mask;
6429 		break;
6430 	case RTE_FLOW_ITEM_TYPE_E_TAG:
6431 		mask = &rte_flow_item_e_tag_mask;
6432 		break;
6433 	case RTE_FLOW_ITEM_TYPE_NVGRE:
6434 		mask = &rte_flow_item_nvgre_mask;
6435 		break;
6436 	case RTE_FLOW_ITEM_TYPE_MPLS:
6437 		mask = &rte_flow_item_mpls_mask;
6438 		break;
6439 	case RTE_FLOW_ITEM_TYPE_GRE:
6440 		mask = &rte_flow_item_gre_mask;
6441 		break;
6442 	case RTE_FLOW_ITEM_TYPE_GRE_KEY:
6443 		mask = &gre_key_default_mask;
6444 		break;
6445 	case RTE_FLOW_ITEM_TYPE_META:
6446 		mask = &rte_flow_item_meta_mask;
6447 		break;
6448 	case RTE_FLOW_ITEM_TYPE_FUZZY:
6449 		mask = &rte_flow_item_fuzzy_mask;
6450 		break;
6451 	case RTE_FLOW_ITEM_TYPE_GTP:
6452 		mask = &rte_flow_item_gtp_mask;
6453 		break;
6454 	case RTE_FLOW_ITEM_TYPE_GTP_PSC:
6455 		mask = &rte_flow_item_gtp_psc_mask;
6456 		break;
6457 	case RTE_FLOW_ITEM_TYPE_GENEVE:
6458 		mask = &rte_flow_item_geneve_mask;
6459 		break;
6460 	case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID:
6461 		mask = &rte_flow_item_pppoe_proto_id_mask;
6462 		break;
6463 	case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
6464 		mask = &rte_flow_item_l2tpv3oip_mask;
6465 		break;
6466 	case RTE_FLOW_ITEM_TYPE_ESP:
6467 		mask = &rte_flow_item_esp_mask;
6468 		break;
6469 	case RTE_FLOW_ITEM_TYPE_AH:
6470 		mask = &rte_flow_item_ah_mask;
6471 		break;
6472 	default:
6473 		break;
6474 	}
6475 	return mask;
6476 }
6477 
6478 
6479 
6480 /** Dispatch parsed buffer to function calls. */
6481 static void
6482 cmd_set_raw_parsed(const struct buffer *in)
6483 {
6484 	uint32_t n = in->args.vc.pattern_n;
6485 	int i = 0;
6486 	struct rte_flow_item *item = NULL;
6487 	size_t size = 0;
6488 	uint8_t *data = NULL;
6489 	uint8_t *data_tail = NULL;
6490 	size_t *total_size = NULL;
6491 	uint16_t upper_layer = 0;
6492 	uint16_t proto = 0;
6493 	uint16_t idx = in->port; /* We borrow port field as index */
6494 
6495 	RTE_ASSERT(in->command == SET_RAW_ENCAP ||
6496 		   in->command == SET_RAW_DECAP);
6497 	if (in->command == SET_RAW_ENCAP) {
6498 		total_size = &raw_encap_confs[idx].size;
6499 		data = (uint8_t *)&raw_encap_confs[idx].data;
6500 	} else {
6501 		total_size = &raw_decap_confs[idx].size;
6502 		data = (uint8_t *)&raw_decap_confs[idx].data;
6503 	}
6504 	*total_size = 0;
6505 	memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA);
6506 	/* process hdr from upper layer to low layer (L3/L4 -> L2). */
6507 	data_tail = data + ACTION_RAW_ENCAP_MAX_DATA;
6508 	for (i = n - 1 ; i >= 0; --i) {
6509 		item = in->args.vc.pattern + i;
6510 		if (item->spec == NULL)
6511 			item->spec = flow_item_default_mask(item);
6512 		switch (item->type) {
6513 		case RTE_FLOW_ITEM_TYPE_ETH:
6514 			size = sizeof(struct rte_flow_item_eth);
6515 			break;
6516 		case RTE_FLOW_ITEM_TYPE_VLAN:
6517 			size = sizeof(struct rte_flow_item_vlan);
6518 			proto = RTE_ETHER_TYPE_VLAN;
6519 			break;
6520 		case RTE_FLOW_ITEM_TYPE_IPV4:
6521 			size = sizeof(struct rte_flow_item_ipv4);
6522 			proto = RTE_ETHER_TYPE_IPV4;
6523 			break;
6524 		case RTE_FLOW_ITEM_TYPE_IPV6:
6525 			size = sizeof(struct rte_flow_item_ipv6);
6526 			proto = RTE_ETHER_TYPE_IPV6;
6527 			break;
6528 		case RTE_FLOW_ITEM_TYPE_UDP:
6529 			size = sizeof(struct rte_flow_item_udp);
6530 			proto = 0x11;
6531 			break;
6532 		case RTE_FLOW_ITEM_TYPE_TCP:
6533 			size = sizeof(struct rte_flow_item_tcp);
6534 			proto = 0x06;
6535 			break;
6536 		case RTE_FLOW_ITEM_TYPE_VXLAN:
6537 			size = sizeof(struct rte_flow_item_vxlan);
6538 			break;
6539 		case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
6540 			size = sizeof(struct rte_flow_item_vxlan_gpe);
6541 			break;
6542 		case RTE_FLOW_ITEM_TYPE_GRE:
6543 			size = sizeof(struct rte_flow_item_gre);
6544 			proto = 0x2F;
6545 			break;
6546 		case RTE_FLOW_ITEM_TYPE_GRE_KEY:
6547 			size = sizeof(rte_be32_t);
6548 			proto = 0x0;
6549 			break;
6550 		case RTE_FLOW_ITEM_TYPE_MPLS:
6551 			size = sizeof(struct rte_flow_item_mpls);
6552 			proto = 0x0;
6553 			break;
6554 		case RTE_FLOW_ITEM_TYPE_NVGRE:
6555 			size = sizeof(struct rte_flow_item_nvgre);
6556 			proto = 0x2F;
6557 			break;
6558 		case RTE_FLOW_ITEM_TYPE_GENEVE:
6559 			size = sizeof(struct rte_flow_item_geneve);
6560 			break;
6561 		case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
6562 			size = sizeof(struct rte_flow_item_l2tpv3oip);
6563 			proto = 0x73;
6564 			break;
6565 		case RTE_FLOW_ITEM_TYPE_ESP:
6566 			size = sizeof(struct rte_flow_item_esp);
6567 			proto = 0x32;
6568 			break;
6569 		case RTE_FLOW_ITEM_TYPE_AH:
6570 			size = sizeof(struct rte_flow_item_ah);
6571 			proto = 0x33;
6572 			break;
6573 		default:
6574 			printf("Error - Not supported item\n");
6575 			*total_size = 0;
6576 			memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA);
6577 			return;
6578 		}
6579 		*total_size += size;
6580 		rte_memcpy(data_tail - (*total_size), item->spec, size);
6581 		/* update some fields which cannot be set by cmdline */
6582 		update_fields((data_tail - (*total_size)), item,
6583 			      upper_layer);
6584 		upper_layer = proto;
6585 	}
6586 	if (verbose_level & 0x1)
6587 		printf("total data size is %zu\n", (*total_size));
6588 	RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA);
6589 	memmove(data, (data_tail - (*total_size)), *total_size);
6590 }
6591 
6592 /** Populate help strings for current token (cmdline API). */
6593 static int
6594 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst,
6595 		     unsigned int size)
6596 {
6597 	struct context *ctx = &cmd_flow_context;
6598 	const struct token *token = &token_list[ctx->prev];
6599 
6600 	(void)hdr;
6601 	if (!size)
6602 		return -1;
6603 	/* Set token type and update global help with details. */
6604 	snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN"));
6605 	if (token->help)
6606 		cmd_set_raw.help_str = token->help;
6607 	else
6608 		cmd_set_raw.help_str = token->name;
6609 	return 0;
6610 }
6611 
6612 /** Token definition template (cmdline API). */
6613 static struct cmdline_token_hdr cmd_set_raw_token_hdr = {
6614 	.ops = &(struct cmdline_token_ops){
6615 		.parse = cmd_flow_parse,
6616 		.complete_get_nb = cmd_flow_complete_get_nb,
6617 		.complete_get_elt = cmd_flow_complete_get_elt,
6618 		.get_help = cmd_set_raw_get_help,
6619 	},
6620 	.offset = 0,
6621 };
6622 
6623 /** Populate the next dynamic token. */
6624 static void
6625 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr,
6626 	     cmdline_parse_token_hdr_t **hdr_inst)
6627 {
6628 	struct context *ctx = &cmd_flow_context;
6629 
6630 	/* Always reinitialize context before requesting the first token. */
6631 	if (!(hdr_inst - cmd_set_raw.tokens)) {
6632 		cmd_flow_context_init(ctx);
6633 		ctx->curr = START_SET;
6634 	}
6635 	/* Return NULL when no more tokens are expected. */
6636 	if (!ctx->next_num && (ctx->curr != START_SET)) {
6637 		*hdr = NULL;
6638 		return;
6639 	}
6640 	/* Determine if command should end here. */
6641 	if (ctx->eol && ctx->last && ctx->next_num) {
6642 		const enum index *list = ctx->next[ctx->next_num - 1];
6643 		int i;
6644 
6645 		for (i = 0; list[i]; ++i) {
6646 			if (list[i] != END)
6647 				continue;
6648 			*hdr = NULL;
6649 			return;
6650 		}
6651 	}
6652 	*hdr = &cmd_set_raw_token_hdr;
6653 }
6654 
6655 /** Token generator and output processing callback (cmdline API). */
6656 static void
6657 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2)
6658 {
6659 	if (cl == NULL)
6660 		cmd_set_raw_tok(arg0, arg2);
6661 	else
6662 		cmd_set_raw_parsed(arg0);
6663 }
6664 
6665 /** Global parser instance (cmdline API). */
6666 cmdline_parse_inst_t cmd_set_raw = {
6667 	.f = cmd_set_raw_cb,
6668 	.data = NULL, /**< Unused. */
6669 	.help_str = NULL, /**< Updated by cmd_flow_get_help(). */
6670 	.tokens = {
6671 		NULL,
6672 	}, /**< Tokens are returned by cmd_flow_tok(). */
6673 };
6674 
6675 /* *** display raw_encap/raw_decap buf */
6676 struct cmd_show_set_raw_result {
6677 	cmdline_fixed_string_t cmd_show;
6678 	cmdline_fixed_string_t cmd_what;
6679 	cmdline_fixed_string_t cmd_all;
6680 	uint16_t cmd_index;
6681 };
6682 
6683 static void
6684 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data)
6685 {
6686 	struct cmd_show_set_raw_result *res = parsed_result;
6687 	uint16_t index = res->cmd_index;
6688 	uint8_t all = 0;
6689 	uint8_t *raw_data = NULL;
6690 	size_t raw_size = 0;
6691 	char title[16] = {0};
6692 
6693 	RTE_SET_USED(cl);
6694 	RTE_SET_USED(data);
6695 	if (!strcmp(res->cmd_all, "all")) {
6696 		all = 1;
6697 		index = 0;
6698 	} else if (index >= RAW_ENCAP_CONFS_MAX_NUM) {
6699 		printf("index should be 0-%u\n", RAW_ENCAP_CONFS_MAX_NUM - 1);
6700 		return;
6701 	}
6702 	do {
6703 		if (!strcmp(res->cmd_what, "raw_encap")) {
6704 			raw_data = (uint8_t *)&raw_encap_confs[index].data;
6705 			raw_size = raw_encap_confs[index].size;
6706 			snprintf(title, 16, "\nindex: %u", index);
6707 			rte_hexdump(stdout, title, raw_data, raw_size);
6708 		} else {
6709 			raw_data = (uint8_t *)&raw_decap_confs[index].data;
6710 			raw_size = raw_decap_confs[index].size;
6711 			snprintf(title, 16, "\nindex: %u", index);
6712 			rte_hexdump(stdout, title, raw_data, raw_size);
6713 		}
6714 	} while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM);
6715 }
6716 
6717 cmdline_parse_token_string_t cmd_show_set_raw_cmd_show =
6718 	TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
6719 			cmd_show, "show");
6720 cmdline_parse_token_string_t cmd_show_set_raw_cmd_what =
6721 	TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
6722 			cmd_what, "raw_encap#raw_decap");
6723 cmdline_parse_token_num_t cmd_show_set_raw_cmd_index =
6724 	TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result,
6725 			cmd_index, UINT16);
6726 cmdline_parse_token_string_t cmd_show_set_raw_cmd_all =
6727 	TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
6728 			cmd_all, "all");
6729 cmdline_parse_inst_t cmd_show_set_raw = {
6730 	.f = cmd_show_set_raw_parsed,
6731 	.data = NULL,
6732 	.help_str = "show <raw_encap|raw_decap> <index>",
6733 	.tokens = {
6734 		(void *)&cmd_show_set_raw_cmd_show,
6735 		(void *)&cmd_show_set_raw_cmd_what,
6736 		(void *)&cmd_show_set_raw_cmd_index,
6737 		NULL,
6738 	},
6739 };
6740 cmdline_parse_inst_t cmd_show_set_raw_all = {
6741 	.f = cmd_show_set_raw_parsed,
6742 	.data = NULL,
6743 	.help_str = "show <raw_encap|raw_decap> all",
6744 	.tokens = {
6745 		(void *)&cmd_show_set_raw_cmd_show,
6746 		(void *)&cmd_show_set_raw_cmd_what,
6747 		(void *)&cmd_show_set_raw_cmd_all,
6748 		NULL,
6749 	},
6750 };
6751