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