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