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