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