ethdev: fix C99 flexible arrays from flow API
[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_common.h>
17 #include <rte_ethdev.h>
18 #include <rte_byteorder.h>
19 #include <cmdline_parse.h>
20 #include <cmdline_parse_etheraddr.h>
21 #include <rte_flow.h>
22
23 #include "testpmd.h"
24
25 /** Parser token indices. */
26 enum index {
27         /* Special tokens. */
28         ZERO = 0,
29         END,
30
31         /* Common tokens. */
32         INTEGER,
33         UNSIGNED,
34         PREFIX,
35         BOOLEAN,
36         STRING,
37         MAC_ADDR,
38         IPV4_ADDR,
39         IPV6_ADDR,
40         RULE_ID,
41         PORT_ID,
42         GROUP_ID,
43         PRIORITY_LEVEL,
44
45         /* Top-level command. */
46         FLOW,
47
48         /* Sub-level commands. */
49         VALIDATE,
50         CREATE,
51         DESTROY,
52         FLUSH,
53         QUERY,
54         LIST,
55         ISOLATE,
56
57         /* Destroy arguments. */
58         DESTROY_RULE,
59
60         /* Query arguments. */
61         QUERY_ACTION,
62
63         /* List arguments. */
64         LIST_GROUP,
65
66         /* Validate/create arguments. */
67         GROUP,
68         PRIORITY,
69         INGRESS,
70         EGRESS,
71
72         /* Validate/create pattern. */
73         PATTERN,
74         ITEM_PARAM_IS,
75         ITEM_PARAM_SPEC,
76         ITEM_PARAM_LAST,
77         ITEM_PARAM_MASK,
78         ITEM_PARAM_PREFIX,
79         ITEM_NEXT,
80         ITEM_END,
81         ITEM_VOID,
82         ITEM_INVERT,
83         ITEM_ANY,
84         ITEM_ANY_NUM,
85         ITEM_PF,
86         ITEM_VF,
87         ITEM_VF_ID,
88         ITEM_PORT,
89         ITEM_PORT_INDEX,
90         ITEM_RAW,
91         ITEM_RAW_RELATIVE,
92         ITEM_RAW_SEARCH,
93         ITEM_RAW_OFFSET,
94         ITEM_RAW_LIMIT,
95         ITEM_RAW_PATTERN,
96         ITEM_ETH,
97         ITEM_ETH_DST,
98         ITEM_ETH_SRC,
99         ITEM_ETH_TYPE,
100         ITEM_VLAN,
101         ITEM_VLAN_TPID,
102         ITEM_VLAN_TCI,
103         ITEM_VLAN_PCP,
104         ITEM_VLAN_DEI,
105         ITEM_VLAN_VID,
106         ITEM_IPV4,
107         ITEM_IPV4_TOS,
108         ITEM_IPV4_TTL,
109         ITEM_IPV4_PROTO,
110         ITEM_IPV4_SRC,
111         ITEM_IPV4_DST,
112         ITEM_IPV6,
113         ITEM_IPV6_TC,
114         ITEM_IPV6_FLOW,
115         ITEM_IPV6_PROTO,
116         ITEM_IPV6_HOP,
117         ITEM_IPV6_SRC,
118         ITEM_IPV6_DST,
119         ITEM_ICMP,
120         ITEM_ICMP_TYPE,
121         ITEM_ICMP_CODE,
122         ITEM_UDP,
123         ITEM_UDP_SRC,
124         ITEM_UDP_DST,
125         ITEM_TCP,
126         ITEM_TCP_SRC,
127         ITEM_TCP_DST,
128         ITEM_TCP_FLAGS,
129         ITEM_SCTP,
130         ITEM_SCTP_SRC,
131         ITEM_SCTP_DST,
132         ITEM_SCTP_TAG,
133         ITEM_SCTP_CKSUM,
134         ITEM_VXLAN,
135         ITEM_VXLAN_VNI,
136         ITEM_E_TAG,
137         ITEM_E_TAG_GRP_ECID_B,
138         ITEM_NVGRE,
139         ITEM_NVGRE_TNI,
140         ITEM_MPLS,
141         ITEM_MPLS_LABEL,
142         ITEM_GRE,
143         ITEM_GRE_PROTO,
144         ITEM_FUZZY,
145         ITEM_FUZZY_THRESH,
146         ITEM_GTP,
147         ITEM_GTP_TEID,
148         ITEM_GTPC,
149         ITEM_GTPU,
150         ITEM_GENEVE,
151         ITEM_GENEVE_VNI,
152         ITEM_GENEVE_PROTO,
153
154         /* Validate/create actions. */
155         ACTIONS,
156         ACTION_NEXT,
157         ACTION_END,
158         ACTION_VOID,
159         ACTION_PASSTHRU,
160         ACTION_MARK,
161         ACTION_MARK_ID,
162         ACTION_FLAG,
163         ACTION_QUEUE,
164         ACTION_QUEUE_INDEX,
165         ACTION_DROP,
166         ACTION_COUNT,
167         ACTION_RSS,
168         ACTION_RSS_TYPES,
169         ACTION_RSS_TYPE,
170         ACTION_RSS_KEY,
171         ACTION_RSS_KEY_LEN,
172         ACTION_RSS_QUEUES,
173         ACTION_RSS_QUEUE,
174         ACTION_PF,
175         ACTION_VF,
176         ACTION_VF_ORIGINAL,
177         ACTION_VF_ID,
178         ACTION_METER,
179         ACTION_METER_ID,
180 };
181
182 /** Maximum size for pattern in struct rte_flow_item_raw. */
183 #define ITEM_RAW_PATTERN_SIZE 40
184
185 /** Storage size for struct rte_flow_item_raw including pattern. */
186 #define ITEM_RAW_SIZE \
187         (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
188
189 /** Maximum number of queue indices in struct rte_flow_action_rss. */
190 #define ACTION_RSS_QUEUE_NUM 32
191
192 /** Storage for struct rte_flow_action_rss including external data. */
193 struct action_rss_data {
194         struct rte_flow_action_rss conf;
195         uint16_t queue[ACTION_RSS_QUEUE_NUM];
196         struct rte_eth_rss_conf rss_conf;
197         uint8_t rss_key[RSS_HASH_KEY_LENGTH];
198 };
199
200 /** Maximum number of subsequent tokens and arguments on the stack. */
201 #define CTX_STACK_SIZE 16
202
203 /** Parser context. */
204 struct context {
205         /** Stack of subsequent token lists to process. */
206         const enum index *next[CTX_STACK_SIZE];
207         /** Arguments for stacked tokens. */
208         const void *args[CTX_STACK_SIZE];
209         enum index curr; /**< Current token index. */
210         enum index prev; /**< Index of the last token seen. */
211         int next_num; /**< Number of entries in next[]. */
212         int args_num; /**< Number of entries in args[]. */
213         uint32_t eol:1; /**< EOL has been detected. */
214         uint32_t last:1; /**< No more arguments. */
215         portid_t port; /**< Current port ID (for completions). */
216         uint32_t objdata; /**< Object-specific data. */
217         void *object; /**< Address of current object for relative offsets. */
218         void *objmask; /**< Object a full mask must be written to. */
219 };
220
221 /** Token argument. */
222 struct arg {
223         uint32_t hton:1; /**< Use network byte ordering. */
224         uint32_t sign:1; /**< Value is signed. */
225         uint32_t bounded:1; /**< Value is bounded. */
226         uintmax_t min; /**< Minimum value if bounded. */
227         uintmax_t max; /**< Maximum value if bounded. */
228         uint32_t offset; /**< Relative offset from ctx->object. */
229         uint32_t size; /**< Field size. */
230         const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */
231 };
232
233 /** Parser token definition. */
234 struct token {
235         /** Type displayed during completion (defaults to "TOKEN"). */
236         const char *type;
237         /** Help displayed during completion (defaults to token name). */
238         const char *help;
239         /** Private data used by parser functions. */
240         const void *priv;
241         /**
242          * Lists of subsequent tokens to push on the stack. Each call to the
243          * parser consumes the last entry of that stack.
244          */
245         const enum index *const *next;
246         /** Arguments stack for subsequent tokens that need them. */
247         const struct arg *const *args;
248         /**
249          * Token-processing callback, returns -1 in case of error, the
250          * length of the matched string otherwise. If NULL, attempts to
251          * match the token name.
252          *
253          * If buf is not NULL, the result should be stored in it according
254          * to context. An error is returned if not large enough.
255          */
256         int (*call)(struct context *ctx, const struct token *token,
257                     const char *str, unsigned int len,
258                     void *buf, unsigned int size);
259         /**
260          * Callback that provides possible values for this token, used for
261          * completion. Returns -1 in case of error, the number of possible
262          * values otherwise. If NULL, the token name is used.
263          *
264          * If buf is not NULL, entry index ent is written to buf and the
265          * full length of the entry is returned (same behavior as
266          * snprintf()).
267          */
268         int (*comp)(struct context *ctx, const struct token *token,
269                     unsigned int ent, char *buf, unsigned int size);
270         /** Mandatory token name, no default value. */
271         const char *name;
272 };
273
274 /** Static initializer for the next field. */
275 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, }
276
277 /** Static initializer for a NEXT() entry. */
278 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, }
279
280 /** Static initializer for the args field. */
281 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, }
282
283 /** Static initializer for ARGS() to target a field. */
284 #define ARGS_ENTRY(s, f) \
285         (&(const struct arg){ \
286                 .offset = offsetof(s, f), \
287                 .size = sizeof(((s *)0)->f), \
288         })
289
290 /** Static initializer for ARGS() to target a bit-field. */
291 #define ARGS_ENTRY_BF(s, f, b) \
292         (&(const struct arg){ \
293                 .size = sizeof(s), \
294                 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \
295         })
296
297 /** Static initializer for ARGS() to target an arbitrary bit-mask. */
298 #define ARGS_ENTRY_MASK(s, f, m) \
299         (&(const struct arg){ \
300                 .offset = offsetof(s, f), \
301                 .size = sizeof(((s *)0)->f), \
302                 .mask = (const void *)(m), \
303         })
304
305 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */
306 #define ARGS_ENTRY_MASK_HTON(s, f, m) \
307         (&(const struct arg){ \
308                 .hton = 1, \
309                 .offset = offsetof(s, f), \
310                 .size = sizeof(((s *)0)->f), \
311                 .mask = (const void *)(m), \
312         })
313
314 /** Static initializer for ARGS() to target a pointer. */
315 #define ARGS_ENTRY_PTR(s, f) \
316         (&(const struct arg){ \
317                 .size = sizeof(*((s *)0)->f), \
318         })
319
320 /** Static initializer for ARGS() with arbitrary offset and size. */
321 #define ARGS_ENTRY_ARB(o, s) \
322         (&(const struct arg){ \
323                 .offset = (o), \
324                 .size = (s), \
325         })
326
327 /** Same as ARGS_ENTRY_ARB() with bounded values. */
328 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \
329         (&(const struct arg){ \
330                 .bounded = 1, \
331                 .min = (i), \
332                 .max = (a), \
333                 .offset = (o), \
334                 .size = (s), \
335         })
336
337 /** Same as ARGS_ENTRY() using network byte ordering. */
338 #define ARGS_ENTRY_HTON(s, f) \
339         (&(const struct arg){ \
340                 .hton = 1, \
341                 .offset = offsetof(s, f), \
342                 .size = sizeof(((s *)0)->f), \
343         })
344
345 /** Parser output buffer layout expected by cmd_flow_parsed(). */
346 struct buffer {
347         enum index command; /**< Flow command. */
348         portid_t port; /**< Affected port ID. */
349         union {
350                 struct {
351                         struct rte_flow_attr attr;
352                         struct rte_flow_item *pattern;
353                         struct rte_flow_action *actions;
354                         uint32_t pattern_n;
355                         uint32_t actions_n;
356                         uint8_t *data;
357                 } vc; /**< Validate/create arguments. */
358                 struct {
359                         uint32_t *rule;
360                         uint32_t rule_n;
361                 } destroy; /**< Destroy arguments. */
362                 struct {
363                         uint32_t rule;
364                         enum rte_flow_action_type action;
365                 } query; /**< Query arguments. */
366                 struct {
367                         uint32_t *group;
368                         uint32_t group_n;
369                 } list; /**< List arguments. */
370                 struct {
371                         int set;
372                 } isolate; /**< Isolated mode arguments. */
373         } args; /**< Command arguments. */
374 };
375
376 /** Private data for pattern items. */
377 struct parse_item_priv {
378         enum rte_flow_item_type type; /**< Item type. */
379         uint32_t size; /**< Size of item specification structure. */
380 };
381
382 #define PRIV_ITEM(t, s) \
383         (&(const struct parse_item_priv){ \
384                 .type = RTE_FLOW_ITEM_TYPE_ ## t, \
385                 .size = s, \
386         })
387
388 /** Private data for actions. */
389 struct parse_action_priv {
390         enum rte_flow_action_type type; /**< Action type. */
391         uint32_t size; /**< Size of action configuration structure. */
392 };
393
394 #define PRIV_ACTION(t, s) \
395         (&(const struct parse_action_priv){ \
396                 .type = RTE_FLOW_ACTION_TYPE_ ## t, \
397                 .size = s, \
398         })
399
400 static const enum index next_vc_attr[] = {
401         GROUP,
402         PRIORITY,
403         INGRESS,
404         EGRESS,
405         PATTERN,
406         ZERO,
407 };
408
409 static const enum index next_destroy_attr[] = {
410         DESTROY_RULE,
411         END,
412         ZERO,
413 };
414
415 static const enum index next_list_attr[] = {
416         LIST_GROUP,
417         END,
418         ZERO,
419 };
420
421 static const enum index item_param[] = {
422         ITEM_PARAM_IS,
423         ITEM_PARAM_SPEC,
424         ITEM_PARAM_LAST,
425         ITEM_PARAM_MASK,
426         ITEM_PARAM_PREFIX,
427         ZERO,
428 };
429
430 static const enum index next_item[] = {
431         ITEM_END,
432         ITEM_VOID,
433         ITEM_INVERT,
434         ITEM_ANY,
435         ITEM_PF,
436         ITEM_VF,
437         ITEM_PORT,
438         ITEM_RAW,
439         ITEM_ETH,
440         ITEM_VLAN,
441         ITEM_IPV4,
442         ITEM_IPV6,
443         ITEM_ICMP,
444         ITEM_UDP,
445         ITEM_TCP,
446         ITEM_SCTP,
447         ITEM_VXLAN,
448         ITEM_E_TAG,
449         ITEM_NVGRE,
450         ITEM_MPLS,
451         ITEM_GRE,
452         ITEM_FUZZY,
453         ITEM_GTP,
454         ITEM_GTPC,
455         ITEM_GTPU,
456         ITEM_GENEVE,
457         ZERO,
458 };
459
460 static const enum index item_fuzzy[] = {
461         ITEM_FUZZY_THRESH,
462         ITEM_NEXT,
463         ZERO,
464 };
465
466 static const enum index item_any[] = {
467         ITEM_ANY_NUM,
468         ITEM_NEXT,
469         ZERO,
470 };
471
472 static const enum index item_vf[] = {
473         ITEM_VF_ID,
474         ITEM_NEXT,
475         ZERO,
476 };
477
478 static const enum index item_port[] = {
479         ITEM_PORT_INDEX,
480         ITEM_NEXT,
481         ZERO,
482 };
483
484 static const enum index item_raw[] = {
485         ITEM_RAW_RELATIVE,
486         ITEM_RAW_SEARCH,
487         ITEM_RAW_OFFSET,
488         ITEM_RAW_LIMIT,
489         ITEM_RAW_PATTERN,
490         ITEM_NEXT,
491         ZERO,
492 };
493
494 static const enum index item_eth[] = {
495         ITEM_ETH_DST,
496         ITEM_ETH_SRC,
497         ITEM_ETH_TYPE,
498         ITEM_NEXT,
499         ZERO,
500 };
501
502 static const enum index item_vlan[] = {
503         ITEM_VLAN_TPID,
504         ITEM_VLAN_TCI,
505         ITEM_VLAN_PCP,
506         ITEM_VLAN_DEI,
507         ITEM_VLAN_VID,
508         ITEM_NEXT,
509         ZERO,
510 };
511
512 static const enum index item_ipv4[] = {
513         ITEM_IPV4_TOS,
514         ITEM_IPV4_TTL,
515         ITEM_IPV4_PROTO,
516         ITEM_IPV4_SRC,
517         ITEM_IPV4_DST,
518         ITEM_NEXT,
519         ZERO,
520 };
521
522 static const enum index item_ipv6[] = {
523         ITEM_IPV6_TC,
524         ITEM_IPV6_FLOW,
525         ITEM_IPV6_PROTO,
526         ITEM_IPV6_HOP,
527         ITEM_IPV6_SRC,
528         ITEM_IPV6_DST,
529         ITEM_NEXT,
530         ZERO,
531 };
532
533 static const enum index item_icmp[] = {
534         ITEM_ICMP_TYPE,
535         ITEM_ICMP_CODE,
536         ITEM_NEXT,
537         ZERO,
538 };
539
540 static const enum index item_udp[] = {
541         ITEM_UDP_SRC,
542         ITEM_UDP_DST,
543         ITEM_NEXT,
544         ZERO,
545 };
546
547 static const enum index item_tcp[] = {
548         ITEM_TCP_SRC,
549         ITEM_TCP_DST,
550         ITEM_TCP_FLAGS,
551         ITEM_NEXT,
552         ZERO,
553 };
554
555 static const enum index item_sctp[] = {
556         ITEM_SCTP_SRC,
557         ITEM_SCTP_DST,
558         ITEM_SCTP_TAG,
559         ITEM_SCTP_CKSUM,
560         ITEM_NEXT,
561         ZERO,
562 };
563
564 static const enum index item_vxlan[] = {
565         ITEM_VXLAN_VNI,
566         ITEM_NEXT,
567         ZERO,
568 };
569
570 static const enum index item_e_tag[] = {
571         ITEM_E_TAG_GRP_ECID_B,
572         ITEM_NEXT,
573         ZERO,
574 };
575
576 static const enum index item_nvgre[] = {
577         ITEM_NVGRE_TNI,
578         ITEM_NEXT,
579         ZERO,
580 };
581
582 static const enum index item_mpls[] = {
583         ITEM_MPLS_LABEL,
584         ITEM_NEXT,
585         ZERO,
586 };
587
588 static const enum index item_gre[] = {
589         ITEM_GRE_PROTO,
590         ITEM_NEXT,
591         ZERO,
592 };
593
594 static const enum index item_gtp[] = {
595         ITEM_GTP_TEID,
596         ITEM_NEXT,
597         ZERO,
598 };
599
600 static const enum index item_geneve[] = {
601         ITEM_GENEVE_VNI,
602         ITEM_GENEVE_PROTO,
603         ITEM_NEXT,
604         ZERO,
605 };
606
607 static const enum index next_action[] = {
608         ACTION_END,
609         ACTION_VOID,
610         ACTION_PASSTHRU,
611         ACTION_MARK,
612         ACTION_FLAG,
613         ACTION_QUEUE,
614         ACTION_DROP,
615         ACTION_COUNT,
616         ACTION_RSS,
617         ACTION_PF,
618         ACTION_VF,
619         ACTION_METER,
620         ZERO,
621 };
622
623 static const enum index action_mark[] = {
624         ACTION_MARK_ID,
625         ACTION_NEXT,
626         ZERO,
627 };
628
629 static const enum index action_queue[] = {
630         ACTION_QUEUE_INDEX,
631         ACTION_NEXT,
632         ZERO,
633 };
634
635 static const enum index action_rss[] = {
636         ACTION_RSS_TYPES,
637         ACTION_RSS_KEY,
638         ACTION_RSS_KEY_LEN,
639         ACTION_RSS_QUEUES,
640         ACTION_NEXT,
641         ZERO,
642 };
643
644 static const enum index action_vf[] = {
645         ACTION_VF_ORIGINAL,
646         ACTION_VF_ID,
647         ACTION_NEXT,
648         ZERO,
649 };
650
651 static const enum index action_meter[] = {
652         ACTION_METER_ID,
653         ACTION_NEXT,
654         ZERO,
655 };
656
657 static int parse_init(struct context *, const struct token *,
658                       const char *, unsigned int,
659                       void *, unsigned int);
660 static int parse_vc(struct context *, const struct token *,
661                     const char *, unsigned int,
662                     void *, unsigned int);
663 static int parse_vc_spec(struct context *, const struct token *,
664                          const char *, unsigned int, void *, unsigned int);
665 static int parse_vc_conf(struct context *, const struct token *,
666                          const char *, unsigned int, void *, unsigned int);
667 static int parse_vc_action_rss(struct context *, const struct token *,
668                                const char *, unsigned int, void *,
669                                unsigned int);
670 static int parse_vc_action_rss_type(struct context *, const struct token *,
671                                     const char *, unsigned int, void *,
672                                     unsigned int);
673 static int parse_vc_action_rss_queue(struct context *, const struct token *,
674                                      const char *, unsigned int, void *,
675                                      unsigned int);
676 static int parse_destroy(struct context *, const struct token *,
677                          const char *, unsigned int,
678                          void *, unsigned int);
679 static int parse_flush(struct context *, const struct token *,
680                        const char *, unsigned int,
681                        void *, unsigned int);
682 static int parse_query(struct context *, const struct token *,
683                        const char *, unsigned int,
684                        void *, unsigned int);
685 static int parse_action(struct context *, const struct token *,
686                         const char *, unsigned int,
687                         void *, unsigned int);
688 static int parse_list(struct context *, const struct token *,
689                       const char *, unsigned int,
690                       void *, unsigned int);
691 static int parse_isolate(struct context *, const struct token *,
692                          const char *, unsigned int,
693                          void *, unsigned int);
694 static int parse_int(struct context *, const struct token *,
695                      const char *, unsigned int,
696                      void *, unsigned int);
697 static int parse_prefix(struct context *, const struct token *,
698                         const char *, unsigned int,
699                         void *, unsigned int);
700 static int parse_boolean(struct context *, const struct token *,
701                          const char *, unsigned int,
702                          void *, unsigned int);
703 static int parse_string(struct context *, const struct token *,
704                         const char *, unsigned int,
705                         void *, unsigned int);
706 static int parse_mac_addr(struct context *, const struct token *,
707                           const char *, unsigned int,
708                           void *, unsigned int);
709 static int parse_ipv4_addr(struct context *, const struct token *,
710                            const char *, unsigned int,
711                            void *, unsigned int);
712 static int parse_ipv6_addr(struct context *, const struct token *,
713                            const char *, unsigned int,
714                            void *, unsigned int);
715 static int parse_port(struct context *, const struct token *,
716                       const char *, unsigned int,
717                       void *, unsigned int);
718 static int comp_none(struct context *, const struct token *,
719                      unsigned int, char *, unsigned int);
720 static int comp_boolean(struct context *, const struct token *,
721                         unsigned int, char *, unsigned int);
722 static int comp_action(struct context *, const struct token *,
723                        unsigned int, char *, unsigned int);
724 static int comp_port(struct context *, const struct token *,
725                      unsigned int, char *, unsigned int);
726 static int comp_rule_id(struct context *, const struct token *,
727                         unsigned int, char *, unsigned int);
728 static int comp_vc_action_rss_type(struct context *, const struct token *,
729                                    unsigned int, char *, unsigned int);
730 static int comp_vc_action_rss_queue(struct context *, const struct token *,
731                                     unsigned int, char *, unsigned int);
732
733 /** Token definitions. */
734 static const struct token token_list[] = {
735         /* Special tokens. */
736         [ZERO] = {
737                 .name = "ZERO",
738                 .help = "null entry, abused as the entry point",
739                 .next = NEXT(NEXT_ENTRY(FLOW)),
740         },
741         [END] = {
742                 .name = "",
743                 .type = "RETURN",
744                 .help = "command may end here",
745         },
746         /* Common tokens. */
747         [INTEGER] = {
748                 .name = "{int}",
749                 .type = "INTEGER",
750                 .help = "integer value",
751                 .call = parse_int,
752                 .comp = comp_none,
753         },
754         [UNSIGNED] = {
755                 .name = "{unsigned}",
756                 .type = "UNSIGNED",
757                 .help = "unsigned integer value",
758                 .call = parse_int,
759                 .comp = comp_none,
760         },
761         [PREFIX] = {
762                 .name = "{prefix}",
763                 .type = "PREFIX",
764                 .help = "prefix length for bit-mask",
765                 .call = parse_prefix,
766                 .comp = comp_none,
767         },
768         [BOOLEAN] = {
769                 .name = "{boolean}",
770                 .type = "BOOLEAN",
771                 .help = "any boolean value",
772                 .call = parse_boolean,
773                 .comp = comp_boolean,
774         },
775         [STRING] = {
776                 .name = "{string}",
777                 .type = "STRING",
778                 .help = "fixed string",
779                 .call = parse_string,
780                 .comp = comp_none,
781         },
782         [MAC_ADDR] = {
783                 .name = "{MAC address}",
784                 .type = "MAC-48",
785                 .help = "standard MAC address notation",
786                 .call = parse_mac_addr,
787                 .comp = comp_none,
788         },
789         [IPV4_ADDR] = {
790                 .name = "{IPv4 address}",
791                 .type = "IPV4 ADDRESS",
792                 .help = "standard IPv4 address notation",
793                 .call = parse_ipv4_addr,
794                 .comp = comp_none,
795         },
796         [IPV6_ADDR] = {
797                 .name = "{IPv6 address}",
798                 .type = "IPV6 ADDRESS",
799                 .help = "standard IPv6 address notation",
800                 .call = parse_ipv6_addr,
801                 .comp = comp_none,
802         },
803         [RULE_ID] = {
804                 .name = "{rule id}",
805                 .type = "RULE ID",
806                 .help = "rule identifier",
807                 .call = parse_int,
808                 .comp = comp_rule_id,
809         },
810         [PORT_ID] = {
811                 .name = "{port_id}",
812                 .type = "PORT ID",
813                 .help = "port identifier",
814                 .call = parse_port,
815                 .comp = comp_port,
816         },
817         [GROUP_ID] = {
818                 .name = "{group_id}",
819                 .type = "GROUP ID",
820                 .help = "group identifier",
821                 .call = parse_int,
822                 .comp = comp_none,
823         },
824         [PRIORITY_LEVEL] = {
825                 .name = "{level}",
826                 .type = "PRIORITY",
827                 .help = "priority level",
828                 .call = parse_int,
829                 .comp = comp_none,
830         },
831         /* Top-level command. */
832         [FLOW] = {
833                 .name = "flow",
834                 .type = "{command} {port_id} [{arg} [...]]",
835                 .help = "manage ingress/egress flow rules",
836                 .next = NEXT(NEXT_ENTRY
837                              (VALIDATE,
838                               CREATE,
839                               DESTROY,
840                               FLUSH,
841                               LIST,
842                               QUERY,
843                               ISOLATE)),
844                 .call = parse_init,
845         },
846         /* Sub-level commands. */
847         [VALIDATE] = {
848                 .name = "validate",
849                 .help = "check whether a flow rule can be created",
850                 .next = NEXT(next_vc_attr, NEXT_ENTRY(PORT_ID)),
851                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
852                 .call = parse_vc,
853         },
854         [CREATE] = {
855                 .name = "create",
856                 .help = "create a flow rule",
857                 .next = NEXT(next_vc_attr, NEXT_ENTRY(PORT_ID)),
858                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
859                 .call = parse_vc,
860         },
861         [DESTROY] = {
862                 .name = "destroy",
863                 .help = "destroy specific flow rules",
864                 .next = NEXT(NEXT_ENTRY(DESTROY_RULE), NEXT_ENTRY(PORT_ID)),
865                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
866                 .call = parse_destroy,
867         },
868         [FLUSH] = {
869                 .name = "flush",
870                 .help = "destroy all flow rules",
871                 .next = NEXT(NEXT_ENTRY(PORT_ID)),
872                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
873                 .call = parse_flush,
874         },
875         [QUERY] = {
876                 .name = "query",
877                 .help = "query an existing flow rule",
878                 .next = NEXT(NEXT_ENTRY(QUERY_ACTION),
879                              NEXT_ENTRY(RULE_ID),
880                              NEXT_ENTRY(PORT_ID)),
881                 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action),
882                              ARGS_ENTRY(struct buffer, args.query.rule),
883                              ARGS_ENTRY(struct buffer, port)),
884                 .call = parse_query,
885         },
886         [LIST] = {
887                 .name = "list",
888                 .help = "list existing flow rules",
889                 .next = NEXT(next_list_attr, NEXT_ENTRY(PORT_ID)),
890                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
891                 .call = parse_list,
892         },
893         [ISOLATE] = {
894                 .name = "isolate",
895                 .help = "restrict ingress traffic to the defined flow rules",
896                 .next = NEXT(NEXT_ENTRY(BOOLEAN),
897                              NEXT_ENTRY(PORT_ID)),
898                 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set),
899                              ARGS_ENTRY(struct buffer, port)),
900                 .call = parse_isolate,
901         },
902         /* Destroy arguments. */
903         [DESTROY_RULE] = {
904                 .name = "rule",
905                 .help = "specify a rule identifier",
906                 .next = NEXT(next_destroy_attr, NEXT_ENTRY(RULE_ID)),
907                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)),
908                 .call = parse_destroy,
909         },
910         /* Query arguments. */
911         [QUERY_ACTION] = {
912                 .name = "{action}",
913                 .type = "ACTION",
914                 .help = "action to query, must be part of the rule",
915                 .call = parse_action,
916                 .comp = comp_action,
917         },
918         /* List arguments. */
919         [LIST_GROUP] = {
920                 .name = "group",
921                 .help = "specify a group",
922                 .next = NEXT(next_list_attr, NEXT_ENTRY(GROUP_ID)),
923                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)),
924                 .call = parse_list,
925         },
926         /* Validate/create attributes. */
927         [GROUP] = {
928                 .name = "group",
929                 .help = "specify a group",
930                 .next = NEXT(next_vc_attr, NEXT_ENTRY(GROUP_ID)),
931                 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)),
932                 .call = parse_vc,
933         },
934         [PRIORITY] = {
935                 .name = "priority",
936                 .help = "specify a priority level",
937                 .next = NEXT(next_vc_attr, NEXT_ENTRY(PRIORITY_LEVEL)),
938                 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)),
939                 .call = parse_vc,
940         },
941         [INGRESS] = {
942                 .name = "ingress",
943                 .help = "affect rule to ingress",
944                 .next = NEXT(next_vc_attr),
945                 .call = parse_vc,
946         },
947         [EGRESS] = {
948                 .name = "egress",
949                 .help = "affect rule to egress",
950                 .next = NEXT(next_vc_attr),
951                 .call = parse_vc,
952         },
953         /* Validate/create pattern. */
954         [PATTERN] = {
955                 .name = "pattern",
956                 .help = "submit a list of pattern items",
957                 .next = NEXT(next_item),
958                 .call = parse_vc,
959         },
960         [ITEM_PARAM_IS] = {
961                 .name = "is",
962                 .help = "match value perfectly (with full bit-mask)",
963                 .call = parse_vc_spec,
964         },
965         [ITEM_PARAM_SPEC] = {
966                 .name = "spec",
967                 .help = "match value according to configured bit-mask",
968                 .call = parse_vc_spec,
969         },
970         [ITEM_PARAM_LAST] = {
971                 .name = "last",
972                 .help = "specify upper bound to establish a range",
973                 .call = parse_vc_spec,
974         },
975         [ITEM_PARAM_MASK] = {
976                 .name = "mask",
977                 .help = "specify bit-mask with relevant bits set to one",
978                 .call = parse_vc_spec,
979         },
980         [ITEM_PARAM_PREFIX] = {
981                 .name = "prefix",
982                 .help = "generate bit-mask from a prefix length",
983                 .call = parse_vc_spec,
984         },
985         [ITEM_NEXT] = {
986                 .name = "/",
987                 .help = "specify next pattern item",
988                 .next = NEXT(next_item),
989         },
990         [ITEM_END] = {
991                 .name = "end",
992                 .help = "end list of pattern items",
993                 .priv = PRIV_ITEM(END, 0),
994                 .next = NEXT(NEXT_ENTRY(ACTIONS)),
995                 .call = parse_vc,
996         },
997         [ITEM_VOID] = {
998                 .name = "void",
999                 .help = "no-op pattern item",
1000                 .priv = PRIV_ITEM(VOID, 0),
1001                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
1002                 .call = parse_vc,
1003         },
1004         [ITEM_INVERT] = {
1005                 .name = "invert",
1006                 .help = "perform actions when pattern does not match",
1007                 .priv = PRIV_ITEM(INVERT, 0),
1008                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
1009                 .call = parse_vc,
1010         },
1011         [ITEM_ANY] = {
1012                 .name = "any",
1013                 .help = "match any protocol for the current layer",
1014                 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)),
1015                 .next = NEXT(item_any),
1016                 .call = parse_vc,
1017         },
1018         [ITEM_ANY_NUM] = {
1019                 .name = "num",
1020                 .help = "number of layers covered",
1021                 .next = NEXT(item_any, NEXT_ENTRY(UNSIGNED), item_param),
1022                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)),
1023         },
1024         [ITEM_PF] = {
1025                 .name = "pf",
1026                 .help = "match packets addressed to the physical function",
1027                 .priv = PRIV_ITEM(PF, 0),
1028                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
1029                 .call = parse_vc,
1030         },
1031         [ITEM_VF] = {
1032                 .name = "vf",
1033                 .help = "match packets addressed to a virtual function ID",
1034                 .priv = PRIV_ITEM(VF, sizeof(struct rte_flow_item_vf)),
1035                 .next = NEXT(item_vf),
1036                 .call = parse_vc,
1037         },
1038         [ITEM_VF_ID] = {
1039                 .name = "id",
1040                 .help = "destination VF ID",
1041                 .next = NEXT(item_vf, NEXT_ENTRY(UNSIGNED), item_param),
1042                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_vf, id)),
1043         },
1044         [ITEM_PORT] = {
1045                 .name = "port",
1046                 .help = "device-specific physical port index to use",
1047                 .priv = PRIV_ITEM(PORT, sizeof(struct rte_flow_item_port)),
1048                 .next = NEXT(item_port),
1049                 .call = parse_vc,
1050         },
1051         [ITEM_PORT_INDEX] = {
1052                 .name = "index",
1053                 .help = "physical port index",
1054                 .next = NEXT(item_port, NEXT_ENTRY(UNSIGNED), item_param),
1055                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port, index)),
1056         },
1057         [ITEM_RAW] = {
1058                 .name = "raw",
1059                 .help = "match an arbitrary byte string",
1060                 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE),
1061                 .next = NEXT(item_raw),
1062                 .call = parse_vc,
1063         },
1064         [ITEM_RAW_RELATIVE] = {
1065                 .name = "relative",
1066                 .help = "look for pattern after the previous item",
1067                 .next = NEXT(item_raw, NEXT_ENTRY(BOOLEAN), item_param),
1068                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
1069                                            relative, 1)),
1070         },
1071         [ITEM_RAW_SEARCH] = {
1072                 .name = "search",
1073                 .help = "search pattern from offset (see also limit)",
1074                 .next = NEXT(item_raw, NEXT_ENTRY(BOOLEAN), item_param),
1075                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
1076                                            search, 1)),
1077         },
1078         [ITEM_RAW_OFFSET] = {
1079                 .name = "offset",
1080                 .help = "absolute or relative offset for pattern",
1081                 .next = NEXT(item_raw, NEXT_ENTRY(INTEGER), item_param),
1082                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)),
1083         },
1084         [ITEM_RAW_LIMIT] = {
1085                 .name = "limit",
1086                 .help = "search area limit for start of pattern",
1087                 .next = NEXT(item_raw, NEXT_ENTRY(UNSIGNED), item_param),
1088                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)),
1089         },
1090         [ITEM_RAW_PATTERN] = {
1091                 .name = "pattern",
1092                 .help = "byte string to look for",
1093                 .next = NEXT(item_raw,
1094                              NEXT_ENTRY(STRING),
1095                              NEXT_ENTRY(ITEM_PARAM_IS,
1096                                         ITEM_PARAM_SPEC,
1097                                         ITEM_PARAM_MASK)),
1098                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern),
1099                              ARGS_ENTRY(struct rte_flow_item_raw, length),
1100                              ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw),
1101                                             ITEM_RAW_PATTERN_SIZE)),
1102         },
1103         [ITEM_ETH] = {
1104                 .name = "eth",
1105                 .help = "match Ethernet header",
1106                 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
1107                 .next = NEXT(item_eth),
1108                 .call = parse_vc,
1109         },
1110         [ITEM_ETH_DST] = {
1111                 .name = "dst",
1112                 .help = "destination MAC",
1113                 .next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param),
1114                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, dst)),
1115         },
1116         [ITEM_ETH_SRC] = {
1117                 .name = "src",
1118                 .help = "source MAC",
1119                 .next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param),
1120                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, src)),
1121         },
1122         [ITEM_ETH_TYPE] = {
1123                 .name = "type",
1124                 .help = "EtherType",
1125                 .next = NEXT(item_eth, NEXT_ENTRY(UNSIGNED), item_param),
1126                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, type)),
1127         },
1128         [ITEM_VLAN] = {
1129                 .name = "vlan",
1130                 .help = "match 802.1Q/ad VLAN tag",
1131                 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
1132                 .next = NEXT(item_vlan),
1133                 .call = parse_vc,
1134         },
1135         [ITEM_VLAN_TPID] = {
1136                 .name = "tpid",
1137                 .help = "tag protocol identifier",
1138                 .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1139                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tpid)),
1140         },
1141         [ITEM_VLAN_TCI] = {
1142                 .name = "tci",
1143                 .help = "tag control information",
1144                 .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1145                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)),
1146         },
1147         [ITEM_VLAN_PCP] = {
1148                 .name = "pcp",
1149                 .help = "priority code point",
1150                 .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1151                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
1152                                                   tci, "\xe0\x00")),
1153         },
1154         [ITEM_VLAN_DEI] = {
1155                 .name = "dei",
1156                 .help = "drop eligible indicator",
1157                 .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1158                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
1159                                                   tci, "\x10\x00")),
1160         },
1161         [ITEM_VLAN_VID] = {
1162                 .name = "vid",
1163                 .help = "VLAN identifier",
1164                 .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
1165                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
1166                                                   tci, "\x0f\xff")),
1167         },
1168         [ITEM_IPV4] = {
1169                 .name = "ipv4",
1170                 .help = "match IPv4 header",
1171                 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
1172                 .next = NEXT(item_ipv4),
1173                 .call = parse_vc,
1174         },
1175         [ITEM_IPV4_TOS] = {
1176                 .name = "tos",
1177                 .help = "type of service",
1178                 .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
1179                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
1180                                              hdr.type_of_service)),
1181         },
1182         [ITEM_IPV4_TTL] = {
1183                 .name = "ttl",
1184                 .help = "time to live",
1185                 .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
1186                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
1187                                              hdr.time_to_live)),
1188         },
1189         [ITEM_IPV4_PROTO] = {
1190                 .name = "proto",
1191                 .help = "next protocol ID",
1192                 .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
1193                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
1194                                              hdr.next_proto_id)),
1195         },
1196         [ITEM_IPV4_SRC] = {
1197                 .name = "src",
1198                 .help = "source address",
1199                 .next = NEXT(item_ipv4, NEXT_ENTRY(IPV4_ADDR), item_param),
1200                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
1201                                              hdr.src_addr)),
1202         },
1203         [ITEM_IPV4_DST] = {
1204                 .name = "dst",
1205                 .help = "destination address",
1206                 .next = NEXT(item_ipv4, NEXT_ENTRY(IPV4_ADDR), item_param),
1207                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
1208                                              hdr.dst_addr)),
1209         },
1210         [ITEM_IPV6] = {
1211                 .name = "ipv6",
1212                 .help = "match IPv6 header",
1213                 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
1214                 .next = NEXT(item_ipv6),
1215                 .call = parse_vc,
1216         },
1217         [ITEM_IPV6_TC] = {
1218                 .name = "tc",
1219                 .help = "traffic class",
1220                 .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
1221                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
1222                                                   hdr.vtc_flow,
1223                                                   "\x0f\xf0\x00\x00")),
1224         },
1225         [ITEM_IPV6_FLOW] = {
1226                 .name = "flow",
1227                 .help = "flow label",
1228                 .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
1229                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
1230                                                   hdr.vtc_flow,
1231                                                   "\x00\x0f\xff\xff")),
1232         },
1233         [ITEM_IPV6_PROTO] = {
1234                 .name = "proto",
1235                 .help = "protocol (next header)",
1236                 .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
1237                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
1238                                              hdr.proto)),
1239         },
1240         [ITEM_IPV6_HOP] = {
1241                 .name = "hop",
1242                 .help = "hop limit",
1243                 .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
1244                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
1245                                              hdr.hop_limits)),
1246         },
1247         [ITEM_IPV6_SRC] = {
1248                 .name = "src",
1249                 .help = "source address",
1250                 .next = NEXT(item_ipv6, NEXT_ENTRY(IPV6_ADDR), item_param),
1251                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
1252                                              hdr.src_addr)),
1253         },
1254         [ITEM_IPV6_DST] = {
1255                 .name = "dst",
1256                 .help = "destination address",
1257                 .next = NEXT(item_ipv6, NEXT_ENTRY(IPV6_ADDR), item_param),
1258                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
1259                                              hdr.dst_addr)),
1260         },
1261         [ITEM_ICMP] = {
1262                 .name = "icmp",
1263                 .help = "match ICMP header",
1264                 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
1265                 .next = NEXT(item_icmp),
1266                 .call = parse_vc,
1267         },
1268         [ITEM_ICMP_TYPE] = {
1269                 .name = "type",
1270                 .help = "ICMP packet type",
1271                 .next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
1272                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
1273                                              hdr.icmp_type)),
1274         },
1275         [ITEM_ICMP_CODE] = {
1276                 .name = "code",
1277                 .help = "ICMP packet code",
1278                 .next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
1279                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
1280                                              hdr.icmp_code)),
1281         },
1282         [ITEM_UDP] = {
1283                 .name = "udp",
1284                 .help = "match UDP header",
1285                 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
1286                 .next = NEXT(item_udp),
1287                 .call = parse_vc,
1288         },
1289         [ITEM_UDP_SRC] = {
1290                 .name = "src",
1291                 .help = "UDP source port",
1292                 .next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
1293                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
1294                                              hdr.src_port)),
1295         },
1296         [ITEM_UDP_DST] = {
1297                 .name = "dst",
1298                 .help = "UDP destination port",
1299                 .next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
1300                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
1301                                              hdr.dst_port)),
1302         },
1303         [ITEM_TCP] = {
1304                 .name = "tcp",
1305                 .help = "match TCP header",
1306                 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
1307                 .next = NEXT(item_tcp),
1308                 .call = parse_vc,
1309         },
1310         [ITEM_TCP_SRC] = {
1311                 .name = "src",
1312                 .help = "TCP source port",
1313                 .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
1314                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
1315                                              hdr.src_port)),
1316         },
1317         [ITEM_TCP_DST] = {
1318                 .name = "dst",
1319                 .help = "TCP destination port",
1320                 .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
1321                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
1322                                              hdr.dst_port)),
1323         },
1324         [ITEM_TCP_FLAGS] = {
1325                 .name = "flags",
1326                 .help = "TCP flags",
1327                 .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
1328                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
1329                                              hdr.tcp_flags)),
1330         },
1331         [ITEM_SCTP] = {
1332                 .name = "sctp",
1333                 .help = "match SCTP header",
1334                 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
1335                 .next = NEXT(item_sctp),
1336                 .call = parse_vc,
1337         },
1338         [ITEM_SCTP_SRC] = {
1339                 .name = "src",
1340                 .help = "SCTP source port",
1341                 .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
1342                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
1343                                              hdr.src_port)),
1344         },
1345         [ITEM_SCTP_DST] = {
1346                 .name = "dst",
1347                 .help = "SCTP destination port",
1348                 .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
1349                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
1350                                              hdr.dst_port)),
1351         },
1352         [ITEM_SCTP_TAG] = {
1353                 .name = "tag",
1354                 .help = "validation tag",
1355                 .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
1356                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
1357                                              hdr.tag)),
1358         },
1359         [ITEM_SCTP_CKSUM] = {
1360                 .name = "cksum",
1361                 .help = "checksum",
1362                 .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
1363                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
1364                                              hdr.cksum)),
1365         },
1366         [ITEM_VXLAN] = {
1367                 .name = "vxlan",
1368                 .help = "match VXLAN header",
1369                 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
1370                 .next = NEXT(item_vxlan),
1371                 .call = parse_vc,
1372         },
1373         [ITEM_VXLAN_VNI] = {
1374                 .name = "vni",
1375                 .help = "VXLAN identifier",
1376                 .next = NEXT(item_vxlan, NEXT_ENTRY(UNSIGNED), item_param),
1377                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)),
1378         },
1379         [ITEM_E_TAG] = {
1380                 .name = "e_tag",
1381                 .help = "match E-Tag header",
1382                 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
1383                 .next = NEXT(item_e_tag),
1384                 .call = parse_vc,
1385         },
1386         [ITEM_E_TAG_GRP_ECID_B] = {
1387                 .name = "grp_ecid_b",
1388                 .help = "GRP and E-CID base",
1389                 .next = NEXT(item_e_tag, NEXT_ENTRY(UNSIGNED), item_param),
1390                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag,
1391                                                   rsvd_grp_ecid_b,
1392                                                   "\x3f\xff")),
1393         },
1394         [ITEM_NVGRE] = {
1395                 .name = "nvgre",
1396                 .help = "match NVGRE header",
1397                 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
1398                 .next = NEXT(item_nvgre),
1399                 .call = parse_vc,
1400         },
1401         [ITEM_NVGRE_TNI] = {
1402                 .name = "tni",
1403                 .help = "virtual subnet ID",
1404                 .next = NEXT(item_nvgre, NEXT_ENTRY(UNSIGNED), item_param),
1405                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)),
1406         },
1407         [ITEM_MPLS] = {
1408                 .name = "mpls",
1409                 .help = "match MPLS header",
1410                 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
1411                 .next = NEXT(item_mpls),
1412                 .call = parse_vc,
1413         },
1414         [ITEM_MPLS_LABEL] = {
1415                 .name = "label",
1416                 .help = "MPLS label",
1417                 .next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param),
1418                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
1419                                                   label_tc_s,
1420                                                   "\xff\xff\xf0")),
1421         },
1422         [ITEM_GRE] = {
1423                 .name = "gre",
1424                 .help = "match GRE header",
1425                 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
1426                 .next = NEXT(item_gre),
1427                 .call = parse_vc,
1428         },
1429         [ITEM_GRE_PROTO] = {
1430                 .name = "protocol",
1431                 .help = "GRE protocol type",
1432                 .next = NEXT(item_gre, NEXT_ENTRY(UNSIGNED), item_param),
1433                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
1434                                              protocol)),
1435         },
1436         [ITEM_FUZZY] = {
1437                 .name = "fuzzy",
1438                 .help = "fuzzy pattern match, expect faster than default",
1439                 .priv = PRIV_ITEM(FUZZY,
1440                                 sizeof(struct rte_flow_item_fuzzy)),
1441                 .next = NEXT(item_fuzzy),
1442                 .call = parse_vc,
1443         },
1444         [ITEM_FUZZY_THRESH] = {
1445                 .name = "thresh",
1446                 .help = "match accuracy threshold",
1447                 .next = NEXT(item_fuzzy, NEXT_ENTRY(UNSIGNED), item_param),
1448                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy,
1449                                         thresh)),
1450         },
1451         [ITEM_GTP] = {
1452                 .name = "gtp",
1453                 .help = "match GTP header",
1454                 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)),
1455                 .next = NEXT(item_gtp),
1456                 .call = parse_vc,
1457         },
1458         [ITEM_GTP_TEID] = {
1459                 .name = "teid",
1460                 .help = "tunnel endpoint identifier",
1461                 .next = NEXT(item_gtp, NEXT_ENTRY(UNSIGNED), item_param),
1462                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, teid)),
1463         },
1464         [ITEM_GTPC] = {
1465                 .name = "gtpc",
1466                 .help = "match GTP header",
1467                 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
1468                 .next = NEXT(item_gtp),
1469                 .call = parse_vc,
1470         },
1471         [ITEM_GTPU] = {
1472                 .name = "gtpu",
1473                 .help = "match GTP header",
1474                 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)),
1475                 .next = NEXT(item_gtp),
1476                 .call = parse_vc,
1477         },
1478         [ITEM_GENEVE] = {
1479                 .name = "geneve",
1480                 .help = "match GENEVE header",
1481                 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
1482                 .next = NEXT(item_geneve),
1483                 .call = parse_vc,
1484         },
1485         [ITEM_GENEVE_VNI] = {
1486                 .name = "vni",
1487                 .help = "virtual network identifier",
1488                 .next = NEXT(item_geneve, NEXT_ENTRY(UNSIGNED), item_param),
1489                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)),
1490         },
1491         [ITEM_GENEVE_PROTO] = {
1492                 .name = "protocol",
1493                 .help = "GENEVE protocol type",
1494                 .next = NEXT(item_geneve, NEXT_ENTRY(UNSIGNED), item_param),
1495                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve,
1496                                              protocol)),
1497         },
1498
1499         /* Validate/create actions. */
1500         [ACTIONS] = {
1501                 .name = "actions",
1502                 .help = "submit a list of associated actions",
1503                 .next = NEXT(next_action),
1504                 .call = parse_vc,
1505         },
1506         [ACTION_NEXT] = {
1507                 .name = "/",
1508                 .help = "specify next action",
1509                 .next = NEXT(next_action),
1510         },
1511         [ACTION_END] = {
1512                 .name = "end",
1513                 .help = "end list of actions",
1514                 .priv = PRIV_ACTION(END, 0),
1515                 .call = parse_vc,
1516         },
1517         [ACTION_VOID] = {
1518                 .name = "void",
1519                 .help = "no-op action",
1520                 .priv = PRIV_ACTION(VOID, 0),
1521                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
1522                 .call = parse_vc,
1523         },
1524         [ACTION_PASSTHRU] = {
1525                 .name = "passthru",
1526                 .help = "let subsequent rule process matched packets",
1527                 .priv = PRIV_ACTION(PASSTHRU, 0),
1528                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
1529                 .call = parse_vc,
1530         },
1531         [ACTION_MARK] = {
1532                 .name = "mark",
1533                 .help = "attach 32 bit value to packets",
1534                 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
1535                 .next = NEXT(action_mark),
1536                 .call = parse_vc,
1537         },
1538         [ACTION_MARK_ID] = {
1539                 .name = "id",
1540                 .help = "32 bit value to return with packets",
1541                 .next = NEXT(action_mark, NEXT_ENTRY(UNSIGNED)),
1542                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)),
1543                 .call = parse_vc_conf,
1544         },
1545         [ACTION_FLAG] = {
1546                 .name = "flag",
1547                 .help = "flag packets",
1548                 .priv = PRIV_ACTION(FLAG, 0),
1549                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
1550                 .call = parse_vc,
1551         },
1552         [ACTION_QUEUE] = {
1553                 .name = "queue",
1554                 .help = "assign packets to a given queue index",
1555                 .priv = PRIV_ACTION(QUEUE,
1556                                     sizeof(struct rte_flow_action_queue)),
1557                 .next = NEXT(action_queue),
1558                 .call = parse_vc,
1559         },
1560         [ACTION_QUEUE_INDEX] = {
1561                 .name = "index",
1562                 .help = "queue index to use",
1563                 .next = NEXT(action_queue, NEXT_ENTRY(UNSIGNED)),
1564                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
1565                 .call = parse_vc_conf,
1566         },
1567         [ACTION_DROP] = {
1568                 .name = "drop",
1569                 .help = "drop packets (note: passthru has priority)",
1570                 .priv = PRIV_ACTION(DROP, 0),
1571                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
1572                 .call = parse_vc,
1573         },
1574         [ACTION_COUNT] = {
1575                 .name = "count",
1576                 .help = "enable counters for this rule",
1577                 .priv = PRIV_ACTION(COUNT, 0),
1578                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
1579                 .call = parse_vc,
1580         },
1581         [ACTION_RSS] = {
1582                 .name = "rss",
1583                 .help = "spread packets among several queues",
1584                 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)),
1585                 .next = NEXT(action_rss),
1586                 .call = parse_vc_action_rss,
1587         },
1588         [ACTION_RSS_TYPES] = {
1589                 .name = "types",
1590                 .help = "RSS hash types",
1591                 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)),
1592         },
1593         [ACTION_RSS_TYPE] = {
1594                 .name = "{type}",
1595                 .help = "RSS hash type",
1596                 .call = parse_vc_action_rss_type,
1597                 .comp = comp_vc_action_rss_type,
1598         },
1599         [ACTION_RSS_KEY] = {
1600                 .name = "key",
1601                 .help = "RSS hash key",
1602                 .next = NEXT(action_rss, NEXT_ENTRY(STRING)),
1603                 .args = ARGS(ARGS_ENTRY_ARB(0, 0),
1604                              ARGS_ENTRY_ARB
1605                              (offsetof(struct action_rss_data, rss_conf) +
1606                               offsetof(struct rte_eth_rss_conf, rss_key_len),
1607                               sizeof(((struct rte_eth_rss_conf *)0)->
1608                                      rss_key_len)),
1609                              ARGS_ENTRY(struct action_rss_data, rss_key)),
1610         },
1611         [ACTION_RSS_KEY_LEN] = {
1612                 .name = "key_len",
1613                 .help = "RSS hash key length in bytes",
1614                 .next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
1615                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
1616                              (offsetof(struct action_rss_data, rss_conf) +
1617                               offsetof(struct rte_eth_rss_conf, rss_key_len),
1618                               sizeof(((struct rte_eth_rss_conf *)0)->
1619                                      rss_key_len),
1620                               0,
1621                               RSS_HASH_KEY_LENGTH)),
1622         },
1623         [ACTION_RSS_QUEUES] = {
1624                 .name = "queues",
1625                 .help = "queue indices to use",
1626                 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)),
1627                 .call = parse_vc_conf,
1628         },
1629         [ACTION_RSS_QUEUE] = {
1630                 .name = "{queue}",
1631                 .help = "queue index",
1632                 .call = parse_vc_action_rss_queue,
1633                 .comp = comp_vc_action_rss_queue,
1634         },
1635         [ACTION_PF] = {
1636                 .name = "pf",
1637                 .help = "redirect packets to physical device function",
1638                 .priv = PRIV_ACTION(PF, 0),
1639                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
1640                 .call = parse_vc,
1641         },
1642         [ACTION_VF] = {
1643                 .name = "vf",
1644                 .help = "redirect packets to virtual device function",
1645                 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)),
1646                 .next = NEXT(action_vf),
1647                 .call = parse_vc,
1648         },
1649         [ACTION_VF_ORIGINAL] = {
1650                 .name = "original",
1651                 .help = "use original VF ID if possible",
1652                 .next = NEXT(action_vf, NEXT_ENTRY(BOOLEAN)),
1653                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf,
1654                                            original, 1)),
1655                 .call = parse_vc_conf,
1656         },
1657         [ACTION_VF_ID] = {
1658                 .name = "id",
1659                 .help = "VF ID to redirect packets to",
1660                 .next = NEXT(action_vf, NEXT_ENTRY(UNSIGNED)),
1661                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)),
1662                 .call = parse_vc_conf,
1663         },
1664         [ACTION_METER] = {
1665                 .name = "meter",
1666                 .help = "meter the directed packets at given id",
1667                 .priv = PRIV_ACTION(METER,
1668                                     sizeof(struct rte_flow_action_meter)),
1669                 .next = NEXT(action_meter),
1670                 .call = parse_vc,
1671         },
1672         [ACTION_METER_ID] = {
1673                 .name = "mtr_id",
1674                 .help = "meter id to use",
1675                 .next = NEXT(action_meter, NEXT_ENTRY(UNSIGNED)),
1676                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)),
1677                 .call = parse_vc_conf,
1678         },
1679 };
1680
1681 /** Remove and return last entry from argument stack. */
1682 static const struct arg *
1683 pop_args(struct context *ctx)
1684 {
1685         return ctx->args_num ? ctx->args[--ctx->args_num] : NULL;
1686 }
1687
1688 /** Add entry on top of the argument stack. */
1689 static int
1690 push_args(struct context *ctx, const struct arg *arg)
1691 {
1692         if (ctx->args_num == CTX_STACK_SIZE)
1693                 return -1;
1694         ctx->args[ctx->args_num++] = arg;
1695         return 0;
1696 }
1697
1698 /** Spread value into buffer according to bit-mask. */
1699 static size_t
1700 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg)
1701 {
1702         uint32_t i = arg->size;
1703         uint32_t end = 0;
1704         int sub = 1;
1705         int add = 0;
1706         size_t len = 0;
1707
1708         if (!arg->mask)
1709                 return 0;
1710 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
1711         if (!arg->hton) {
1712                 i = 0;
1713                 end = arg->size;
1714                 sub = 0;
1715                 add = 1;
1716         }
1717 #endif
1718         while (i != end) {
1719                 unsigned int shift = 0;
1720                 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub);
1721
1722                 for (shift = 0; arg->mask[i] >> shift; ++shift) {
1723                         if (!(arg->mask[i] & (1 << shift)))
1724                                 continue;
1725                         ++len;
1726                         if (!dst)
1727                                 continue;
1728                         *buf &= ~(1 << shift);
1729                         *buf |= (val & 1) << shift;
1730                         val >>= 1;
1731                 }
1732                 i += add;
1733         }
1734         return len;
1735 }
1736
1737 /** Compare a string with a partial one of a given length. */
1738 static int
1739 strcmp_partial(const char *full, const char *partial, size_t partial_len)
1740 {
1741         int r = strncmp(full, partial, partial_len);
1742
1743         if (r)
1744                 return r;
1745         if (strlen(full) <= partial_len)
1746                 return 0;
1747         return full[partial_len];
1748 }
1749
1750 /**
1751  * Parse a prefix length and generate a bit-mask.
1752  *
1753  * Last argument (ctx->args) is retrieved to determine mask size, storage
1754  * location and whether the result must use network byte ordering.
1755  */
1756 static int
1757 parse_prefix(struct context *ctx, const struct token *token,
1758              const char *str, unsigned int len,
1759              void *buf, unsigned int size)
1760 {
1761         const struct arg *arg = pop_args(ctx);
1762         static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff";
1763         char *end;
1764         uintmax_t u;
1765         unsigned int bytes;
1766         unsigned int extra;
1767
1768         (void)token;
1769         /* Argument is expected. */
1770         if (!arg)
1771                 return -1;
1772         errno = 0;
1773         u = strtoumax(str, &end, 0);
1774         if (errno || (size_t)(end - str) != len)
1775                 goto error;
1776         if (arg->mask) {
1777                 uintmax_t v = 0;
1778
1779                 extra = arg_entry_bf_fill(NULL, 0, arg);
1780                 if (u > extra)
1781                         goto error;
1782                 if (!ctx->object)
1783                         return len;
1784                 extra -= u;
1785                 while (u--)
1786                         (v <<= 1, v |= 1);
1787                 v <<= extra;
1788                 if (!arg_entry_bf_fill(ctx->object, v, arg) ||
1789                     !arg_entry_bf_fill(ctx->objmask, -1, arg))
1790                         goto error;
1791                 return len;
1792         }
1793         bytes = u / 8;
1794         extra = u % 8;
1795         size = arg->size;
1796         if (bytes > size || bytes + !!extra > size)
1797                 goto error;
1798         if (!ctx->object)
1799                 return len;
1800         buf = (uint8_t *)ctx->object + arg->offset;
1801 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
1802         if (!arg->hton) {
1803                 memset((uint8_t *)buf + size - bytes, 0xff, bytes);
1804                 memset(buf, 0x00, size - bytes);
1805                 if (extra)
1806                         ((uint8_t *)buf)[size - bytes - 1] = conv[extra];
1807         } else
1808 #endif
1809         {
1810                 memset(buf, 0xff, bytes);
1811                 memset((uint8_t *)buf + bytes, 0x00, size - bytes);
1812                 if (extra)
1813                         ((uint8_t *)buf)[bytes] = conv[extra];
1814         }
1815         if (ctx->objmask)
1816                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
1817         return len;
1818 error:
1819         push_args(ctx, arg);
1820         return -1;
1821 }
1822
1823 /** Default parsing function for token name matching. */
1824 static int
1825 parse_default(struct context *ctx, const struct token *token,
1826               const char *str, unsigned int len,
1827               void *buf, unsigned int size)
1828 {
1829         (void)ctx;
1830         (void)buf;
1831         (void)size;
1832         if (strcmp_partial(token->name, str, len))
1833                 return -1;
1834         return len;
1835 }
1836
1837 /** Parse flow command, initialize output buffer for subsequent tokens. */
1838 static int
1839 parse_init(struct context *ctx, const struct token *token,
1840            const char *str, unsigned int len,
1841            void *buf, unsigned int size)
1842 {
1843         struct buffer *out = buf;
1844
1845         /* Token name must match. */
1846         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
1847                 return -1;
1848         /* Nothing else to do if there is no buffer. */
1849         if (!out)
1850                 return len;
1851         /* Make sure buffer is large enough. */
1852         if (size < sizeof(*out))
1853                 return -1;
1854         /* Initialize buffer. */
1855         memset(out, 0x00, sizeof(*out));
1856         memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out));
1857         ctx->objdata = 0;
1858         ctx->object = out;
1859         ctx->objmask = NULL;
1860         return len;
1861 }
1862
1863 /** Parse tokens for validate/create commands. */
1864 static int
1865 parse_vc(struct context *ctx, const struct token *token,
1866          const char *str, unsigned int len,
1867          void *buf, unsigned int size)
1868 {
1869         struct buffer *out = buf;
1870         uint8_t *data;
1871         uint32_t data_size;
1872
1873         /* Token name must match. */
1874         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
1875                 return -1;
1876         /* Nothing else to do if there is no buffer. */
1877         if (!out)
1878                 return len;
1879         if (!out->command) {
1880                 if (ctx->curr != VALIDATE && ctx->curr != CREATE)
1881                         return -1;
1882                 if (sizeof(*out) > size)
1883                         return -1;
1884                 out->command = ctx->curr;
1885                 ctx->objdata = 0;
1886                 ctx->object = out;
1887                 ctx->objmask = NULL;
1888                 out->args.vc.data = (uint8_t *)out + size;
1889                 return len;
1890         }
1891         ctx->objdata = 0;
1892         ctx->object = &out->args.vc.attr;
1893         ctx->objmask = NULL;
1894         switch (ctx->curr) {
1895         case GROUP:
1896         case PRIORITY:
1897                 return len;
1898         case INGRESS:
1899                 out->args.vc.attr.ingress = 1;
1900                 return len;
1901         case EGRESS:
1902                 out->args.vc.attr.egress = 1;
1903                 return len;
1904         case PATTERN:
1905                 out->args.vc.pattern =
1906                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
1907                                                sizeof(double));
1908                 ctx->object = out->args.vc.pattern;
1909                 ctx->objmask = NULL;
1910                 return len;
1911         case ACTIONS:
1912                 out->args.vc.actions =
1913                         (void *)RTE_ALIGN_CEIL((uintptr_t)
1914                                                (out->args.vc.pattern +
1915                                                 out->args.vc.pattern_n),
1916                                                sizeof(double));
1917                 ctx->object = out->args.vc.actions;
1918                 ctx->objmask = NULL;
1919                 return len;
1920         default:
1921                 if (!token->priv)
1922                         return -1;
1923                 break;
1924         }
1925         if (!out->args.vc.actions) {
1926                 const struct parse_item_priv *priv = token->priv;
1927                 struct rte_flow_item *item =
1928                         out->args.vc.pattern + out->args.vc.pattern_n;
1929
1930                 data_size = priv->size * 3; /* spec, last, mask */
1931                 data = (void *)RTE_ALIGN_FLOOR((uintptr_t)
1932                                                (out->args.vc.data - data_size),
1933                                                sizeof(double));
1934                 if ((uint8_t *)item + sizeof(*item) > data)
1935                         return -1;
1936                 *item = (struct rte_flow_item){
1937                         .type = priv->type,
1938                 };
1939                 ++out->args.vc.pattern_n;
1940                 ctx->object = item;
1941                 ctx->objmask = NULL;
1942         } else {
1943                 const struct parse_action_priv *priv = token->priv;
1944                 struct rte_flow_action *action =
1945                         out->args.vc.actions + out->args.vc.actions_n;
1946
1947                 data_size = priv->size; /* configuration */
1948                 data = (void *)RTE_ALIGN_FLOOR((uintptr_t)
1949                                                (out->args.vc.data - data_size),
1950                                                sizeof(double));
1951                 if ((uint8_t *)action + sizeof(*action) > data)
1952                         return -1;
1953                 *action = (struct rte_flow_action){
1954                         .type = priv->type,
1955                         .conf = data_size ? data : NULL,
1956                 };
1957                 ++out->args.vc.actions_n;
1958                 ctx->object = action;
1959                 ctx->objmask = NULL;
1960         }
1961         memset(data, 0, data_size);
1962         out->args.vc.data = data;
1963         ctx->objdata = data_size;
1964         return len;
1965 }
1966
1967 /** Parse pattern item parameter type. */
1968 static int
1969 parse_vc_spec(struct context *ctx, const struct token *token,
1970               const char *str, unsigned int len,
1971               void *buf, unsigned int size)
1972 {
1973         struct buffer *out = buf;
1974         struct rte_flow_item *item;
1975         uint32_t data_size;
1976         int index;
1977         int objmask = 0;
1978
1979         (void)size;
1980         /* Token name must match. */
1981         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
1982                 return -1;
1983         /* Parse parameter types. */
1984         switch (ctx->curr) {
1985                 static const enum index prefix[] = NEXT_ENTRY(PREFIX);
1986
1987         case ITEM_PARAM_IS:
1988                 index = 0;
1989                 objmask = 1;
1990                 break;
1991         case ITEM_PARAM_SPEC:
1992                 index = 0;
1993                 break;
1994         case ITEM_PARAM_LAST:
1995                 index = 1;
1996                 break;
1997         case ITEM_PARAM_PREFIX:
1998                 /* Modify next token to expect a prefix. */
1999                 if (ctx->next_num < 2)
2000                         return -1;
2001                 ctx->next[ctx->next_num - 2] = prefix;
2002                 /* Fall through. */
2003         case ITEM_PARAM_MASK:
2004                 index = 2;
2005                 break;
2006         default:
2007                 return -1;
2008         }
2009         /* Nothing else to do if there is no buffer. */
2010         if (!out)
2011                 return len;
2012         if (!out->args.vc.pattern_n)
2013                 return -1;
2014         item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
2015         data_size = ctx->objdata / 3; /* spec, last, mask */
2016         /* Point to selected object. */
2017         ctx->object = out->args.vc.data + (data_size * index);
2018         if (objmask) {
2019                 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */
2020                 item->mask = ctx->objmask;
2021         } else
2022                 ctx->objmask = NULL;
2023         /* Update relevant item pointer. */
2024         *((const void **[]){ &item->spec, &item->last, &item->mask })[index] =
2025                 ctx->object;
2026         return len;
2027 }
2028
2029 /** Parse action configuration field. */
2030 static int
2031 parse_vc_conf(struct context *ctx, const struct token *token,
2032               const char *str, unsigned int len,
2033               void *buf, unsigned int size)
2034 {
2035         struct buffer *out = buf;
2036
2037         (void)size;
2038         /* Token name must match. */
2039         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
2040                 return -1;
2041         /* Nothing else to do if there is no buffer. */
2042         if (!out)
2043                 return len;
2044         /* Point to selected object. */
2045         ctx->object = out->args.vc.data;
2046         ctx->objmask = NULL;
2047         return len;
2048 }
2049
2050 /** Parse RSS action. */
2051 static int
2052 parse_vc_action_rss(struct context *ctx, const struct token *token,
2053                     const char *str, unsigned int len,
2054                     void *buf, unsigned int size)
2055 {
2056         struct buffer *out = buf;
2057         struct rte_flow_action *action;
2058         struct action_rss_data *action_rss_data;
2059         unsigned int i;
2060         int ret;
2061
2062         ret = parse_vc(ctx, token, str, len, buf, size);
2063         if (ret < 0)
2064                 return ret;
2065         /* Nothing else to do if there is no buffer. */
2066         if (!out)
2067                 return ret;
2068         if (!out->args.vc.actions_n)
2069                 return -1;
2070         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
2071         /* Point to selected object. */
2072         ctx->object = out->args.vc.data;
2073         ctx->objmask = NULL;
2074         /* Set up default configuration. */
2075         action_rss_data = ctx->object;
2076         *action_rss_data = (struct action_rss_data){
2077                 .conf = (struct rte_flow_action_rss){
2078                         .rss_conf = &action_rss_data->rss_conf,
2079                         .num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
2080                         .queue = action_rss_data->queue,
2081                 },
2082                 .queue = { 0 },
2083                 .rss_conf = (struct rte_eth_rss_conf){
2084                         .rss_key = action_rss_data->rss_key,
2085                         .rss_key_len = sizeof(action_rss_data->rss_key),
2086                         .rss_hf = rss_hf,
2087                 },
2088                 .rss_key = "testpmd's default RSS hash key",
2089         };
2090         for (i = 0; i < action_rss_data->conf.num; ++i)
2091                 action_rss_data->queue[i] = i;
2092         if (!port_id_is_invalid(ctx->port, DISABLED_WARN) &&
2093             ctx->port != (portid_t)RTE_PORT_ALL) {
2094                 struct rte_eth_dev_info info;
2095
2096                 rte_eth_dev_info_get(ctx->port, &info);
2097                 action_rss_data->rss_conf.rss_key_len =
2098                         RTE_MIN(sizeof(action_rss_data->rss_key),
2099                                 info.hash_key_size);
2100         }
2101         action->conf = &action_rss_data->conf;
2102         return ret;
2103 }
2104
2105 /**
2106  * Parse type field for RSS action.
2107  *
2108  * Valid tokens are type field names and the "end" token.
2109  */
2110 static int
2111 parse_vc_action_rss_type(struct context *ctx, const struct token *token,
2112                           const char *str, unsigned int len,
2113                           void *buf, unsigned int size)
2114 {
2115         static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE);
2116         struct action_rss_data *action_rss_data;
2117         unsigned int i;
2118
2119         (void)token;
2120         (void)buf;
2121         (void)size;
2122         if (ctx->curr != ACTION_RSS_TYPE)
2123                 return -1;
2124         if (!(ctx->objdata >> 16) && ctx->object) {
2125                 action_rss_data = ctx->object;
2126                 action_rss_data->rss_conf.rss_hf = 0;
2127         }
2128         if (!strcmp_partial("end", str, len)) {
2129                 ctx->objdata &= 0xffff;
2130                 return len;
2131         }
2132         for (i = 0; rss_type_table[i].str; ++i)
2133                 if (!strcmp_partial(rss_type_table[i].str, str, len))
2134                         break;
2135         if (!rss_type_table[i].str)
2136                 return -1;
2137         ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff);
2138         /* Repeat token. */
2139         if (ctx->next_num == RTE_DIM(ctx->next))
2140                 return -1;
2141         ctx->next[ctx->next_num++] = next;
2142         if (!ctx->object)
2143                 return len;
2144         action_rss_data = ctx->object;
2145         action_rss_data->rss_conf.rss_hf |= rss_type_table[i].rss_type;
2146         return len;
2147 }
2148
2149 /**
2150  * Parse queue field for RSS action.
2151  *
2152  * Valid tokens are queue indices and the "end" token.
2153  */
2154 static int
2155 parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
2156                           const char *str, unsigned int len,
2157                           void *buf, unsigned int size)
2158 {
2159         static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE);
2160         struct action_rss_data *action_rss_data;
2161         int ret;
2162         int i;
2163
2164         (void)token;
2165         (void)buf;
2166         (void)size;
2167         if (ctx->curr != ACTION_RSS_QUEUE)
2168                 return -1;
2169         i = ctx->objdata >> 16;
2170         if (!strcmp_partial("end", str, len)) {
2171                 ctx->objdata &= 0xffff;
2172                 return len;
2173         }
2174         if (i >= ACTION_RSS_QUEUE_NUM)
2175                 return -1;
2176         if (push_args(ctx,
2177                       ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) +
2178                                      i * sizeof(action_rss_data->queue[i]),
2179                                      sizeof(action_rss_data->queue[i]))))
2180                 return -1;
2181         ret = parse_int(ctx, token, str, len, NULL, 0);
2182         if (ret < 0) {
2183                 pop_args(ctx);
2184                 return -1;
2185         }
2186         ++i;
2187         ctx->objdata = i << 16 | (ctx->objdata & 0xffff);
2188         /* Repeat token. */
2189         if (ctx->next_num == RTE_DIM(ctx->next))
2190                 return -1;
2191         ctx->next[ctx->next_num++] = next;
2192         if (!ctx->object)
2193                 return len;
2194         action_rss_data = ctx->object;
2195         action_rss_data->conf.num = i;
2196         action_rss_data->conf.queue = i ? action_rss_data->queue : NULL;
2197         return len;
2198 }
2199
2200 /** Parse tokens for destroy command. */
2201 static int
2202 parse_destroy(struct context *ctx, const struct token *token,
2203               const char *str, unsigned int len,
2204               void *buf, unsigned int size)
2205 {
2206         struct buffer *out = buf;
2207
2208         /* Token name must match. */
2209         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
2210                 return -1;
2211         /* Nothing else to do if there is no buffer. */
2212         if (!out)
2213                 return len;
2214         if (!out->command) {
2215                 if (ctx->curr != DESTROY)
2216                         return -1;
2217                 if (sizeof(*out) > size)
2218                         return -1;
2219                 out->command = ctx->curr;
2220                 ctx->objdata = 0;
2221                 ctx->object = out;
2222                 ctx->objmask = NULL;
2223                 out->args.destroy.rule =
2224                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
2225                                                sizeof(double));
2226                 return len;
2227         }
2228         if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) +
2229              sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size)
2230                 return -1;
2231         ctx->objdata = 0;
2232         ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++;
2233         ctx->objmask = NULL;
2234         return len;
2235 }
2236
2237 /** Parse tokens for flush command. */
2238 static int
2239 parse_flush(struct context *ctx, const struct token *token,
2240             const char *str, unsigned int len,
2241             void *buf, unsigned int size)
2242 {
2243         struct buffer *out = buf;
2244
2245         /* Token name must match. */
2246         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
2247                 return -1;
2248         /* Nothing else to do if there is no buffer. */
2249         if (!out)
2250                 return len;
2251         if (!out->command) {
2252                 if (ctx->curr != FLUSH)
2253                         return -1;
2254                 if (sizeof(*out) > size)
2255                         return -1;
2256                 out->command = ctx->curr;
2257                 ctx->objdata = 0;
2258                 ctx->object = out;
2259                 ctx->objmask = NULL;
2260         }
2261         return len;
2262 }
2263
2264 /** Parse tokens for query command. */
2265 static int
2266 parse_query(struct context *ctx, const struct token *token,
2267             const char *str, unsigned int len,
2268             void *buf, unsigned int size)
2269 {
2270         struct buffer *out = buf;
2271
2272         /* Token name must match. */
2273         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
2274                 return -1;
2275         /* Nothing else to do if there is no buffer. */
2276         if (!out)
2277                 return len;
2278         if (!out->command) {
2279                 if (ctx->curr != QUERY)
2280                         return -1;
2281                 if (sizeof(*out) > size)
2282                         return -1;
2283                 out->command = ctx->curr;
2284                 ctx->objdata = 0;
2285                 ctx->object = out;
2286                 ctx->objmask = NULL;
2287         }
2288         return len;
2289 }
2290
2291 /** Parse action names. */
2292 static int
2293 parse_action(struct context *ctx, const struct token *token,
2294              const char *str, unsigned int len,
2295              void *buf, unsigned int size)
2296 {
2297         struct buffer *out = buf;
2298         const struct arg *arg = pop_args(ctx);
2299         unsigned int i;
2300
2301         (void)size;
2302         /* Argument is expected. */
2303         if (!arg)
2304                 return -1;
2305         /* Parse action name. */
2306         for (i = 0; next_action[i]; ++i) {
2307                 const struct parse_action_priv *priv;
2308
2309                 token = &token_list[next_action[i]];
2310                 if (strcmp_partial(token->name, str, len))
2311                         continue;
2312                 priv = token->priv;
2313                 if (!priv)
2314                         goto error;
2315                 if (out)
2316                         memcpy((uint8_t *)ctx->object + arg->offset,
2317                                &priv->type,
2318                                arg->size);
2319                 return len;
2320         }
2321 error:
2322         push_args(ctx, arg);
2323         return -1;
2324 }
2325
2326 /** Parse tokens for list command. */
2327 static int
2328 parse_list(struct context *ctx, const struct token *token,
2329            const char *str, unsigned int len,
2330            void *buf, unsigned int size)
2331 {
2332         struct buffer *out = buf;
2333
2334         /* Token name must match. */
2335         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
2336                 return -1;
2337         /* Nothing else to do if there is no buffer. */
2338         if (!out)
2339                 return len;
2340         if (!out->command) {
2341                 if (ctx->curr != LIST)
2342                         return -1;
2343                 if (sizeof(*out) > size)
2344                         return -1;
2345                 out->command = ctx->curr;
2346                 ctx->objdata = 0;
2347                 ctx->object = out;
2348                 ctx->objmask = NULL;
2349                 out->args.list.group =
2350                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
2351                                                sizeof(double));
2352                 return len;
2353         }
2354         if (((uint8_t *)(out->args.list.group + out->args.list.group_n) +
2355              sizeof(*out->args.list.group)) > (uint8_t *)out + size)
2356                 return -1;
2357         ctx->objdata = 0;
2358         ctx->object = out->args.list.group + out->args.list.group_n++;
2359         ctx->objmask = NULL;
2360         return len;
2361 }
2362
2363 /** Parse tokens for isolate command. */
2364 static int
2365 parse_isolate(struct context *ctx, const struct token *token,
2366               const char *str, unsigned int len,
2367               void *buf, unsigned int size)
2368 {
2369         struct buffer *out = buf;
2370
2371         /* Token name must match. */
2372         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
2373                 return -1;
2374         /* Nothing else to do if there is no buffer. */
2375         if (!out)
2376                 return len;
2377         if (!out->command) {
2378                 if (ctx->curr != ISOLATE)
2379                         return -1;
2380                 if (sizeof(*out) > size)
2381                         return -1;
2382                 out->command = ctx->curr;
2383                 ctx->objdata = 0;
2384                 ctx->object = out;
2385                 ctx->objmask = NULL;
2386         }
2387         return len;
2388 }
2389
2390 /**
2391  * Parse signed/unsigned integers 8 to 64-bit long.
2392  *
2393  * Last argument (ctx->args) is retrieved to determine integer type and
2394  * storage location.
2395  */
2396 static int
2397 parse_int(struct context *ctx, const struct token *token,
2398           const char *str, unsigned int len,
2399           void *buf, unsigned int size)
2400 {
2401         const struct arg *arg = pop_args(ctx);
2402         uintmax_t u;
2403         char *end;
2404
2405         (void)token;
2406         /* Argument is expected. */
2407         if (!arg)
2408                 return -1;
2409         errno = 0;
2410         u = arg->sign ?
2411                 (uintmax_t)strtoimax(str, &end, 0) :
2412                 strtoumax(str, &end, 0);
2413         if (errno || (size_t)(end - str) != len)
2414                 goto error;
2415         if (arg->bounded &&
2416             ((arg->sign && ((intmax_t)u < (intmax_t)arg->min ||
2417                             (intmax_t)u > (intmax_t)arg->max)) ||
2418              (!arg->sign && (u < arg->min || u > arg->max))))
2419                 goto error;
2420         if (!ctx->object)
2421                 return len;
2422         if (arg->mask) {
2423                 if (!arg_entry_bf_fill(ctx->object, u, arg) ||
2424                     !arg_entry_bf_fill(ctx->objmask, -1, arg))
2425                         goto error;
2426                 return len;
2427         }
2428         buf = (uint8_t *)ctx->object + arg->offset;
2429         size = arg->size;
2430 objmask:
2431         switch (size) {
2432         case sizeof(uint8_t):
2433                 *(uint8_t *)buf = u;
2434                 break;
2435         case sizeof(uint16_t):
2436                 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u;
2437                 break;
2438         case sizeof(uint8_t [3]):
2439 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
2440                 if (!arg->hton) {
2441                         ((uint8_t *)buf)[0] = u;
2442                         ((uint8_t *)buf)[1] = u >> 8;
2443                         ((uint8_t *)buf)[2] = u >> 16;
2444                         break;
2445                 }
2446 #endif
2447                 ((uint8_t *)buf)[0] = u >> 16;
2448                 ((uint8_t *)buf)[1] = u >> 8;
2449                 ((uint8_t *)buf)[2] = u;
2450                 break;
2451         case sizeof(uint32_t):
2452                 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u;
2453                 break;
2454         case sizeof(uint64_t):
2455                 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u;
2456                 break;
2457         default:
2458                 goto error;
2459         }
2460         if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) {
2461                 u = -1;
2462                 buf = (uint8_t *)ctx->objmask + arg->offset;
2463                 goto objmask;
2464         }
2465         return len;
2466 error:
2467         push_args(ctx, arg);
2468         return -1;
2469 }
2470
2471 /**
2472  * Parse a string.
2473  *
2474  * Three arguments (ctx->args) are retrieved from the stack to store data,
2475  * its actual length and address (in that order).
2476  */
2477 static int
2478 parse_string(struct context *ctx, const struct token *token,
2479              const char *str, unsigned int len,
2480              void *buf, unsigned int size)
2481 {
2482         const struct arg *arg_data = pop_args(ctx);
2483         const struct arg *arg_len = pop_args(ctx);
2484         const struct arg *arg_addr = pop_args(ctx);
2485         char tmp[16]; /* Ought to be enough. */
2486         int ret;
2487
2488         /* Arguments are expected. */
2489         if (!arg_data)
2490                 return -1;
2491         if (!arg_len) {
2492                 push_args(ctx, arg_data);
2493                 return -1;
2494         }
2495         if (!arg_addr) {
2496                 push_args(ctx, arg_len);
2497                 push_args(ctx, arg_data);
2498                 return -1;
2499         }
2500         size = arg_data->size;
2501         /* Bit-mask fill is not supported. */
2502         if (arg_data->mask || size < len)
2503                 goto error;
2504         if (!ctx->object)
2505                 return len;
2506         /* Let parse_int() fill length information first. */
2507         ret = snprintf(tmp, sizeof(tmp), "%u", len);
2508         if (ret < 0)
2509                 goto error;
2510         push_args(ctx, arg_len);
2511         ret = parse_int(ctx, token, tmp, ret, NULL, 0);
2512         if (ret < 0) {
2513                 pop_args(ctx);
2514                 goto error;
2515         }
2516         buf = (uint8_t *)ctx->object + arg_data->offset;
2517         /* Output buffer is not necessarily NUL-terminated. */
2518         memcpy(buf, str, len);
2519         memset((uint8_t *)buf + len, 0x00, size - len);
2520         if (ctx->objmask)
2521                 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len);
2522         /* Save address if requested. */
2523         if (arg_addr->size) {
2524                 memcpy((uint8_t *)ctx->object + arg_addr->offset,
2525                        (void *[]){
2526                         (uint8_t *)ctx->object + arg_data->offset
2527                        },
2528                        arg_addr->size);
2529                 if (ctx->objmask)
2530                         memcpy((uint8_t *)ctx->objmask + arg_addr->offset,
2531                                (void *[]){
2532                                 (uint8_t *)ctx->objmask + arg_data->offset
2533                                },
2534                                arg_addr->size);
2535         }
2536         return len;
2537 error:
2538         push_args(ctx, arg_addr);
2539         push_args(ctx, arg_len);
2540         push_args(ctx, arg_data);
2541         return -1;
2542 }
2543
2544 /**
2545  * Parse a MAC address.
2546  *
2547  * Last argument (ctx->args) is retrieved to determine storage size and
2548  * location.
2549  */
2550 static int
2551 parse_mac_addr(struct context *ctx, const struct token *token,
2552                const char *str, unsigned int len,
2553                void *buf, unsigned int size)
2554 {
2555         const struct arg *arg = pop_args(ctx);
2556         struct ether_addr tmp;
2557         int ret;
2558
2559         (void)token;
2560         /* Argument is expected. */
2561         if (!arg)
2562                 return -1;
2563         size = arg->size;
2564         /* Bit-mask fill is not supported. */
2565         if (arg->mask || size != sizeof(tmp))
2566                 goto error;
2567         /* Only network endian is supported. */
2568         if (!arg->hton)
2569                 goto error;
2570         ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
2571         if (ret < 0 || (unsigned int)ret != len)
2572                 goto error;
2573         if (!ctx->object)
2574                 return len;
2575         buf = (uint8_t *)ctx->object + arg->offset;
2576         memcpy(buf, &tmp, size);
2577         if (ctx->objmask)
2578                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
2579         return len;
2580 error:
2581         push_args(ctx, arg);
2582         return -1;
2583 }
2584
2585 /**
2586  * Parse an IPv4 address.
2587  *
2588  * Last argument (ctx->args) is retrieved to determine storage size and
2589  * location.
2590  */
2591 static int
2592 parse_ipv4_addr(struct context *ctx, const struct token *token,
2593                 const char *str, unsigned int len,
2594                 void *buf, unsigned int size)
2595 {
2596         const struct arg *arg = pop_args(ctx);
2597         char str2[len + 1];
2598         struct in_addr tmp;
2599         int ret;
2600
2601         /* Argument is expected. */
2602         if (!arg)
2603                 return -1;
2604         size = arg->size;
2605         /* Bit-mask fill is not supported. */
2606         if (arg->mask || size != sizeof(tmp))
2607                 goto error;
2608         /* Only network endian is supported. */
2609         if (!arg->hton)
2610                 goto error;
2611         memcpy(str2, str, len);
2612         str2[len] = '\0';
2613         ret = inet_pton(AF_INET, str2, &tmp);
2614         if (ret != 1) {
2615                 /* Attempt integer parsing. */
2616                 push_args(ctx, arg);
2617                 return parse_int(ctx, token, str, len, buf, size);
2618         }
2619         if (!ctx->object)
2620                 return len;
2621         buf = (uint8_t *)ctx->object + arg->offset;
2622         memcpy(buf, &tmp, size);
2623         if (ctx->objmask)
2624                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
2625         return len;
2626 error:
2627         push_args(ctx, arg);
2628         return -1;
2629 }
2630
2631 /**
2632  * Parse an IPv6 address.
2633  *
2634  * Last argument (ctx->args) is retrieved to determine storage size and
2635  * location.
2636  */
2637 static int
2638 parse_ipv6_addr(struct context *ctx, const struct token *token,
2639                 const char *str, unsigned int len,
2640                 void *buf, unsigned int size)
2641 {
2642         const struct arg *arg = pop_args(ctx);
2643         char str2[len + 1];
2644         struct in6_addr tmp;
2645         int ret;
2646
2647         (void)token;
2648         /* Argument is expected. */
2649         if (!arg)
2650                 return -1;
2651         size = arg->size;
2652         /* Bit-mask fill is not supported. */
2653         if (arg->mask || size != sizeof(tmp))
2654                 goto error;
2655         /* Only network endian is supported. */
2656         if (!arg->hton)
2657                 goto error;
2658         memcpy(str2, str, len);
2659         str2[len] = '\0';
2660         ret = inet_pton(AF_INET6, str2, &tmp);
2661         if (ret != 1)
2662                 goto error;
2663         if (!ctx->object)
2664                 return len;
2665         buf = (uint8_t *)ctx->object + arg->offset;
2666         memcpy(buf, &tmp, size);
2667         if (ctx->objmask)
2668                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
2669         return len;
2670 error:
2671         push_args(ctx, arg);
2672         return -1;
2673 }
2674
2675 /** Boolean values (even indices stand for false). */
2676 static const char *const boolean_name[] = {
2677         "0", "1",
2678         "false", "true",
2679         "no", "yes",
2680         "N", "Y",
2681         "off", "on",
2682         NULL,
2683 };
2684
2685 /**
2686  * Parse a boolean value.
2687  *
2688  * Last argument (ctx->args) is retrieved to determine storage size and
2689  * location.
2690  */
2691 static int
2692 parse_boolean(struct context *ctx, const struct token *token,
2693               const char *str, unsigned int len,
2694               void *buf, unsigned int size)
2695 {
2696         const struct arg *arg = pop_args(ctx);
2697         unsigned int i;
2698         int ret;
2699
2700         /* Argument is expected. */
2701         if (!arg)
2702                 return -1;
2703         for (i = 0; boolean_name[i]; ++i)
2704                 if (!strcmp_partial(boolean_name[i], str, len))
2705                         break;
2706         /* Process token as integer. */
2707         if (boolean_name[i])
2708                 str = i & 1 ? "1" : "0";
2709         push_args(ctx, arg);
2710         ret = parse_int(ctx, token, str, strlen(str), buf, size);
2711         return ret > 0 ? (int)len : ret;
2712 }
2713
2714 /** Parse port and update context. */
2715 static int
2716 parse_port(struct context *ctx, const struct token *token,
2717            const char *str, unsigned int len,
2718            void *buf, unsigned int size)
2719 {
2720         struct buffer *out = &(struct buffer){ .port = 0 };
2721         int ret;
2722
2723         if (buf)
2724                 out = buf;
2725         else {
2726                 ctx->objdata = 0;
2727                 ctx->object = out;
2728                 ctx->objmask = NULL;
2729                 size = sizeof(*out);
2730         }
2731         ret = parse_int(ctx, token, str, len, out, size);
2732         if (ret >= 0)
2733                 ctx->port = out->port;
2734         if (!buf)
2735                 ctx->object = NULL;
2736         return ret;
2737 }
2738
2739 /** No completion. */
2740 static int
2741 comp_none(struct context *ctx, const struct token *token,
2742           unsigned int ent, char *buf, unsigned int size)
2743 {
2744         (void)ctx;
2745         (void)token;
2746         (void)ent;
2747         (void)buf;
2748         (void)size;
2749         return 0;
2750 }
2751
2752 /** Complete boolean values. */
2753 static int
2754 comp_boolean(struct context *ctx, const struct token *token,
2755              unsigned int ent, char *buf, unsigned int size)
2756 {
2757         unsigned int i;
2758
2759         (void)ctx;
2760         (void)token;
2761         for (i = 0; boolean_name[i]; ++i)
2762                 if (buf && i == ent)
2763                         return snprintf(buf, size, "%s", boolean_name[i]);
2764         if (buf)
2765                 return -1;
2766         return i;
2767 }
2768
2769 /** Complete action names. */
2770 static int
2771 comp_action(struct context *ctx, const struct token *token,
2772             unsigned int ent, char *buf, unsigned int size)
2773 {
2774         unsigned int i;
2775
2776         (void)ctx;
2777         (void)token;
2778         for (i = 0; next_action[i]; ++i)
2779                 if (buf && i == ent)
2780                         return snprintf(buf, size, "%s",
2781                                         token_list[next_action[i]].name);
2782         if (buf)
2783                 return -1;
2784         return i;
2785 }
2786
2787 /** Complete available ports. */
2788 static int
2789 comp_port(struct context *ctx, const struct token *token,
2790           unsigned int ent, char *buf, unsigned int size)
2791 {
2792         unsigned int i = 0;
2793         portid_t p;
2794
2795         (void)ctx;
2796         (void)token;
2797         RTE_ETH_FOREACH_DEV(p) {
2798                 if (buf && i == ent)
2799                         return snprintf(buf, size, "%u", p);
2800                 ++i;
2801         }
2802         if (buf)
2803                 return -1;
2804         return i;
2805 }
2806
2807 /** Complete available rule IDs. */
2808 static int
2809 comp_rule_id(struct context *ctx, const struct token *token,
2810              unsigned int ent, char *buf, unsigned int size)
2811 {
2812         unsigned int i = 0;
2813         struct rte_port *port;
2814         struct port_flow *pf;
2815
2816         (void)token;
2817         if (port_id_is_invalid(ctx->port, DISABLED_WARN) ||
2818             ctx->port == (portid_t)RTE_PORT_ALL)
2819                 return -1;
2820         port = &ports[ctx->port];
2821         for (pf = port->flow_list; pf != NULL; pf = pf->next) {
2822                 if (buf && i == ent)
2823                         return snprintf(buf, size, "%u", pf->id);
2824                 ++i;
2825         }
2826         if (buf)
2827                 return -1;
2828         return i;
2829 }
2830
2831 /** Complete type field for RSS action. */
2832 static int
2833 comp_vc_action_rss_type(struct context *ctx, const struct token *token,
2834                         unsigned int ent, char *buf, unsigned int size)
2835 {
2836         unsigned int i;
2837
2838         (void)ctx;
2839         (void)token;
2840         for (i = 0; rss_type_table[i].str; ++i)
2841                 ;
2842         if (!buf)
2843                 return i + 1;
2844         if (ent < i)
2845                 return snprintf(buf, size, "%s", rss_type_table[ent].str);
2846         if (ent == i)
2847                 return snprintf(buf, size, "end");
2848         return -1;
2849 }
2850
2851 /** Complete queue field for RSS action. */
2852 static int
2853 comp_vc_action_rss_queue(struct context *ctx, const struct token *token,
2854                          unsigned int ent, char *buf, unsigned int size)
2855 {
2856         (void)ctx;
2857         (void)token;
2858         if (!buf)
2859                 return nb_rxq + 1;
2860         if (ent < nb_rxq)
2861                 return snprintf(buf, size, "%u", ent);
2862         if (ent == nb_rxq)
2863                 return snprintf(buf, size, "end");
2864         return -1;
2865 }
2866
2867 /** Internal context. */
2868 static struct context cmd_flow_context;
2869
2870 /** Global parser instance (cmdline API). */
2871 cmdline_parse_inst_t cmd_flow;
2872
2873 /** Initialize context. */
2874 static void
2875 cmd_flow_context_init(struct context *ctx)
2876 {
2877         /* A full memset() is not necessary. */
2878         ctx->curr = ZERO;
2879         ctx->prev = ZERO;
2880         ctx->next_num = 0;
2881         ctx->args_num = 0;
2882         ctx->eol = 0;
2883         ctx->last = 0;
2884         ctx->port = 0;
2885         ctx->objdata = 0;
2886         ctx->object = NULL;
2887         ctx->objmask = NULL;
2888 }
2889
2890 /** Parse a token (cmdline API). */
2891 static int
2892 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result,
2893                unsigned int size)
2894 {
2895         struct context *ctx = &cmd_flow_context;
2896         const struct token *token;
2897         const enum index *list;
2898         int len;
2899         int i;
2900
2901         (void)hdr;
2902         token = &token_list[ctx->curr];
2903         /* Check argument length. */
2904         ctx->eol = 0;
2905         ctx->last = 1;
2906         for (len = 0; src[len]; ++len)
2907                 if (src[len] == '#' || isspace(src[len]))
2908                         break;
2909         if (!len)
2910                 return -1;
2911         /* Last argument and EOL detection. */
2912         for (i = len; src[i]; ++i)
2913                 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n')
2914                         break;
2915                 else if (!isspace(src[i])) {
2916                         ctx->last = 0;
2917                         break;
2918                 }
2919         for (; src[i]; ++i)
2920                 if (src[i] == '\r' || src[i] == '\n') {
2921                         ctx->eol = 1;
2922                         break;
2923                 }
2924         /* Initialize context if necessary. */
2925         if (!ctx->next_num) {
2926                 if (!token->next)
2927                         return 0;
2928                 ctx->next[ctx->next_num++] = token->next[0];
2929         }
2930         /* Process argument through candidates. */
2931         ctx->prev = ctx->curr;
2932         list = ctx->next[ctx->next_num - 1];
2933         for (i = 0; list[i]; ++i) {
2934                 const struct token *next = &token_list[list[i]];
2935                 int tmp;
2936
2937                 ctx->curr = list[i];
2938                 if (next->call)
2939                         tmp = next->call(ctx, next, src, len, result, size);
2940                 else
2941                         tmp = parse_default(ctx, next, src, len, result, size);
2942                 if (tmp == -1 || tmp != len)
2943                         continue;
2944                 token = next;
2945                 break;
2946         }
2947         if (!list[i])
2948                 return -1;
2949         --ctx->next_num;
2950         /* Push subsequent tokens if any. */
2951         if (token->next)
2952                 for (i = 0; token->next[i]; ++i) {
2953                         if (ctx->next_num == RTE_DIM(ctx->next))
2954                                 return -1;
2955                         ctx->next[ctx->next_num++] = token->next[i];
2956                 }
2957         /* Push arguments if any. */
2958         if (token->args)
2959                 for (i = 0; token->args[i]; ++i) {
2960                         if (ctx->args_num == RTE_DIM(ctx->args))
2961                                 return -1;
2962                         ctx->args[ctx->args_num++] = token->args[i];
2963                 }
2964         return len;
2965 }
2966
2967 /** Return number of completion entries (cmdline API). */
2968 static int
2969 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr)
2970 {
2971         struct context *ctx = &cmd_flow_context;
2972         const struct token *token = &token_list[ctx->curr];
2973         const enum index *list;
2974         int i;
2975
2976         (void)hdr;
2977         /* Count number of tokens in current list. */
2978         if (ctx->next_num)
2979                 list = ctx->next[ctx->next_num - 1];
2980         else
2981                 list = token->next[0];
2982         for (i = 0; list[i]; ++i)
2983                 ;
2984         if (!i)
2985                 return 0;
2986         /*
2987          * If there is a single token, use its completion callback, otherwise
2988          * return the number of entries.
2989          */
2990         token = &token_list[list[0]];
2991         if (i == 1 && token->comp) {
2992                 /* Save index for cmd_flow_get_help(). */
2993                 ctx->prev = list[0];
2994                 return token->comp(ctx, token, 0, NULL, 0);
2995         }
2996         return i;
2997 }
2998
2999 /** Return a completion entry (cmdline API). */
3000 static int
3001 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index,
3002                           char *dst, unsigned int size)
3003 {
3004         struct context *ctx = &cmd_flow_context;
3005         const struct token *token = &token_list[ctx->curr];
3006         const enum index *list;
3007         int i;
3008
3009         (void)hdr;
3010         /* Count number of tokens in current list. */
3011         if (ctx->next_num)
3012                 list = ctx->next[ctx->next_num - 1];
3013         else
3014                 list = token->next[0];
3015         for (i = 0; list[i]; ++i)
3016                 ;
3017         if (!i)
3018                 return -1;
3019         /* If there is a single token, use its completion callback. */
3020         token = &token_list[list[0]];
3021         if (i == 1 && token->comp) {
3022                 /* Save index for cmd_flow_get_help(). */
3023                 ctx->prev = list[0];
3024                 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0;
3025         }
3026         /* Otherwise make sure the index is valid and use defaults. */
3027         if (index >= i)
3028                 return -1;
3029         token = &token_list[list[index]];
3030         snprintf(dst, size, "%s", token->name);
3031         /* Save index for cmd_flow_get_help(). */
3032         ctx->prev = list[index];
3033         return 0;
3034 }
3035
3036 /** Populate help strings for current token (cmdline API). */
3037 static int
3038 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size)
3039 {
3040         struct context *ctx = &cmd_flow_context;
3041         const struct token *token = &token_list[ctx->prev];
3042
3043         (void)hdr;
3044         if (!size)
3045                 return -1;
3046         /* Set token type and update global help with details. */
3047         snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN"));
3048         if (token->help)
3049                 cmd_flow.help_str = token->help;
3050         else
3051                 cmd_flow.help_str = token->name;
3052         return 0;
3053 }
3054
3055 /** Token definition template (cmdline API). */
3056 static struct cmdline_token_hdr cmd_flow_token_hdr = {
3057         .ops = &(struct cmdline_token_ops){
3058                 .parse = cmd_flow_parse,
3059                 .complete_get_nb = cmd_flow_complete_get_nb,
3060                 .complete_get_elt = cmd_flow_complete_get_elt,
3061                 .get_help = cmd_flow_get_help,
3062         },
3063         .offset = 0,
3064 };
3065
3066 /** Populate the next dynamic token. */
3067 static void
3068 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr,
3069              cmdline_parse_token_hdr_t **hdr_inst)
3070 {
3071         struct context *ctx = &cmd_flow_context;
3072
3073         /* Always reinitialize context before requesting the first token. */
3074         if (!(hdr_inst - cmd_flow.tokens))
3075                 cmd_flow_context_init(ctx);
3076         /* Return NULL when no more tokens are expected. */
3077         if (!ctx->next_num && ctx->curr) {
3078                 *hdr = NULL;
3079                 return;
3080         }
3081         /* Determine if command should end here. */
3082         if (ctx->eol && ctx->last && ctx->next_num) {
3083                 const enum index *list = ctx->next[ctx->next_num - 1];
3084                 int i;
3085
3086                 for (i = 0; list[i]; ++i) {
3087                         if (list[i] != END)
3088                                 continue;
3089                         *hdr = NULL;
3090                         return;
3091                 }
3092         }
3093         *hdr = &cmd_flow_token_hdr;
3094 }
3095
3096 /** Dispatch parsed buffer to function calls. */
3097 static void
3098 cmd_flow_parsed(const struct buffer *in)
3099 {
3100         switch (in->command) {
3101         case VALIDATE:
3102                 port_flow_validate(in->port, &in->args.vc.attr,
3103                                    in->args.vc.pattern, in->args.vc.actions);
3104                 break;
3105         case CREATE:
3106                 port_flow_create(in->port, &in->args.vc.attr,
3107                                  in->args.vc.pattern, in->args.vc.actions);
3108                 break;
3109         case DESTROY:
3110                 port_flow_destroy(in->port, in->args.destroy.rule_n,
3111                                   in->args.destroy.rule);
3112                 break;
3113         case FLUSH:
3114                 port_flow_flush(in->port);
3115                 break;
3116         case QUERY:
3117                 port_flow_query(in->port, in->args.query.rule,
3118                                 in->args.query.action);
3119                 break;
3120         case LIST:
3121                 port_flow_list(in->port, in->args.list.group_n,
3122                                in->args.list.group);
3123                 break;
3124         case ISOLATE:
3125                 port_flow_isolate(in->port, in->args.isolate.set);
3126                 break;
3127         default:
3128                 break;
3129         }
3130 }
3131
3132 /** Token generator and output processing callback (cmdline API). */
3133 static void
3134 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2)
3135 {
3136         if (cl == NULL)
3137                 cmd_flow_tok(arg0, arg2);
3138         else
3139                 cmd_flow_parsed(arg0);
3140 }
3141
3142 /** Global parser instance (cmdline API). */
3143 cmdline_parse_inst_t cmd_flow = {
3144         .f = cmd_flow_cb,
3145         .data = NULL, /**< Unused. */
3146         .help_str = NULL, /**< Updated by cmd_flow_get_help(). */
3147         .tokens = {
3148                 NULL,
3149         }, /**< Tokens are returned by cmd_flow_tok(). */
3150 };