1496d7a0673a41092e17257fc042dc70c2e732af
[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
14 #include <rte_string_fns.h>
15 #include <rte_common.h>
16 #include <rte_ethdev.h>
17 #include <rte_byteorder.h>
18 #include <cmdline_parse.h>
19 #include <cmdline_parse_etheraddr.h>
20 #include <cmdline_parse_string.h>
21 #include <cmdline_parse_num.h>
22 #include <rte_flow.h>
23 #include <rte_hexdump.h>
24 #include <rte_vxlan.h>
25 #include <rte_gre.h>
26 #include <rte_mpls.h>
27 #include <rte_gtp.h>
28 #include <rte_geneve.h>
29
30 #include "testpmd.h"
31
32 /** Parser token indices. */
33 enum index {
34         /* Special tokens. */
35         ZERO = 0,
36         END,
37         START_SET,
38         END_SET,
39
40         /* Common tokens. */
41         COMMON_INTEGER,
42         COMMON_UNSIGNED,
43         COMMON_PREFIX,
44         COMMON_BOOLEAN,
45         COMMON_STRING,
46         COMMON_HEX,
47         COMMON_FILE_PATH,
48         COMMON_MAC_ADDR,
49         COMMON_IPV4_ADDR,
50         COMMON_IPV6_ADDR,
51         COMMON_RULE_ID,
52         COMMON_PORT_ID,
53         COMMON_GROUP_ID,
54         COMMON_PRIORITY_LEVEL,
55         COMMON_INDIRECT_ACTION_ID,
56         COMMON_POLICY_ID,
57
58         /* TOP-level command. */
59         ADD,
60
61         /* Top-level command. */
62         SET,
63         /* Sub-leve commands. */
64         SET_RAW_ENCAP,
65         SET_RAW_DECAP,
66         SET_RAW_INDEX,
67         SET_SAMPLE_ACTIONS,
68         SET_SAMPLE_INDEX,
69
70         /* Top-level command. */
71         FLOW,
72         /* Sub-level commands. */
73         INDIRECT_ACTION,
74         VALIDATE,
75         CREATE,
76         DESTROY,
77         FLUSH,
78         DUMP,
79         QUERY,
80         LIST,
81         AGED,
82         ISOLATE,
83         TUNNEL,
84
85         /* Tunnel arguments. */
86         TUNNEL_CREATE,
87         TUNNEL_CREATE_TYPE,
88         TUNNEL_LIST,
89         TUNNEL_DESTROY,
90         TUNNEL_DESTROY_ID,
91
92         /* Destroy arguments. */
93         DESTROY_RULE,
94
95         /* Query arguments. */
96         QUERY_ACTION,
97
98         /* List arguments. */
99         LIST_GROUP,
100
101         /* Destroy aged flow arguments. */
102         AGED_DESTROY,
103
104         /* Validate/create arguments. */
105         VC_GROUP,
106         VC_PRIORITY,
107         VC_INGRESS,
108         VC_EGRESS,
109         VC_TRANSFER,
110         VC_TUNNEL_SET,
111         VC_TUNNEL_MATCH,
112
113         /* Dump arguments */
114         DUMP_ALL,
115         DUMP_ONE,
116
117         /* Indirect action arguments */
118         INDIRECT_ACTION_CREATE,
119         INDIRECT_ACTION_UPDATE,
120         INDIRECT_ACTION_DESTROY,
121         INDIRECT_ACTION_QUERY,
122
123         /* Indirect action create arguments */
124         INDIRECT_ACTION_CREATE_ID,
125         INDIRECT_ACTION_INGRESS,
126         INDIRECT_ACTION_EGRESS,
127         INDIRECT_ACTION_TRANSFER,
128         INDIRECT_ACTION_SPEC,
129
130         /* Indirect action destroy arguments */
131         INDIRECT_ACTION_DESTROY_ID,
132
133         /* Validate/create pattern. */
134         ITEM_PATTERN,
135         ITEM_PARAM_IS,
136         ITEM_PARAM_SPEC,
137         ITEM_PARAM_LAST,
138         ITEM_PARAM_MASK,
139         ITEM_PARAM_PREFIX,
140         ITEM_NEXT,
141         ITEM_END,
142         ITEM_VOID,
143         ITEM_INVERT,
144         ITEM_ANY,
145         ITEM_ANY_NUM,
146         ITEM_PF,
147         ITEM_VF,
148         ITEM_VF_ID,
149         ITEM_PHY_PORT,
150         ITEM_PHY_PORT_INDEX,
151         ITEM_PORT_ID,
152         ITEM_PORT_ID_ID,
153         ITEM_MARK,
154         ITEM_MARK_ID,
155         ITEM_RAW,
156         ITEM_RAW_RELATIVE,
157         ITEM_RAW_SEARCH,
158         ITEM_RAW_OFFSET,
159         ITEM_RAW_LIMIT,
160         ITEM_RAW_PATTERN,
161         ITEM_ETH,
162         ITEM_ETH_DST,
163         ITEM_ETH_SRC,
164         ITEM_ETH_TYPE,
165         ITEM_ETH_HAS_VLAN,
166         ITEM_VLAN,
167         ITEM_VLAN_TCI,
168         ITEM_VLAN_PCP,
169         ITEM_VLAN_DEI,
170         ITEM_VLAN_VID,
171         ITEM_VLAN_INNER_TYPE,
172         ITEM_VLAN_HAS_MORE_VLAN,
173         ITEM_IPV4,
174         ITEM_IPV4_VER_IHL,
175         ITEM_IPV4_TOS,
176         ITEM_IPV4_ID,
177         ITEM_IPV4_FRAGMENT_OFFSET,
178         ITEM_IPV4_TTL,
179         ITEM_IPV4_PROTO,
180         ITEM_IPV4_SRC,
181         ITEM_IPV4_DST,
182         ITEM_IPV6,
183         ITEM_IPV6_TC,
184         ITEM_IPV6_FLOW,
185         ITEM_IPV6_PROTO,
186         ITEM_IPV6_HOP,
187         ITEM_IPV6_SRC,
188         ITEM_IPV6_DST,
189         ITEM_IPV6_HAS_FRAG_EXT,
190         ITEM_ICMP,
191         ITEM_ICMP_TYPE,
192         ITEM_ICMP_CODE,
193         ITEM_ICMP_IDENT,
194         ITEM_ICMP_SEQ,
195         ITEM_UDP,
196         ITEM_UDP_SRC,
197         ITEM_UDP_DST,
198         ITEM_TCP,
199         ITEM_TCP_SRC,
200         ITEM_TCP_DST,
201         ITEM_TCP_FLAGS,
202         ITEM_SCTP,
203         ITEM_SCTP_SRC,
204         ITEM_SCTP_DST,
205         ITEM_SCTP_TAG,
206         ITEM_SCTP_CKSUM,
207         ITEM_VXLAN,
208         ITEM_VXLAN_VNI,
209         ITEM_VXLAN_LAST_RSVD,
210         ITEM_E_TAG,
211         ITEM_E_TAG_GRP_ECID_B,
212         ITEM_NVGRE,
213         ITEM_NVGRE_TNI,
214         ITEM_MPLS,
215         ITEM_MPLS_LABEL,
216         ITEM_MPLS_TC,
217         ITEM_MPLS_S,
218         ITEM_GRE,
219         ITEM_GRE_PROTO,
220         ITEM_GRE_C_RSVD0_VER,
221         ITEM_GRE_C_BIT,
222         ITEM_GRE_K_BIT,
223         ITEM_GRE_S_BIT,
224         ITEM_FUZZY,
225         ITEM_FUZZY_THRESH,
226         ITEM_GTP,
227         ITEM_GTP_FLAGS,
228         ITEM_GTP_MSG_TYPE,
229         ITEM_GTP_TEID,
230         ITEM_GTPC,
231         ITEM_GTPU,
232         ITEM_GENEVE,
233         ITEM_GENEVE_VNI,
234         ITEM_GENEVE_PROTO,
235         ITEM_GENEVE_OPTLEN,
236         ITEM_VXLAN_GPE,
237         ITEM_VXLAN_GPE_VNI,
238         ITEM_ARP_ETH_IPV4,
239         ITEM_ARP_ETH_IPV4_SHA,
240         ITEM_ARP_ETH_IPV4_SPA,
241         ITEM_ARP_ETH_IPV4_THA,
242         ITEM_ARP_ETH_IPV4_TPA,
243         ITEM_IPV6_EXT,
244         ITEM_IPV6_EXT_NEXT_HDR,
245         ITEM_IPV6_FRAG_EXT,
246         ITEM_IPV6_FRAG_EXT_NEXT_HDR,
247         ITEM_IPV6_FRAG_EXT_FRAG_DATA,
248         ITEM_IPV6_FRAG_EXT_ID,
249         ITEM_ICMP6,
250         ITEM_ICMP6_TYPE,
251         ITEM_ICMP6_CODE,
252         ITEM_ICMP6_ND_NS,
253         ITEM_ICMP6_ND_NS_TARGET_ADDR,
254         ITEM_ICMP6_ND_NA,
255         ITEM_ICMP6_ND_NA_TARGET_ADDR,
256         ITEM_ICMP6_ND_OPT,
257         ITEM_ICMP6_ND_OPT_TYPE,
258         ITEM_ICMP6_ND_OPT_SLA_ETH,
259         ITEM_ICMP6_ND_OPT_SLA_ETH_SLA,
260         ITEM_ICMP6_ND_OPT_TLA_ETH,
261         ITEM_ICMP6_ND_OPT_TLA_ETH_TLA,
262         ITEM_META,
263         ITEM_META_DATA,
264         ITEM_GRE_KEY,
265         ITEM_GRE_KEY_VALUE,
266         ITEM_GTP_PSC,
267         ITEM_GTP_PSC_QFI,
268         ITEM_GTP_PSC_PDU_T,
269         ITEM_PPPOES,
270         ITEM_PPPOED,
271         ITEM_PPPOE_SEID,
272         ITEM_PPPOE_PROTO_ID,
273         ITEM_HIGIG2,
274         ITEM_HIGIG2_CLASSIFICATION,
275         ITEM_HIGIG2_VID,
276         ITEM_TAG,
277         ITEM_TAG_DATA,
278         ITEM_TAG_INDEX,
279         ITEM_L2TPV3OIP,
280         ITEM_L2TPV3OIP_SESSION_ID,
281         ITEM_ESP,
282         ITEM_ESP_SPI,
283         ITEM_AH,
284         ITEM_AH_SPI,
285         ITEM_PFCP,
286         ITEM_PFCP_S_FIELD,
287         ITEM_PFCP_SEID,
288         ITEM_ECPRI,
289         ITEM_ECPRI_COMMON,
290         ITEM_ECPRI_COMMON_TYPE,
291         ITEM_ECPRI_COMMON_TYPE_IQ_DATA,
292         ITEM_ECPRI_COMMON_TYPE_RTC_CTRL,
293         ITEM_ECPRI_COMMON_TYPE_DLY_MSR,
294         ITEM_ECPRI_MSG_IQ_DATA_PCID,
295         ITEM_ECPRI_MSG_RTC_CTRL_RTCID,
296         ITEM_ECPRI_MSG_DLY_MSR_MSRID,
297         ITEM_GENEVE_OPT,
298         ITEM_GENEVE_OPT_CLASS,
299         ITEM_GENEVE_OPT_TYPE,
300         ITEM_GENEVE_OPT_LENGTH,
301         ITEM_GENEVE_OPT_DATA,
302         ITEM_INTEGRITY,
303         ITEM_INTEGRITY_LEVEL,
304         ITEM_INTEGRITY_VALUE,
305         ITEM_CONNTRACK,
306         ITEM_POL_PORT,
307         ITEM_POL_METER,
308         ITEM_POL_POLICY,
309         ITEM_PORT_REPRESENTOR,
310         ITEM_PORT_REPRESENTOR_PORT_ID,
311         ITEM_REPRESENTED_PORT,
312         ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
313
314         /* Validate/create actions. */
315         ACTIONS,
316         ACTION_NEXT,
317         ACTION_END,
318         ACTION_VOID,
319         ACTION_PASSTHRU,
320         ACTION_JUMP,
321         ACTION_JUMP_GROUP,
322         ACTION_MARK,
323         ACTION_MARK_ID,
324         ACTION_FLAG,
325         ACTION_QUEUE,
326         ACTION_QUEUE_INDEX,
327         ACTION_DROP,
328         ACTION_COUNT,
329         ACTION_COUNT_ID,
330         ACTION_RSS,
331         ACTION_RSS_FUNC,
332         ACTION_RSS_LEVEL,
333         ACTION_RSS_FUNC_DEFAULT,
334         ACTION_RSS_FUNC_TOEPLITZ,
335         ACTION_RSS_FUNC_SIMPLE_XOR,
336         ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ,
337         ACTION_RSS_TYPES,
338         ACTION_RSS_TYPE,
339         ACTION_RSS_KEY,
340         ACTION_RSS_KEY_LEN,
341         ACTION_RSS_QUEUES,
342         ACTION_RSS_QUEUE,
343         ACTION_PF,
344         ACTION_VF,
345         ACTION_VF_ORIGINAL,
346         ACTION_VF_ID,
347         ACTION_PHY_PORT,
348         ACTION_PHY_PORT_ORIGINAL,
349         ACTION_PHY_PORT_INDEX,
350         ACTION_PORT_ID,
351         ACTION_PORT_ID_ORIGINAL,
352         ACTION_PORT_ID_ID,
353         ACTION_METER,
354         ACTION_METER_COLOR,
355         ACTION_METER_COLOR_TYPE,
356         ACTION_METER_COLOR_GREEN,
357         ACTION_METER_COLOR_YELLOW,
358         ACTION_METER_COLOR_RED,
359         ACTION_METER_ID,
360         ACTION_OF_SET_MPLS_TTL,
361         ACTION_OF_SET_MPLS_TTL_MPLS_TTL,
362         ACTION_OF_DEC_MPLS_TTL,
363         ACTION_OF_SET_NW_TTL,
364         ACTION_OF_SET_NW_TTL_NW_TTL,
365         ACTION_OF_DEC_NW_TTL,
366         ACTION_OF_COPY_TTL_OUT,
367         ACTION_OF_COPY_TTL_IN,
368         ACTION_OF_POP_VLAN,
369         ACTION_OF_PUSH_VLAN,
370         ACTION_OF_PUSH_VLAN_ETHERTYPE,
371         ACTION_OF_SET_VLAN_VID,
372         ACTION_OF_SET_VLAN_VID_VLAN_VID,
373         ACTION_OF_SET_VLAN_PCP,
374         ACTION_OF_SET_VLAN_PCP_VLAN_PCP,
375         ACTION_OF_POP_MPLS,
376         ACTION_OF_POP_MPLS_ETHERTYPE,
377         ACTION_OF_PUSH_MPLS,
378         ACTION_OF_PUSH_MPLS_ETHERTYPE,
379         ACTION_VXLAN_ENCAP,
380         ACTION_VXLAN_DECAP,
381         ACTION_NVGRE_ENCAP,
382         ACTION_NVGRE_DECAP,
383         ACTION_L2_ENCAP,
384         ACTION_L2_DECAP,
385         ACTION_MPLSOGRE_ENCAP,
386         ACTION_MPLSOGRE_DECAP,
387         ACTION_MPLSOUDP_ENCAP,
388         ACTION_MPLSOUDP_DECAP,
389         ACTION_SET_IPV4_SRC,
390         ACTION_SET_IPV4_SRC_IPV4_SRC,
391         ACTION_SET_IPV4_DST,
392         ACTION_SET_IPV4_DST_IPV4_DST,
393         ACTION_SET_IPV6_SRC,
394         ACTION_SET_IPV6_SRC_IPV6_SRC,
395         ACTION_SET_IPV6_DST,
396         ACTION_SET_IPV6_DST_IPV6_DST,
397         ACTION_SET_TP_SRC,
398         ACTION_SET_TP_SRC_TP_SRC,
399         ACTION_SET_TP_DST,
400         ACTION_SET_TP_DST_TP_DST,
401         ACTION_MAC_SWAP,
402         ACTION_DEC_TTL,
403         ACTION_SET_TTL,
404         ACTION_SET_TTL_TTL,
405         ACTION_SET_MAC_SRC,
406         ACTION_SET_MAC_SRC_MAC_SRC,
407         ACTION_SET_MAC_DST,
408         ACTION_SET_MAC_DST_MAC_DST,
409         ACTION_INC_TCP_SEQ,
410         ACTION_INC_TCP_SEQ_VALUE,
411         ACTION_DEC_TCP_SEQ,
412         ACTION_DEC_TCP_SEQ_VALUE,
413         ACTION_INC_TCP_ACK,
414         ACTION_INC_TCP_ACK_VALUE,
415         ACTION_DEC_TCP_ACK,
416         ACTION_DEC_TCP_ACK_VALUE,
417         ACTION_RAW_ENCAP,
418         ACTION_RAW_DECAP,
419         ACTION_RAW_ENCAP_INDEX,
420         ACTION_RAW_ENCAP_INDEX_VALUE,
421         ACTION_RAW_DECAP_INDEX,
422         ACTION_RAW_DECAP_INDEX_VALUE,
423         ACTION_SET_TAG,
424         ACTION_SET_TAG_DATA,
425         ACTION_SET_TAG_INDEX,
426         ACTION_SET_TAG_MASK,
427         ACTION_SET_META,
428         ACTION_SET_META_DATA,
429         ACTION_SET_META_MASK,
430         ACTION_SET_IPV4_DSCP,
431         ACTION_SET_IPV4_DSCP_VALUE,
432         ACTION_SET_IPV6_DSCP,
433         ACTION_SET_IPV6_DSCP_VALUE,
434         ACTION_AGE,
435         ACTION_AGE_TIMEOUT,
436         ACTION_SAMPLE,
437         ACTION_SAMPLE_RATIO,
438         ACTION_SAMPLE_INDEX,
439         ACTION_SAMPLE_INDEX_VALUE,
440         ACTION_INDIRECT,
441         INDIRECT_ACTION_ID2PTR,
442         ACTION_MODIFY_FIELD,
443         ACTION_MODIFY_FIELD_OP,
444         ACTION_MODIFY_FIELD_OP_VALUE,
445         ACTION_MODIFY_FIELD_DST_TYPE,
446         ACTION_MODIFY_FIELD_DST_TYPE_VALUE,
447         ACTION_MODIFY_FIELD_DST_LEVEL,
448         ACTION_MODIFY_FIELD_DST_OFFSET,
449         ACTION_MODIFY_FIELD_SRC_TYPE,
450         ACTION_MODIFY_FIELD_SRC_TYPE_VALUE,
451         ACTION_MODIFY_FIELD_SRC_LEVEL,
452         ACTION_MODIFY_FIELD_SRC_OFFSET,
453         ACTION_MODIFY_FIELD_SRC_VALUE,
454         ACTION_MODIFY_FIELD_WIDTH,
455         ACTION_CONNTRACK,
456         ACTION_CONNTRACK_UPDATE,
457         ACTION_CONNTRACK_UPDATE_DIR,
458         ACTION_CONNTRACK_UPDATE_CTX,
459         ACTION_POL_G,
460         ACTION_POL_Y,
461         ACTION_POL_R,
462         ACTION_PORT_REPRESENTOR,
463         ACTION_PORT_REPRESENTOR_PORT_ID,
464 };
465
466 /** Maximum size for pattern in struct rte_flow_item_raw. */
467 #define ITEM_RAW_PATTERN_SIZE 40
468
469 /** Maximum size for GENEVE option data pattern in bytes. */
470 #define ITEM_GENEVE_OPT_DATA_SIZE 124
471
472 /** Storage size for struct rte_flow_item_raw including pattern. */
473 #define ITEM_RAW_SIZE \
474         (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
475
476 /** Maximum number of queue indices in struct rte_flow_action_rss. */
477 #define ACTION_RSS_QUEUE_NUM 128
478
479 /** Storage for struct rte_flow_action_rss including external data. */
480 struct action_rss_data {
481         struct rte_flow_action_rss conf;
482         uint8_t key[RSS_HASH_KEY_LENGTH];
483         uint16_t queue[ACTION_RSS_QUEUE_NUM];
484 };
485
486 /** Maximum data size in struct rte_flow_action_raw_encap. */
487 #define ACTION_RAW_ENCAP_MAX_DATA 512
488 #define RAW_ENCAP_CONFS_MAX_NUM 8
489
490 /** Storage for struct rte_flow_action_raw_encap. */
491 struct raw_encap_conf {
492         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
493         uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA];
494         size_t size;
495 };
496
497 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM];
498
499 /** Storage for struct rte_flow_action_raw_encap including external data. */
500 struct action_raw_encap_data {
501         struct rte_flow_action_raw_encap conf;
502         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
503         uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA];
504         uint16_t idx;
505 };
506
507 /** Storage for struct rte_flow_action_raw_decap. */
508 struct raw_decap_conf {
509         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
510         size_t size;
511 };
512
513 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM];
514
515 /** Storage for struct rte_flow_action_raw_decap including external data. */
516 struct action_raw_decap_data {
517         struct rte_flow_action_raw_decap conf;
518         uint8_t data[ACTION_RAW_ENCAP_MAX_DATA];
519         uint16_t idx;
520 };
521
522 struct vxlan_encap_conf vxlan_encap_conf = {
523         .select_ipv4 = 1,
524         .select_vlan = 0,
525         .select_tos_ttl = 0,
526         .vni = "\x00\x00\x00",
527         .udp_src = 0,
528         .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT),
529         .ipv4_src = RTE_IPV4(127, 0, 0, 1),
530         .ipv4_dst = RTE_IPV4(255, 255, 255, 255),
531         .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
532                 "\x00\x00\x00\x00\x00\x00\x00\x01",
533         .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
534                 "\x00\x00\x00\x00\x00\x00\x11\x11",
535         .vlan_tci = 0,
536         .ip_tos = 0,
537         .ip_ttl = 255,
538         .eth_src = "\x00\x00\x00\x00\x00\x00",
539         .eth_dst = "\xff\xff\xff\xff\xff\xff",
540 };
541
542 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */
543 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6
544
545 /** Storage for struct rte_flow_action_vxlan_encap including external data. */
546 struct action_vxlan_encap_data {
547         struct rte_flow_action_vxlan_encap conf;
548         struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM];
549         struct rte_flow_item_eth item_eth;
550         struct rte_flow_item_vlan item_vlan;
551         union {
552                 struct rte_flow_item_ipv4 item_ipv4;
553                 struct rte_flow_item_ipv6 item_ipv6;
554         };
555         struct rte_flow_item_udp item_udp;
556         struct rte_flow_item_vxlan item_vxlan;
557 };
558
559 struct nvgre_encap_conf nvgre_encap_conf = {
560         .select_ipv4 = 1,
561         .select_vlan = 0,
562         .tni = "\x00\x00\x00",
563         .ipv4_src = RTE_IPV4(127, 0, 0, 1),
564         .ipv4_dst = RTE_IPV4(255, 255, 255, 255),
565         .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
566                 "\x00\x00\x00\x00\x00\x00\x00\x01",
567         .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
568                 "\x00\x00\x00\x00\x00\x00\x11\x11",
569         .vlan_tci = 0,
570         .eth_src = "\x00\x00\x00\x00\x00\x00",
571         .eth_dst = "\xff\xff\xff\xff\xff\xff",
572 };
573
574 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */
575 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5
576
577 /** Storage for struct rte_flow_action_nvgre_encap including external data. */
578 struct action_nvgre_encap_data {
579         struct rte_flow_action_nvgre_encap conf;
580         struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM];
581         struct rte_flow_item_eth item_eth;
582         struct rte_flow_item_vlan item_vlan;
583         union {
584                 struct rte_flow_item_ipv4 item_ipv4;
585                 struct rte_flow_item_ipv6 item_ipv6;
586         };
587         struct rte_flow_item_nvgre item_nvgre;
588 };
589
590 struct l2_encap_conf l2_encap_conf;
591
592 struct l2_decap_conf l2_decap_conf;
593
594 struct mplsogre_encap_conf mplsogre_encap_conf;
595
596 struct mplsogre_decap_conf mplsogre_decap_conf;
597
598 struct mplsoudp_encap_conf mplsoudp_encap_conf;
599
600 struct mplsoudp_decap_conf mplsoudp_decap_conf;
601
602 struct rte_flow_action_conntrack conntrack_context;
603
604 #define ACTION_SAMPLE_ACTIONS_NUM 10
605 #define RAW_SAMPLE_CONFS_MAX_NUM 8
606 /** Storage for struct rte_flow_action_sample including external data. */
607 struct action_sample_data {
608         struct rte_flow_action_sample conf;
609         uint32_t idx;
610 };
611 /** Storage for struct rte_flow_action_sample. */
612 struct raw_sample_conf {
613         struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM];
614 };
615 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM];
616 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM];
617 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM];
618 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM];
619 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM];
620 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM];
621 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM];
622 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM];
623 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM];
624 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM];
625
626 static const char *const modify_field_ops[] = {
627         "set", "add", "sub", NULL
628 };
629
630 static const char *const modify_field_ids[] = {
631         "start", "mac_dst", "mac_src",
632         "vlan_type", "vlan_id", "mac_type",
633         "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst",
634         "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst",
635         "tcp_port_src", "tcp_port_dst",
636         "tcp_seq_num", "tcp_ack_num", "tcp_flags",
637         "udp_port_src", "udp_port_dst",
638         "vxlan_vni", "geneve_vni", "gtp_teid",
639         "tag", "mark", "meta", "pointer", "value", NULL
640 };
641
642 /** Maximum number of subsequent tokens and arguments on the stack. */
643 #define CTX_STACK_SIZE 16
644
645 /** Parser context. */
646 struct context {
647         /** Stack of subsequent token lists to process. */
648         const enum index *next[CTX_STACK_SIZE];
649         /** Arguments for stacked tokens. */
650         const void *args[CTX_STACK_SIZE];
651         enum index curr; /**< Current token index. */
652         enum index prev; /**< Index of the last token seen. */
653         int next_num; /**< Number of entries in next[]. */
654         int args_num; /**< Number of entries in args[]. */
655         uint32_t eol:1; /**< EOL has been detected. */
656         uint32_t last:1; /**< No more arguments. */
657         portid_t port; /**< Current port ID (for completions). */
658         uint32_t objdata; /**< Object-specific data. */
659         void *object; /**< Address of current object for relative offsets. */
660         void *objmask; /**< Object a full mask must be written to. */
661 };
662
663 /** Token argument. */
664 struct arg {
665         uint32_t hton:1; /**< Use network byte ordering. */
666         uint32_t sign:1; /**< Value is signed. */
667         uint32_t bounded:1; /**< Value is bounded. */
668         uintmax_t min; /**< Minimum value if bounded. */
669         uintmax_t max; /**< Maximum value if bounded. */
670         uint32_t offset; /**< Relative offset from ctx->object. */
671         uint32_t size; /**< Field size. */
672         const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */
673 };
674
675 /** Parser token definition. */
676 struct token {
677         /** Type displayed during completion (defaults to "TOKEN"). */
678         const char *type;
679         /** Help displayed during completion (defaults to token name). */
680         const char *help;
681         /** Private data used by parser functions. */
682         const void *priv;
683         /**
684          * Lists of subsequent tokens to push on the stack. Each call to the
685          * parser consumes the last entry of that stack.
686          */
687         const enum index *const *next;
688         /** Arguments stack for subsequent tokens that need them. */
689         const struct arg *const *args;
690         /**
691          * Token-processing callback, returns -1 in case of error, the
692          * length of the matched string otherwise. If NULL, attempts to
693          * match the token name.
694          *
695          * If buf is not NULL, the result should be stored in it according
696          * to context. An error is returned if not large enough.
697          */
698         int (*call)(struct context *ctx, const struct token *token,
699                     const char *str, unsigned int len,
700                     void *buf, unsigned int size);
701         /**
702          * Callback that provides possible values for this token, used for
703          * completion. Returns -1 in case of error, the number of possible
704          * values otherwise. If NULL, the token name is used.
705          *
706          * If buf is not NULL, entry index ent is written to buf and the
707          * full length of the entry is returned (same behavior as
708          * snprintf()).
709          */
710         int (*comp)(struct context *ctx, const struct token *token,
711                     unsigned int ent, char *buf, unsigned int size);
712         /** Mandatory token name, no default value. */
713         const char *name;
714 };
715
716 /** Static initializer for the next field. */
717 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, }
718
719 /** Static initializer for a NEXT() entry. */
720 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, }
721
722 /** Static initializer for the args field. */
723 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, }
724
725 /** Static initializer for ARGS() to target a field. */
726 #define ARGS_ENTRY(s, f) \
727         (&(const struct arg){ \
728                 .offset = offsetof(s, f), \
729                 .size = sizeof(((s *)0)->f), \
730         })
731
732 /** Static initializer for ARGS() to target a bit-field. */
733 #define ARGS_ENTRY_BF(s, f, b) \
734         (&(const struct arg){ \
735                 .size = sizeof(s), \
736                 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \
737         })
738
739 /** Static initializer for ARGS() to target a field with limits. */
740 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \
741         (&(const struct arg){ \
742                 .bounded = 1, \
743                 .min = (i), \
744                 .max = (a), \
745                 .offset = offsetof(s, f), \
746                 .size = sizeof(((s *)0)->f), \
747         })
748
749 /** Static initializer for ARGS() to target an arbitrary bit-mask. */
750 #define ARGS_ENTRY_MASK(s, f, m) \
751         (&(const struct arg){ \
752                 .offset = offsetof(s, f), \
753                 .size = sizeof(((s *)0)->f), \
754                 .mask = (const void *)(m), \
755         })
756
757 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */
758 #define ARGS_ENTRY_MASK_HTON(s, f, m) \
759         (&(const struct arg){ \
760                 .hton = 1, \
761                 .offset = offsetof(s, f), \
762                 .size = sizeof(((s *)0)->f), \
763                 .mask = (const void *)(m), \
764         })
765
766 /** Static initializer for ARGS() to target a pointer. */
767 #define ARGS_ENTRY_PTR(s, f) \
768         (&(const struct arg){ \
769                 .size = sizeof(*((s *)0)->f), \
770         })
771
772 /** Static initializer for ARGS() with arbitrary offset and size. */
773 #define ARGS_ENTRY_ARB(o, s) \
774         (&(const struct arg){ \
775                 .offset = (o), \
776                 .size = (s), \
777         })
778
779 /** Same as ARGS_ENTRY_ARB() with bounded values. */
780 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \
781         (&(const struct arg){ \
782                 .bounded = 1, \
783                 .min = (i), \
784                 .max = (a), \
785                 .offset = (o), \
786                 .size = (s), \
787         })
788
789 /** Same as ARGS_ENTRY() using network byte ordering. */
790 #define ARGS_ENTRY_HTON(s, f) \
791         (&(const struct arg){ \
792                 .hton = 1, \
793                 .offset = offsetof(s, f), \
794                 .size = sizeof(((s *)0)->f), \
795         })
796
797 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */
798 #define ARG_ENTRY_HTON(s) \
799         (&(const struct arg){ \
800                 .hton = 1, \
801                 .offset = 0, \
802                 .size = sizeof(s), \
803         })
804
805 /** Parser output buffer layout expected by cmd_flow_parsed(). */
806 struct buffer {
807         enum index command; /**< Flow command. */
808         portid_t port; /**< Affected port ID. */
809         union {
810                 struct {
811                         uint32_t *action_id;
812                         uint32_t action_id_n;
813                 } ia_destroy; /**< Indirect action destroy arguments. */
814                 struct {
815                         uint32_t action_id;
816                 } ia; /* Indirect action query arguments */
817                 struct {
818                         struct rte_flow_attr attr;
819                         struct tunnel_ops tunnel_ops;
820                         struct rte_flow_item *pattern;
821                         struct rte_flow_action *actions;
822                         uint32_t pattern_n;
823                         uint32_t actions_n;
824                         uint8_t *data;
825                 } vc; /**< Validate/create arguments. */
826                 struct {
827                         uint32_t *rule;
828                         uint32_t rule_n;
829                 } destroy; /**< Destroy arguments. */
830                 struct {
831                         char file[128];
832                         bool mode;
833                         uint32_t rule;
834                 } dump; /**< Dump arguments. */
835                 struct {
836                         uint32_t rule;
837                         struct rte_flow_action action;
838                 } query; /**< Query arguments. */
839                 struct {
840                         uint32_t *group;
841                         uint32_t group_n;
842                 } list; /**< List arguments. */
843                 struct {
844                         int set;
845                 } isolate; /**< Isolated mode arguments. */
846                 struct {
847                         int destroy;
848                 } aged; /**< Aged arguments. */
849                 struct {
850                         uint32_t policy_id;
851                 } policy;/**< Policy arguments. */
852         } args; /**< Command arguments. */
853 };
854
855 /** Private data for pattern items. */
856 struct parse_item_priv {
857         enum rte_flow_item_type type; /**< Item type. */
858         uint32_t size; /**< Size of item specification structure. */
859 };
860
861 #define PRIV_ITEM(t, s) \
862         (&(const struct parse_item_priv){ \
863                 .type = RTE_FLOW_ITEM_TYPE_ ## t, \
864                 .size = s, \
865         })
866
867 /** Private data for actions. */
868 struct parse_action_priv {
869         enum rte_flow_action_type type; /**< Action type. */
870         uint32_t size; /**< Size of action configuration structure. */
871 };
872
873 #define PRIV_ACTION(t, s) \
874         (&(const struct parse_action_priv){ \
875                 .type = RTE_FLOW_ACTION_TYPE_ ## t, \
876                 .size = s, \
877         })
878
879 static const enum index next_ia_create_attr[] = {
880         INDIRECT_ACTION_CREATE_ID,
881         INDIRECT_ACTION_INGRESS,
882         INDIRECT_ACTION_EGRESS,
883         INDIRECT_ACTION_TRANSFER,
884         INDIRECT_ACTION_SPEC,
885         ZERO,
886 };
887
888 static const enum index next_dump_subcmd[] = {
889         DUMP_ALL,
890         DUMP_ONE,
891         ZERO,
892 };
893
894 static const enum index next_ia_subcmd[] = {
895         INDIRECT_ACTION_CREATE,
896         INDIRECT_ACTION_UPDATE,
897         INDIRECT_ACTION_DESTROY,
898         INDIRECT_ACTION_QUERY,
899         ZERO,
900 };
901
902 static const enum index next_vc_attr[] = {
903         VC_GROUP,
904         VC_PRIORITY,
905         VC_INGRESS,
906         VC_EGRESS,
907         VC_TRANSFER,
908         VC_TUNNEL_SET,
909         VC_TUNNEL_MATCH,
910         ITEM_PATTERN,
911         ZERO,
912 };
913
914 static const enum index next_destroy_attr[] = {
915         DESTROY_RULE,
916         END,
917         ZERO,
918 };
919
920 static const enum index next_dump_attr[] = {
921         COMMON_FILE_PATH,
922         END,
923         ZERO,
924 };
925
926 static const enum index next_list_attr[] = {
927         LIST_GROUP,
928         END,
929         ZERO,
930 };
931
932 static const enum index next_aged_attr[] = {
933         AGED_DESTROY,
934         END,
935         ZERO,
936 };
937
938 static const enum index next_ia_destroy_attr[] = {
939         INDIRECT_ACTION_DESTROY_ID,
940         END,
941         ZERO,
942 };
943
944 static const enum index item_param[] = {
945         ITEM_PARAM_IS,
946         ITEM_PARAM_SPEC,
947         ITEM_PARAM_LAST,
948         ITEM_PARAM_MASK,
949         ITEM_PARAM_PREFIX,
950         ZERO,
951 };
952
953 static const enum index next_item[] = {
954         ITEM_END,
955         ITEM_VOID,
956         ITEM_INVERT,
957         ITEM_ANY,
958         ITEM_PF,
959         ITEM_VF,
960         ITEM_PHY_PORT,
961         ITEM_PORT_ID,
962         ITEM_MARK,
963         ITEM_RAW,
964         ITEM_ETH,
965         ITEM_VLAN,
966         ITEM_IPV4,
967         ITEM_IPV6,
968         ITEM_ICMP,
969         ITEM_UDP,
970         ITEM_TCP,
971         ITEM_SCTP,
972         ITEM_VXLAN,
973         ITEM_E_TAG,
974         ITEM_NVGRE,
975         ITEM_MPLS,
976         ITEM_GRE,
977         ITEM_FUZZY,
978         ITEM_GTP,
979         ITEM_GTPC,
980         ITEM_GTPU,
981         ITEM_GENEVE,
982         ITEM_VXLAN_GPE,
983         ITEM_ARP_ETH_IPV4,
984         ITEM_IPV6_EXT,
985         ITEM_IPV6_FRAG_EXT,
986         ITEM_ICMP6,
987         ITEM_ICMP6_ND_NS,
988         ITEM_ICMP6_ND_NA,
989         ITEM_ICMP6_ND_OPT,
990         ITEM_ICMP6_ND_OPT_SLA_ETH,
991         ITEM_ICMP6_ND_OPT_TLA_ETH,
992         ITEM_META,
993         ITEM_GRE_KEY,
994         ITEM_GTP_PSC,
995         ITEM_PPPOES,
996         ITEM_PPPOED,
997         ITEM_PPPOE_PROTO_ID,
998         ITEM_HIGIG2,
999         ITEM_TAG,
1000         ITEM_L2TPV3OIP,
1001         ITEM_ESP,
1002         ITEM_AH,
1003         ITEM_PFCP,
1004         ITEM_ECPRI,
1005         ITEM_GENEVE_OPT,
1006         ITEM_INTEGRITY,
1007         ITEM_CONNTRACK,
1008         ITEM_PORT_REPRESENTOR,
1009         ITEM_REPRESENTED_PORT,
1010         END_SET,
1011         ZERO,
1012 };
1013
1014 static const enum index item_fuzzy[] = {
1015         ITEM_FUZZY_THRESH,
1016         ITEM_NEXT,
1017         ZERO,
1018 };
1019
1020 static const enum index item_any[] = {
1021         ITEM_ANY_NUM,
1022         ITEM_NEXT,
1023         ZERO,
1024 };
1025
1026 static const enum index item_vf[] = {
1027         ITEM_VF_ID,
1028         ITEM_NEXT,
1029         ZERO,
1030 };
1031
1032 static const enum index item_phy_port[] = {
1033         ITEM_PHY_PORT_INDEX,
1034         ITEM_NEXT,
1035         ZERO,
1036 };
1037
1038 static const enum index item_port_id[] = {
1039         ITEM_PORT_ID_ID,
1040         ITEM_NEXT,
1041         ZERO,
1042 };
1043
1044 static const enum index item_mark[] = {
1045         ITEM_MARK_ID,
1046         ITEM_NEXT,
1047         ZERO,
1048 };
1049
1050 static const enum index item_raw[] = {
1051         ITEM_RAW_RELATIVE,
1052         ITEM_RAW_SEARCH,
1053         ITEM_RAW_OFFSET,
1054         ITEM_RAW_LIMIT,
1055         ITEM_RAW_PATTERN,
1056         ITEM_NEXT,
1057         ZERO,
1058 };
1059
1060 static const enum index item_eth[] = {
1061         ITEM_ETH_DST,
1062         ITEM_ETH_SRC,
1063         ITEM_ETH_TYPE,
1064         ITEM_ETH_HAS_VLAN,
1065         ITEM_NEXT,
1066         ZERO,
1067 };
1068
1069 static const enum index item_vlan[] = {
1070         ITEM_VLAN_TCI,
1071         ITEM_VLAN_PCP,
1072         ITEM_VLAN_DEI,
1073         ITEM_VLAN_VID,
1074         ITEM_VLAN_INNER_TYPE,
1075         ITEM_VLAN_HAS_MORE_VLAN,
1076         ITEM_NEXT,
1077         ZERO,
1078 };
1079
1080 static const enum index item_ipv4[] = {
1081         ITEM_IPV4_VER_IHL,
1082         ITEM_IPV4_TOS,
1083         ITEM_IPV4_ID,
1084         ITEM_IPV4_FRAGMENT_OFFSET,
1085         ITEM_IPV4_TTL,
1086         ITEM_IPV4_PROTO,
1087         ITEM_IPV4_SRC,
1088         ITEM_IPV4_DST,
1089         ITEM_NEXT,
1090         ZERO,
1091 };
1092
1093 static const enum index item_ipv6[] = {
1094         ITEM_IPV6_TC,
1095         ITEM_IPV6_FLOW,
1096         ITEM_IPV6_PROTO,
1097         ITEM_IPV6_HOP,
1098         ITEM_IPV6_SRC,
1099         ITEM_IPV6_DST,
1100         ITEM_IPV6_HAS_FRAG_EXT,
1101         ITEM_NEXT,
1102         ZERO,
1103 };
1104
1105 static const enum index item_icmp[] = {
1106         ITEM_ICMP_TYPE,
1107         ITEM_ICMP_CODE,
1108         ITEM_ICMP_IDENT,
1109         ITEM_ICMP_SEQ,
1110         ITEM_NEXT,
1111         ZERO,
1112 };
1113
1114 static const enum index item_udp[] = {
1115         ITEM_UDP_SRC,
1116         ITEM_UDP_DST,
1117         ITEM_NEXT,
1118         ZERO,
1119 };
1120
1121 static const enum index item_tcp[] = {
1122         ITEM_TCP_SRC,
1123         ITEM_TCP_DST,
1124         ITEM_TCP_FLAGS,
1125         ITEM_NEXT,
1126         ZERO,
1127 };
1128
1129 static const enum index item_sctp[] = {
1130         ITEM_SCTP_SRC,
1131         ITEM_SCTP_DST,
1132         ITEM_SCTP_TAG,
1133         ITEM_SCTP_CKSUM,
1134         ITEM_NEXT,
1135         ZERO,
1136 };
1137
1138 static const enum index item_vxlan[] = {
1139         ITEM_VXLAN_VNI,
1140         ITEM_VXLAN_LAST_RSVD,
1141         ITEM_NEXT,
1142         ZERO,
1143 };
1144
1145 static const enum index item_e_tag[] = {
1146         ITEM_E_TAG_GRP_ECID_B,
1147         ITEM_NEXT,
1148         ZERO,
1149 };
1150
1151 static const enum index item_nvgre[] = {
1152         ITEM_NVGRE_TNI,
1153         ITEM_NEXT,
1154         ZERO,
1155 };
1156
1157 static const enum index item_mpls[] = {
1158         ITEM_MPLS_LABEL,
1159         ITEM_MPLS_TC,
1160         ITEM_MPLS_S,
1161         ITEM_NEXT,
1162         ZERO,
1163 };
1164
1165 static const enum index item_gre[] = {
1166         ITEM_GRE_PROTO,
1167         ITEM_GRE_C_RSVD0_VER,
1168         ITEM_GRE_C_BIT,
1169         ITEM_GRE_K_BIT,
1170         ITEM_GRE_S_BIT,
1171         ITEM_NEXT,
1172         ZERO,
1173 };
1174
1175 static const enum index item_gre_key[] = {
1176         ITEM_GRE_KEY_VALUE,
1177         ITEM_NEXT,
1178         ZERO,
1179 };
1180
1181 static const enum index item_gtp[] = {
1182         ITEM_GTP_FLAGS,
1183         ITEM_GTP_MSG_TYPE,
1184         ITEM_GTP_TEID,
1185         ITEM_NEXT,
1186         ZERO,
1187 };
1188
1189 static const enum index item_geneve[] = {
1190         ITEM_GENEVE_VNI,
1191         ITEM_GENEVE_PROTO,
1192         ITEM_GENEVE_OPTLEN,
1193         ITEM_NEXT,
1194         ZERO,
1195 };
1196
1197 static const enum index item_vxlan_gpe[] = {
1198         ITEM_VXLAN_GPE_VNI,
1199         ITEM_NEXT,
1200         ZERO,
1201 };
1202
1203 static const enum index item_arp_eth_ipv4[] = {
1204         ITEM_ARP_ETH_IPV4_SHA,
1205         ITEM_ARP_ETH_IPV4_SPA,
1206         ITEM_ARP_ETH_IPV4_THA,
1207         ITEM_ARP_ETH_IPV4_TPA,
1208         ITEM_NEXT,
1209         ZERO,
1210 };
1211
1212 static const enum index item_ipv6_ext[] = {
1213         ITEM_IPV6_EXT_NEXT_HDR,
1214         ITEM_NEXT,
1215         ZERO,
1216 };
1217
1218 static const enum index item_ipv6_frag_ext[] = {
1219         ITEM_IPV6_FRAG_EXT_NEXT_HDR,
1220         ITEM_IPV6_FRAG_EXT_FRAG_DATA,
1221         ITEM_IPV6_FRAG_EXT_ID,
1222         ITEM_NEXT,
1223         ZERO,
1224 };
1225
1226 static const enum index item_icmp6[] = {
1227         ITEM_ICMP6_TYPE,
1228         ITEM_ICMP6_CODE,
1229         ITEM_NEXT,
1230         ZERO,
1231 };
1232
1233 static const enum index item_icmp6_nd_ns[] = {
1234         ITEM_ICMP6_ND_NS_TARGET_ADDR,
1235         ITEM_NEXT,
1236         ZERO,
1237 };
1238
1239 static const enum index item_icmp6_nd_na[] = {
1240         ITEM_ICMP6_ND_NA_TARGET_ADDR,
1241         ITEM_NEXT,
1242         ZERO,
1243 };
1244
1245 static const enum index item_icmp6_nd_opt[] = {
1246         ITEM_ICMP6_ND_OPT_TYPE,
1247         ITEM_NEXT,
1248         ZERO,
1249 };
1250
1251 static const enum index item_icmp6_nd_opt_sla_eth[] = {
1252         ITEM_ICMP6_ND_OPT_SLA_ETH_SLA,
1253         ITEM_NEXT,
1254         ZERO,
1255 };
1256
1257 static const enum index item_icmp6_nd_opt_tla_eth[] = {
1258         ITEM_ICMP6_ND_OPT_TLA_ETH_TLA,
1259         ITEM_NEXT,
1260         ZERO,
1261 };
1262
1263 static const enum index item_meta[] = {
1264         ITEM_META_DATA,
1265         ITEM_NEXT,
1266         ZERO,
1267 };
1268
1269 static const enum index item_gtp_psc[] = {
1270         ITEM_GTP_PSC_QFI,
1271         ITEM_GTP_PSC_PDU_T,
1272         ITEM_NEXT,
1273         ZERO,
1274 };
1275
1276 static const enum index item_pppoed[] = {
1277         ITEM_PPPOE_SEID,
1278         ITEM_NEXT,
1279         ZERO,
1280 };
1281
1282 static const enum index item_pppoes[] = {
1283         ITEM_PPPOE_SEID,
1284         ITEM_NEXT,
1285         ZERO,
1286 };
1287
1288 static const enum index item_pppoe_proto_id[] = {
1289         ITEM_NEXT,
1290         ZERO,
1291 };
1292
1293 static const enum index item_higig2[] = {
1294         ITEM_HIGIG2_CLASSIFICATION,
1295         ITEM_HIGIG2_VID,
1296         ITEM_NEXT,
1297         ZERO,
1298 };
1299
1300 static const enum index item_esp[] = {
1301         ITEM_ESP_SPI,
1302         ITEM_NEXT,
1303         ZERO,
1304 };
1305
1306 static const enum index item_ah[] = {
1307         ITEM_AH_SPI,
1308         ITEM_NEXT,
1309         ZERO,
1310 };
1311
1312 static const enum index item_pfcp[] = {
1313         ITEM_PFCP_S_FIELD,
1314         ITEM_PFCP_SEID,
1315         ITEM_NEXT,
1316         ZERO,
1317 };
1318
1319 static const enum index next_set_raw[] = {
1320         SET_RAW_INDEX,
1321         ITEM_ETH,
1322         ZERO,
1323 };
1324
1325 static const enum index item_tag[] = {
1326         ITEM_TAG_DATA,
1327         ITEM_TAG_INDEX,
1328         ITEM_NEXT,
1329         ZERO,
1330 };
1331
1332 static const enum index item_l2tpv3oip[] = {
1333         ITEM_L2TPV3OIP_SESSION_ID,
1334         ITEM_NEXT,
1335         ZERO,
1336 };
1337
1338 static const enum index item_ecpri[] = {
1339         ITEM_ECPRI_COMMON,
1340         ITEM_NEXT,
1341         ZERO,
1342 };
1343
1344 static const enum index item_ecpri_common[] = {
1345         ITEM_ECPRI_COMMON_TYPE,
1346         ZERO,
1347 };
1348
1349 static const enum index item_ecpri_common_type[] = {
1350         ITEM_ECPRI_COMMON_TYPE_IQ_DATA,
1351         ITEM_ECPRI_COMMON_TYPE_RTC_CTRL,
1352         ITEM_ECPRI_COMMON_TYPE_DLY_MSR,
1353         ZERO,
1354 };
1355
1356 static const enum index item_geneve_opt[] = {
1357         ITEM_GENEVE_OPT_CLASS,
1358         ITEM_GENEVE_OPT_TYPE,
1359         ITEM_GENEVE_OPT_LENGTH,
1360         ITEM_GENEVE_OPT_DATA,
1361         ITEM_NEXT,
1362         ZERO,
1363 };
1364
1365 static const enum index item_integrity[] = {
1366         ITEM_INTEGRITY_LEVEL,
1367         ITEM_INTEGRITY_VALUE,
1368         ZERO,
1369 };
1370
1371 static const enum index item_integrity_lv[] = {
1372         ITEM_INTEGRITY_LEVEL,
1373         ITEM_INTEGRITY_VALUE,
1374         ITEM_NEXT,
1375         ZERO,
1376 };
1377
1378 static const enum index item_port_representor[] = {
1379         ITEM_PORT_REPRESENTOR_PORT_ID,
1380         ITEM_NEXT,
1381         ZERO,
1382 };
1383
1384 static const enum index item_represented_port[] = {
1385         ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
1386         ITEM_NEXT,
1387         ZERO,
1388 };
1389
1390 static const enum index next_action[] = {
1391         ACTION_END,
1392         ACTION_VOID,
1393         ACTION_PASSTHRU,
1394         ACTION_JUMP,
1395         ACTION_MARK,
1396         ACTION_FLAG,
1397         ACTION_QUEUE,
1398         ACTION_DROP,
1399         ACTION_COUNT,
1400         ACTION_RSS,
1401         ACTION_PF,
1402         ACTION_VF,
1403         ACTION_PHY_PORT,
1404         ACTION_PORT_ID,
1405         ACTION_METER,
1406         ACTION_METER_COLOR,
1407         ACTION_OF_SET_MPLS_TTL,
1408         ACTION_OF_DEC_MPLS_TTL,
1409         ACTION_OF_SET_NW_TTL,
1410         ACTION_OF_DEC_NW_TTL,
1411         ACTION_OF_COPY_TTL_OUT,
1412         ACTION_OF_COPY_TTL_IN,
1413         ACTION_OF_POP_VLAN,
1414         ACTION_OF_PUSH_VLAN,
1415         ACTION_OF_SET_VLAN_VID,
1416         ACTION_OF_SET_VLAN_PCP,
1417         ACTION_OF_POP_MPLS,
1418         ACTION_OF_PUSH_MPLS,
1419         ACTION_VXLAN_ENCAP,
1420         ACTION_VXLAN_DECAP,
1421         ACTION_NVGRE_ENCAP,
1422         ACTION_NVGRE_DECAP,
1423         ACTION_L2_ENCAP,
1424         ACTION_L2_DECAP,
1425         ACTION_MPLSOGRE_ENCAP,
1426         ACTION_MPLSOGRE_DECAP,
1427         ACTION_MPLSOUDP_ENCAP,
1428         ACTION_MPLSOUDP_DECAP,
1429         ACTION_SET_IPV4_SRC,
1430         ACTION_SET_IPV4_DST,
1431         ACTION_SET_IPV6_SRC,
1432         ACTION_SET_IPV6_DST,
1433         ACTION_SET_TP_SRC,
1434         ACTION_SET_TP_DST,
1435         ACTION_MAC_SWAP,
1436         ACTION_DEC_TTL,
1437         ACTION_SET_TTL,
1438         ACTION_SET_MAC_SRC,
1439         ACTION_SET_MAC_DST,
1440         ACTION_INC_TCP_SEQ,
1441         ACTION_DEC_TCP_SEQ,
1442         ACTION_INC_TCP_ACK,
1443         ACTION_DEC_TCP_ACK,
1444         ACTION_RAW_ENCAP,
1445         ACTION_RAW_DECAP,
1446         ACTION_SET_TAG,
1447         ACTION_SET_META,
1448         ACTION_SET_IPV4_DSCP,
1449         ACTION_SET_IPV6_DSCP,
1450         ACTION_AGE,
1451         ACTION_SAMPLE,
1452         ACTION_INDIRECT,
1453         ACTION_MODIFY_FIELD,
1454         ACTION_CONNTRACK,
1455         ACTION_CONNTRACK_UPDATE,
1456         ACTION_PORT_REPRESENTOR,
1457         ZERO,
1458 };
1459
1460 static const enum index action_mark[] = {
1461         ACTION_MARK_ID,
1462         ACTION_NEXT,
1463         ZERO,
1464 };
1465
1466 static const enum index action_queue[] = {
1467         ACTION_QUEUE_INDEX,
1468         ACTION_NEXT,
1469         ZERO,
1470 };
1471
1472 static const enum index action_count[] = {
1473         ACTION_COUNT_ID,
1474         ACTION_NEXT,
1475         ZERO,
1476 };
1477
1478 static const enum index action_rss[] = {
1479         ACTION_RSS_FUNC,
1480         ACTION_RSS_LEVEL,
1481         ACTION_RSS_TYPES,
1482         ACTION_RSS_KEY,
1483         ACTION_RSS_KEY_LEN,
1484         ACTION_RSS_QUEUES,
1485         ACTION_NEXT,
1486         ZERO,
1487 };
1488
1489 static const enum index action_vf[] = {
1490         ACTION_VF_ORIGINAL,
1491         ACTION_VF_ID,
1492         ACTION_NEXT,
1493         ZERO,
1494 };
1495
1496 static const enum index action_phy_port[] = {
1497         ACTION_PHY_PORT_ORIGINAL,
1498         ACTION_PHY_PORT_INDEX,
1499         ACTION_NEXT,
1500         ZERO,
1501 };
1502
1503 static const enum index action_port_id[] = {
1504         ACTION_PORT_ID_ORIGINAL,
1505         ACTION_PORT_ID_ID,
1506         ACTION_NEXT,
1507         ZERO,
1508 };
1509
1510 static const enum index action_meter[] = {
1511         ACTION_METER_ID,
1512         ACTION_NEXT,
1513         ZERO,
1514 };
1515
1516 static const enum index action_meter_color[] = {
1517         ACTION_METER_COLOR_TYPE,
1518         ACTION_NEXT,
1519         ZERO,
1520 };
1521
1522 static const enum index action_of_set_mpls_ttl[] = {
1523         ACTION_OF_SET_MPLS_TTL_MPLS_TTL,
1524         ACTION_NEXT,
1525         ZERO,
1526 };
1527
1528 static const enum index action_of_set_nw_ttl[] = {
1529         ACTION_OF_SET_NW_TTL_NW_TTL,
1530         ACTION_NEXT,
1531         ZERO,
1532 };
1533
1534 static const enum index action_of_push_vlan[] = {
1535         ACTION_OF_PUSH_VLAN_ETHERTYPE,
1536         ACTION_NEXT,
1537         ZERO,
1538 };
1539
1540 static const enum index action_of_set_vlan_vid[] = {
1541         ACTION_OF_SET_VLAN_VID_VLAN_VID,
1542         ACTION_NEXT,
1543         ZERO,
1544 };
1545
1546 static const enum index action_of_set_vlan_pcp[] = {
1547         ACTION_OF_SET_VLAN_PCP_VLAN_PCP,
1548         ACTION_NEXT,
1549         ZERO,
1550 };
1551
1552 static const enum index action_of_pop_mpls[] = {
1553         ACTION_OF_POP_MPLS_ETHERTYPE,
1554         ACTION_NEXT,
1555         ZERO,
1556 };
1557
1558 static const enum index action_of_push_mpls[] = {
1559         ACTION_OF_PUSH_MPLS_ETHERTYPE,
1560         ACTION_NEXT,
1561         ZERO,
1562 };
1563
1564 static const enum index action_set_ipv4_src[] = {
1565         ACTION_SET_IPV4_SRC_IPV4_SRC,
1566         ACTION_NEXT,
1567         ZERO,
1568 };
1569
1570 static const enum index action_set_mac_src[] = {
1571         ACTION_SET_MAC_SRC_MAC_SRC,
1572         ACTION_NEXT,
1573         ZERO,
1574 };
1575
1576 static const enum index action_set_ipv4_dst[] = {
1577         ACTION_SET_IPV4_DST_IPV4_DST,
1578         ACTION_NEXT,
1579         ZERO,
1580 };
1581
1582 static const enum index action_set_ipv6_src[] = {
1583         ACTION_SET_IPV6_SRC_IPV6_SRC,
1584         ACTION_NEXT,
1585         ZERO,
1586 };
1587
1588 static const enum index action_set_ipv6_dst[] = {
1589         ACTION_SET_IPV6_DST_IPV6_DST,
1590         ACTION_NEXT,
1591         ZERO,
1592 };
1593
1594 static const enum index action_set_tp_src[] = {
1595         ACTION_SET_TP_SRC_TP_SRC,
1596         ACTION_NEXT,
1597         ZERO,
1598 };
1599
1600 static const enum index action_set_tp_dst[] = {
1601         ACTION_SET_TP_DST_TP_DST,
1602         ACTION_NEXT,
1603         ZERO,
1604 };
1605
1606 static const enum index action_set_ttl[] = {
1607         ACTION_SET_TTL_TTL,
1608         ACTION_NEXT,
1609         ZERO,
1610 };
1611
1612 static const enum index action_jump[] = {
1613         ACTION_JUMP_GROUP,
1614         ACTION_NEXT,
1615         ZERO,
1616 };
1617
1618 static const enum index action_set_mac_dst[] = {
1619         ACTION_SET_MAC_DST_MAC_DST,
1620         ACTION_NEXT,
1621         ZERO,
1622 };
1623
1624 static const enum index action_inc_tcp_seq[] = {
1625         ACTION_INC_TCP_SEQ_VALUE,
1626         ACTION_NEXT,
1627         ZERO,
1628 };
1629
1630 static const enum index action_dec_tcp_seq[] = {
1631         ACTION_DEC_TCP_SEQ_VALUE,
1632         ACTION_NEXT,
1633         ZERO,
1634 };
1635
1636 static const enum index action_inc_tcp_ack[] = {
1637         ACTION_INC_TCP_ACK_VALUE,
1638         ACTION_NEXT,
1639         ZERO,
1640 };
1641
1642 static const enum index action_dec_tcp_ack[] = {
1643         ACTION_DEC_TCP_ACK_VALUE,
1644         ACTION_NEXT,
1645         ZERO,
1646 };
1647
1648 static const enum index action_raw_encap[] = {
1649         ACTION_RAW_ENCAP_INDEX,
1650         ACTION_NEXT,
1651         ZERO,
1652 };
1653
1654 static const enum index action_raw_decap[] = {
1655         ACTION_RAW_DECAP_INDEX,
1656         ACTION_NEXT,
1657         ZERO,
1658 };
1659
1660 static const enum index action_set_tag[] = {
1661         ACTION_SET_TAG_DATA,
1662         ACTION_SET_TAG_INDEX,
1663         ACTION_SET_TAG_MASK,
1664         ACTION_NEXT,
1665         ZERO,
1666 };
1667
1668 static const enum index action_set_meta[] = {
1669         ACTION_SET_META_DATA,
1670         ACTION_SET_META_MASK,
1671         ACTION_NEXT,
1672         ZERO,
1673 };
1674
1675 static const enum index action_set_ipv4_dscp[] = {
1676         ACTION_SET_IPV4_DSCP_VALUE,
1677         ACTION_NEXT,
1678         ZERO,
1679 };
1680
1681 static const enum index action_set_ipv6_dscp[] = {
1682         ACTION_SET_IPV6_DSCP_VALUE,
1683         ACTION_NEXT,
1684         ZERO,
1685 };
1686
1687 static const enum index action_age[] = {
1688         ACTION_AGE,
1689         ACTION_AGE_TIMEOUT,
1690         ACTION_NEXT,
1691         ZERO,
1692 };
1693
1694 static const enum index action_sample[] = {
1695         ACTION_SAMPLE,
1696         ACTION_SAMPLE_RATIO,
1697         ACTION_SAMPLE_INDEX,
1698         ACTION_NEXT,
1699         ZERO,
1700 };
1701
1702 static const enum index next_action_sample[] = {
1703         ACTION_QUEUE,
1704         ACTION_RSS,
1705         ACTION_MARK,
1706         ACTION_COUNT,
1707         ACTION_PORT_ID,
1708         ACTION_RAW_ENCAP,
1709         ACTION_VXLAN_ENCAP,
1710         ACTION_NVGRE_ENCAP,
1711         ACTION_NEXT,
1712         ZERO,
1713 };
1714
1715 static const enum index action_modify_field_dst[] = {
1716         ACTION_MODIFY_FIELD_DST_LEVEL,
1717         ACTION_MODIFY_FIELD_DST_OFFSET,
1718         ACTION_MODIFY_FIELD_SRC_TYPE,
1719         ZERO,
1720 };
1721
1722 static const enum index action_modify_field_src[] = {
1723         ACTION_MODIFY_FIELD_SRC_LEVEL,
1724         ACTION_MODIFY_FIELD_SRC_OFFSET,
1725         ACTION_MODIFY_FIELD_SRC_VALUE,
1726         ACTION_MODIFY_FIELD_WIDTH,
1727         ZERO,
1728 };
1729
1730 static const enum index action_update_conntrack[] = {
1731         ACTION_CONNTRACK_UPDATE_DIR,
1732         ACTION_CONNTRACK_UPDATE_CTX,
1733         ACTION_NEXT,
1734         ZERO,
1735 };
1736
1737 static const enum index action_port_representor[] = {
1738         ACTION_PORT_REPRESENTOR_PORT_ID,
1739         ACTION_NEXT,
1740         ZERO,
1741 };
1742
1743 static int parse_set_raw_encap_decap(struct context *, const struct token *,
1744                                      const char *, unsigned int,
1745                                      void *, unsigned int);
1746 static int parse_set_sample_action(struct context *, const struct token *,
1747                                    const char *, unsigned int,
1748                                    void *, unsigned int);
1749 static int parse_set_init(struct context *, const struct token *,
1750                           const char *, unsigned int,
1751                           void *, unsigned int);
1752 static int parse_init(struct context *, const struct token *,
1753                       const char *, unsigned int,
1754                       void *, unsigned int);
1755 static int parse_vc(struct context *, const struct token *,
1756                     const char *, unsigned int,
1757                     void *, unsigned int);
1758 static int parse_vc_spec(struct context *, const struct token *,
1759                          const char *, unsigned int, void *, unsigned int);
1760 static int parse_vc_conf(struct context *, const struct token *,
1761                          const char *, unsigned int, void *, unsigned int);
1762 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
1763                                     const char *, unsigned int,
1764                                     void *, unsigned int);
1765 static int parse_vc_action_meter_color_type(struct context *,
1766                                         const struct token *,
1767                                         const char *, unsigned int, void *,
1768                                         unsigned int);
1769 static int parse_vc_action_rss(struct context *, const struct token *,
1770                                const char *, unsigned int, void *,
1771                                unsigned int);
1772 static int parse_vc_action_rss_func(struct context *, const struct token *,
1773                                     const char *, unsigned int, void *,
1774                                     unsigned int);
1775 static int parse_vc_action_rss_type(struct context *, const struct token *,
1776                                     const char *, unsigned int, void *,
1777                                     unsigned int);
1778 static int parse_vc_action_rss_queue(struct context *, const struct token *,
1779                                      const char *, unsigned int, void *,
1780                                      unsigned int);
1781 static int parse_vc_action_vxlan_encap(struct context *, const struct token *,
1782                                        const char *, unsigned int, void *,
1783                                        unsigned int);
1784 static int parse_vc_action_nvgre_encap(struct context *, const struct token *,
1785                                        const char *, unsigned int, void *,
1786                                        unsigned int);
1787 static int parse_vc_action_l2_encap(struct context *, const struct token *,
1788                                     const char *, unsigned int, void *,
1789                                     unsigned int);
1790 static int parse_vc_action_l2_decap(struct context *, const struct token *,
1791                                     const char *, unsigned int, void *,
1792                                     unsigned int);
1793 static int parse_vc_action_mplsogre_encap(struct context *,
1794                                           const struct token *, const char *,
1795                                           unsigned int, void *, unsigned int);
1796 static int parse_vc_action_mplsogre_decap(struct context *,
1797                                           const struct token *, const char *,
1798                                           unsigned int, void *, unsigned int);
1799 static int parse_vc_action_mplsoudp_encap(struct context *,
1800                                           const struct token *, const char *,
1801                                           unsigned int, void *, unsigned int);
1802 static int parse_vc_action_mplsoudp_decap(struct context *,
1803                                           const struct token *, const char *,
1804                                           unsigned int, void *, unsigned int);
1805 static int parse_vc_action_raw_encap(struct context *,
1806                                      const struct token *, const char *,
1807                                      unsigned int, void *, unsigned int);
1808 static int parse_vc_action_raw_decap(struct context *,
1809                                      const struct token *, const char *,
1810                                      unsigned int, void *, unsigned int);
1811 static int parse_vc_action_raw_encap_index(struct context *,
1812                                            const struct token *, const char *,
1813                                            unsigned int, void *, unsigned int);
1814 static int parse_vc_action_raw_decap_index(struct context *,
1815                                            const struct token *, const char *,
1816                                            unsigned int, void *, unsigned int);
1817 static int parse_vc_action_set_meta(struct context *ctx,
1818                                     const struct token *token, const char *str,
1819                                     unsigned int len, void *buf,
1820                                         unsigned int size);
1821 static int parse_vc_action_sample(struct context *ctx,
1822                                     const struct token *token, const char *str,
1823                                     unsigned int len, void *buf,
1824                                     unsigned int size);
1825 static int
1826 parse_vc_action_sample_index(struct context *ctx, const struct token *token,
1827                                 const char *str, unsigned int len, void *buf,
1828                                 unsigned int size);
1829 static int
1830 parse_vc_modify_field_op(struct context *ctx, const struct token *token,
1831                                 const char *str, unsigned int len, void *buf,
1832                                 unsigned int size);
1833 static int
1834 parse_vc_modify_field_id(struct context *ctx, const struct token *token,
1835                                 const char *str, unsigned int len, void *buf,
1836                                 unsigned int size);
1837 static int
1838 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token,
1839                          const char *str, unsigned int len, void *buf,
1840                          unsigned int size);
1841 static int parse_destroy(struct context *, const struct token *,
1842                          const char *, unsigned int,
1843                          void *, unsigned int);
1844 static int parse_flush(struct context *, const struct token *,
1845                        const char *, unsigned int,
1846                        void *, unsigned int);
1847 static int parse_dump(struct context *, const struct token *,
1848                       const char *, unsigned int,
1849                       void *, unsigned int);
1850 static int parse_query(struct context *, const struct token *,
1851                        const char *, unsigned int,
1852                        void *, unsigned int);
1853 static int parse_action(struct context *, const struct token *,
1854                         const char *, unsigned int,
1855                         void *, unsigned int);
1856 static int parse_list(struct context *, const struct token *,
1857                       const char *, unsigned int,
1858                       void *, unsigned int);
1859 static int parse_aged(struct context *, const struct token *,
1860                       const char *, unsigned int,
1861                       void *, unsigned int);
1862 static int parse_isolate(struct context *, const struct token *,
1863                          const char *, unsigned int,
1864                          void *, unsigned int);
1865 static int parse_tunnel(struct context *, const struct token *,
1866                         const char *, unsigned int,
1867                         void *, unsigned int);
1868 static int parse_int(struct context *, const struct token *,
1869                      const char *, unsigned int,
1870                      void *, unsigned int);
1871 static int parse_prefix(struct context *, const struct token *,
1872                         const char *, unsigned int,
1873                         void *, unsigned int);
1874 static int parse_boolean(struct context *, const struct token *,
1875                          const char *, unsigned int,
1876                          void *, unsigned int);
1877 static int parse_string(struct context *, const struct token *,
1878                         const char *, unsigned int,
1879                         void *, unsigned int);
1880 static int parse_hex(struct context *ctx, const struct token *token,
1881                         const char *str, unsigned int len,
1882                         void *buf, unsigned int size);
1883 static int parse_string0(struct context *, const struct token *,
1884                         const char *, unsigned int,
1885                         void *, unsigned int);
1886 static int parse_mac_addr(struct context *, const struct token *,
1887                           const char *, unsigned int,
1888                           void *, unsigned int);
1889 static int parse_ipv4_addr(struct context *, const struct token *,
1890                            const char *, unsigned int,
1891                            void *, unsigned int);
1892 static int parse_ipv6_addr(struct context *, const struct token *,
1893                            const char *, unsigned int,
1894                            void *, unsigned int);
1895 static int parse_port(struct context *, const struct token *,
1896                       const char *, unsigned int,
1897                       void *, unsigned int);
1898 static int parse_ia(struct context *, const struct token *,
1899                     const char *, unsigned int,
1900                     void *, unsigned int);
1901 static int parse_ia_destroy(struct context *ctx, const struct token *token,
1902                             const char *str, unsigned int len,
1903                             void *buf, unsigned int size);
1904 static int parse_ia_id2ptr(struct context *ctx, const struct token *token,
1905                            const char *str, unsigned int len, void *buf,
1906                            unsigned int size);
1907 static int parse_mp(struct context *, const struct token *,
1908                     const char *, unsigned int,
1909                     void *, unsigned int);
1910 static int comp_none(struct context *, const struct token *,
1911                      unsigned int, char *, unsigned int);
1912 static int comp_boolean(struct context *, const struct token *,
1913                         unsigned int, char *, unsigned int);
1914 static int comp_action(struct context *, const struct token *,
1915                        unsigned int, char *, unsigned int);
1916 static int comp_port(struct context *, const struct token *,
1917                      unsigned int, char *, unsigned int);
1918 static int comp_rule_id(struct context *, const struct token *,
1919                         unsigned int, char *, unsigned int);
1920 static int comp_vc_action_rss_type(struct context *, const struct token *,
1921                                    unsigned int, char *, unsigned int);
1922 static int comp_vc_action_rss_queue(struct context *, const struct token *,
1923                                     unsigned int, char *, unsigned int);
1924 static int comp_set_raw_index(struct context *, const struct token *,
1925                               unsigned int, char *, unsigned int);
1926 static int comp_set_sample_index(struct context *, const struct token *,
1927                               unsigned int, char *, unsigned int);
1928 static int comp_set_modify_field_op(struct context *, const struct token *,
1929                               unsigned int, char *, unsigned int);
1930 static int comp_set_modify_field_id(struct context *, const struct token *,
1931                               unsigned int, char *, unsigned int);
1932
1933 /** Token definitions. */
1934 static const struct token token_list[] = {
1935         /* Special tokens. */
1936         [ZERO] = {
1937                 .name = "ZERO",
1938                 .help = "null entry, abused as the entry point",
1939                 .next = NEXT(NEXT_ENTRY(FLOW, ADD)),
1940         },
1941         [END] = {
1942                 .name = "",
1943                 .type = "RETURN",
1944                 .help = "command may end here",
1945         },
1946         [START_SET] = {
1947                 .name = "START_SET",
1948                 .help = "null entry, abused as the entry point for set",
1949                 .next = NEXT(NEXT_ENTRY(SET)),
1950         },
1951         [END_SET] = {
1952                 .name = "end_set",
1953                 .type = "RETURN",
1954                 .help = "set command may end here",
1955         },
1956         /* Common tokens. */
1957         [COMMON_INTEGER] = {
1958                 .name = "{int}",
1959                 .type = "INTEGER",
1960                 .help = "integer value",
1961                 .call = parse_int,
1962                 .comp = comp_none,
1963         },
1964         [COMMON_UNSIGNED] = {
1965                 .name = "{unsigned}",
1966                 .type = "UNSIGNED",
1967                 .help = "unsigned integer value",
1968                 .call = parse_int,
1969                 .comp = comp_none,
1970         },
1971         [COMMON_PREFIX] = {
1972                 .name = "{prefix}",
1973                 .type = "PREFIX",
1974                 .help = "prefix length for bit-mask",
1975                 .call = parse_prefix,
1976                 .comp = comp_none,
1977         },
1978         [COMMON_BOOLEAN] = {
1979                 .name = "{boolean}",
1980                 .type = "BOOLEAN",
1981                 .help = "any boolean value",
1982                 .call = parse_boolean,
1983                 .comp = comp_boolean,
1984         },
1985         [COMMON_STRING] = {
1986                 .name = "{string}",
1987                 .type = "STRING",
1988                 .help = "fixed string",
1989                 .call = parse_string,
1990                 .comp = comp_none,
1991         },
1992         [COMMON_HEX] = {
1993                 .name = "{hex}",
1994                 .type = "HEX",
1995                 .help = "fixed string",
1996                 .call = parse_hex,
1997         },
1998         [COMMON_FILE_PATH] = {
1999                 .name = "{file path}",
2000                 .type = "STRING",
2001                 .help = "file path",
2002                 .call = parse_string0,
2003                 .comp = comp_none,
2004         },
2005         [COMMON_MAC_ADDR] = {
2006                 .name = "{MAC address}",
2007                 .type = "MAC-48",
2008                 .help = "standard MAC address notation",
2009                 .call = parse_mac_addr,
2010                 .comp = comp_none,
2011         },
2012         [COMMON_IPV4_ADDR] = {
2013                 .name = "{IPv4 address}",
2014                 .type = "IPV4 ADDRESS",
2015                 .help = "standard IPv4 address notation",
2016                 .call = parse_ipv4_addr,
2017                 .comp = comp_none,
2018         },
2019         [COMMON_IPV6_ADDR] = {
2020                 .name = "{IPv6 address}",
2021                 .type = "IPV6 ADDRESS",
2022                 .help = "standard IPv6 address notation",
2023                 .call = parse_ipv6_addr,
2024                 .comp = comp_none,
2025         },
2026         [COMMON_RULE_ID] = {
2027                 .name = "{rule id}",
2028                 .type = "RULE ID",
2029                 .help = "rule identifier",
2030                 .call = parse_int,
2031                 .comp = comp_rule_id,
2032         },
2033         [COMMON_PORT_ID] = {
2034                 .name = "{port_id}",
2035                 .type = "PORT ID",
2036                 .help = "port identifier",
2037                 .call = parse_port,
2038                 .comp = comp_port,
2039         },
2040         [COMMON_GROUP_ID] = {
2041                 .name = "{group_id}",
2042                 .type = "GROUP ID",
2043                 .help = "group identifier",
2044                 .call = parse_int,
2045                 .comp = comp_none,
2046         },
2047         [COMMON_PRIORITY_LEVEL] = {
2048                 .name = "{level}",
2049                 .type = "PRIORITY",
2050                 .help = "priority level",
2051                 .call = parse_int,
2052                 .comp = comp_none,
2053         },
2054         [COMMON_INDIRECT_ACTION_ID] = {
2055                 .name = "{indirect_action_id}",
2056                 .type = "INDIRECT_ACTION_ID",
2057                 .help = "indirect action id",
2058                 .call = parse_int,
2059                 .comp = comp_none,
2060         },
2061         [COMMON_POLICY_ID] = {
2062                 .name = "{policy_id}",
2063                 .type = "POLCIY_ID",
2064                 .help = "policy id",
2065                 .call = parse_int,
2066                 .comp = comp_none,
2067         },
2068         /* Top-level command. */
2069         [FLOW] = {
2070                 .name = "flow",
2071                 .type = "{command} {port_id} [{arg} [...]]",
2072                 .help = "manage ingress/egress flow rules",
2073                 .next = NEXT(NEXT_ENTRY
2074                              (INDIRECT_ACTION,
2075                               VALIDATE,
2076                               CREATE,
2077                               DESTROY,
2078                               FLUSH,
2079                               DUMP,
2080                               LIST,
2081                               AGED,
2082                               QUERY,
2083                               ISOLATE,
2084                               TUNNEL)),
2085                 .call = parse_init,
2086         },
2087         /* Top-level command. */
2088         [INDIRECT_ACTION] = {
2089                 .name = "indirect_action",
2090                 .type = "{command} {port_id} [{arg} [...]]",
2091                 .help = "manage indirect actions",
2092                 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)),
2093                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2094                 .call = parse_ia,
2095         },
2096         /* Sub-level commands. */
2097         [INDIRECT_ACTION_CREATE] = {
2098                 .name = "create",
2099                 .help = "create indirect action",
2100                 .next = NEXT(next_ia_create_attr),
2101                 .call = parse_ia,
2102         },
2103         [INDIRECT_ACTION_UPDATE] = {
2104                 .name = "update",
2105                 .help = "update indirect action",
2106                 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC),
2107                              NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
2108                 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)),
2109                 .call = parse_ia,
2110         },
2111         [INDIRECT_ACTION_DESTROY] = {
2112                 .name = "destroy",
2113                 .help = "destroy indirect action",
2114                 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)),
2115                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2116                 .call = parse_ia_destroy,
2117         },
2118         [INDIRECT_ACTION_QUERY] = {
2119                 .name = "query",
2120                 .help = "query indirect action",
2121                 .next = NEXT(NEXT_ENTRY(END),
2122                              NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
2123                 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)),
2124                 .call = parse_ia,
2125         },
2126         [VALIDATE] = {
2127                 .name = "validate",
2128                 .help = "check whether a flow rule can be created",
2129                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)),
2130                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2131                 .call = parse_vc,
2132         },
2133         [CREATE] = {
2134                 .name = "create",
2135                 .help = "create a flow rule",
2136                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)),
2137                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2138                 .call = parse_vc,
2139         },
2140         [DESTROY] = {
2141                 .name = "destroy",
2142                 .help = "destroy specific flow rules",
2143                 .next = NEXT(NEXT_ENTRY(DESTROY_RULE),
2144                              NEXT_ENTRY(COMMON_PORT_ID)),
2145                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2146                 .call = parse_destroy,
2147         },
2148         [FLUSH] = {
2149                 .name = "flush",
2150                 .help = "destroy all flow rules",
2151                 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)),
2152                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2153                 .call = parse_flush,
2154         },
2155         [DUMP] = {
2156                 .name = "dump",
2157                 .help = "dump single/all flow rules to file",
2158                 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)),
2159                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2160                 .call = parse_dump,
2161         },
2162         [QUERY] = {
2163                 .name = "query",
2164                 .help = "query an existing flow rule",
2165                 .next = NEXT(NEXT_ENTRY(QUERY_ACTION),
2166                              NEXT_ENTRY(COMMON_RULE_ID),
2167                              NEXT_ENTRY(COMMON_PORT_ID)),
2168                 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type),
2169                              ARGS_ENTRY(struct buffer, args.query.rule),
2170                              ARGS_ENTRY(struct buffer, port)),
2171                 .call = parse_query,
2172         },
2173         [LIST] = {
2174                 .name = "list",
2175                 .help = "list existing flow rules",
2176                 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)),
2177                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2178                 .call = parse_list,
2179         },
2180         [AGED] = {
2181                 .name = "aged",
2182                 .help = "list and destroy aged flows",
2183                 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)),
2184                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2185                 .call = parse_aged,
2186         },
2187         [ISOLATE] = {
2188                 .name = "isolate",
2189                 .help = "restrict ingress traffic to the defined flow rules",
2190                 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN),
2191                              NEXT_ENTRY(COMMON_PORT_ID)),
2192                 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set),
2193                              ARGS_ENTRY(struct buffer, port)),
2194                 .call = parse_isolate,
2195         },
2196         [TUNNEL] = {
2197                 .name = "tunnel",
2198                 .help = "new tunnel API",
2199                 .next = NEXT(NEXT_ENTRY
2200                              (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)),
2201                 .call = parse_tunnel,
2202         },
2203         /* Tunnel arguments. */
2204         [TUNNEL_CREATE] = {
2205                 .name = "create",
2206                 .help = "create new tunnel object",
2207                 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE),
2208                              NEXT_ENTRY(COMMON_PORT_ID)),
2209                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2210                 .call = parse_tunnel,
2211         },
2212         [TUNNEL_CREATE_TYPE] = {
2213                 .name = "type",
2214                 .help = "create new tunnel",
2215                 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)),
2216                 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)),
2217                 .call = parse_tunnel,
2218         },
2219         [TUNNEL_DESTROY] = {
2220                 .name = "destroy",
2221                 .help = "destroy tunel",
2222                 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID),
2223                              NEXT_ENTRY(COMMON_PORT_ID)),
2224                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2225                 .call = parse_tunnel,
2226         },
2227         [TUNNEL_DESTROY_ID] = {
2228                 .name = "id",
2229                 .help = "tunnel identifier to testroy",
2230                 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)),
2231                 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)),
2232                 .call = parse_tunnel,
2233         },
2234         [TUNNEL_LIST] = {
2235                 .name = "list",
2236                 .help = "list existing tunnels",
2237                 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)),
2238                 .args = ARGS(ARGS_ENTRY(struct buffer, port)),
2239                 .call = parse_tunnel,
2240         },
2241         /* Destroy arguments. */
2242         [DESTROY_RULE] = {
2243                 .name = "rule",
2244                 .help = "specify a rule identifier",
2245                 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)),
2246                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)),
2247                 .call = parse_destroy,
2248         },
2249         /* Dump arguments. */
2250         [DUMP_ALL] = {
2251                 .name = "all",
2252                 .help = "dump all",
2253                 .next = NEXT(next_dump_attr),
2254                 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)),
2255                 .call = parse_dump,
2256         },
2257         [DUMP_ONE] = {
2258                 .name = "rule",
2259                 .help = "dump one rule",
2260                 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)),
2261                 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file),
2262                                 ARGS_ENTRY(struct buffer, args.dump.rule)),
2263                 .call = parse_dump,
2264         },
2265         /* Query arguments. */
2266         [QUERY_ACTION] = {
2267                 .name = "{action}",
2268                 .type = "ACTION",
2269                 .help = "action to query, must be part of the rule",
2270                 .call = parse_action,
2271                 .comp = comp_action,
2272         },
2273         /* List arguments. */
2274         [LIST_GROUP] = {
2275                 .name = "group",
2276                 .help = "specify a group",
2277                 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)),
2278                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)),
2279                 .call = parse_list,
2280         },
2281         [AGED_DESTROY] = {
2282                 .name = "destroy",
2283                 .help = "specify aged flows need be destroyed",
2284                 .call = parse_aged,
2285                 .comp = comp_none,
2286         },
2287         /* Validate/create attributes. */
2288         [VC_GROUP] = {
2289                 .name = "group",
2290                 .help = "specify a group",
2291                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)),
2292                 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)),
2293                 .call = parse_vc,
2294         },
2295         [VC_PRIORITY] = {
2296                 .name = "priority",
2297                 .help = "specify a priority level",
2298                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)),
2299                 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)),
2300                 .call = parse_vc,
2301         },
2302         [VC_INGRESS] = {
2303                 .name = "ingress",
2304                 .help = "affect rule to ingress",
2305                 .next = NEXT(next_vc_attr),
2306                 .call = parse_vc,
2307         },
2308         [VC_EGRESS] = {
2309                 .name = "egress",
2310                 .help = "affect rule to egress",
2311                 .next = NEXT(next_vc_attr),
2312                 .call = parse_vc,
2313         },
2314         [VC_TRANSFER] = {
2315                 .name = "transfer",
2316                 .help = "apply rule directly to endpoints found in pattern",
2317                 .next = NEXT(next_vc_attr),
2318                 .call = parse_vc,
2319         },
2320         [VC_TUNNEL_SET] = {
2321                 .name = "tunnel_set",
2322                 .help = "tunnel steer rule",
2323                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)),
2324                 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)),
2325                 .call = parse_vc,
2326         },
2327         [VC_TUNNEL_MATCH] = {
2328                 .name = "tunnel_match",
2329                 .help = "tunnel match rule",
2330                 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)),
2331                 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)),
2332                 .call = parse_vc,
2333         },
2334         /* Validate/create pattern. */
2335         [ITEM_PATTERN] = {
2336                 .name = "pattern",
2337                 .help = "submit a list of pattern items",
2338                 .next = NEXT(next_item),
2339                 .call = parse_vc,
2340         },
2341         [ITEM_PARAM_IS] = {
2342                 .name = "is",
2343                 .help = "match value perfectly (with full bit-mask)",
2344                 .call = parse_vc_spec,
2345         },
2346         [ITEM_PARAM_SPEC] = {
2347                 .name = "spec",
2348                 .help = "match value according to configured bit-mask",
2349                 .call = parse_vc_spec,
2350         },
2351         [ITEM_PARAM_LAST] = {
2352                 .name = "last",
2353                 .help = "specify upper bound to establish a range",
2354                 .call = parse_vc_spec,
2355         },
2356         [ITEM_PARAM_MASK] = {
2357                 .name = "mask",
2358                 .help = "specify bit-mask with relevant bits set to one",
2359                 .call = parse_vc_spec,
2360         },
2361         [ITEM_PARAM_PREFIX] = {
2362                 .name = "prefix",
2363                 .help = "generate bit-mask from a prefix length",
2364                 .call = parse_vc_spec,
2365         },
2366         [ITEM_NEXT] = {
2367                 .name = "/",
2368                 .help = "specify next pattern item",
2369                 .next = NEXT(next_item),
2370         },
2371         [ITEM_END] = {
2372                 .name = "end",
2373                 .help = "end list of pattern items",
2374                 .priv = PRIV_ITEM(END, 0),
2375                 .next = NEXT(NEXT_ENTRY(ACTIONS)),
2376                 .call = parse_vc,
2377         },
2378         [ITEM_VOID] = {
2379                 .name = "void",
2380                 .help = "no-op pattern item",
2381                 .priv = PRIV_ITEM(VOID, 0),
2382                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
2383                 .call = parse_vc,
2384         },
2385         [ITEM_INVERT] = {
2386                 .name = "invert",
2387                 .help = "perform actions when pattern does not match",
2388                 .priv = PRIV_ITEM(INVERT, 0),
2389                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
2390                 .call = parse_vc,
2391         },
2392         [ITEM_ANY] = {
2393                 .name = "any",
2394                 .help = "match any protocol for the current layer",
2395                 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)),
2396                 .next = NEXT(item_any),
2397                 .call = parse_vc,
2398         },
2399         [ITEM_ANY_NUM] = {
2400                 .name = "num",
2401                 .help = "number of layers covered",
2402                 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
2403                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)),
2404         },
2405         [ITEM_PF] = {
2406                 .name = "pf",
2407                 .help = "match traffic from/to the physical function",
2408                 .priv = PRIV_ITEM(PF, 0),
2409                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
2410                 .call = parse_vc,
2411         },
2412         [ITEM_VF] = {
2413                 .name = "vf",
2414                 .help = "match traffic from/to a virtual function ID",
2415                 .priv = PRIV_ITEM(VF, sizeof(struct rte_flow_item_vf)),
2416                 .next = NEXT(item_vf),
2417                 .call = parse_vc,
2418         },
2419         [ITEM_VF_ID] = {
2420                 .name = "id",
2421                 .help = "VF ID",
2422                 .next = NEXT(item_vf, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
2423                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_vf, id)),
2424         },
2425         [ITEM_PHY_PORT] = {
2426                 .name = "phy_port",
2427                 .help = "match traffic from/to a specific physical port",
2428                 .priv = PRIV_ITEM(PHY_PORT,
2429                                   sizeof(struct rte_flow_item_phy_port)),
2430                 .next = NEXT(item_phy_port),
2431                 .call = parse_vc,
2432         },
2433         [ITEM_PHY_PORT_INDEX] = {
2434                 .name = "index",
2435                 .help = "physical port index",
2436                 .next = NEXT(item_phy_port, NEXT_ENTRY(COMMON_UNSIGNED),
2437                              item_param),
2438                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_phy_port, index)),
2439         },
2440         [ITEM_PORT_ID] = {
2441                 .name = "port_id",
2442                 .help = "match traffic from/to a given DPDK port ID",
2443                 .priv = PRIV_ITEM(PORT_ID,
2444                                   sizeof(struct rte_flow_item_port_id)),
2445                 .next = NEXT(item_port_id),
2446                 .call = parse_vc,
2447         },
2448         [ITEM_PORT_ID_ID] = {
2449                 .name = "id",
2450                 .help = "DPDK port ID",
2451                 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED),
2452                              item_param),
2453                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)),
2454         },
2455         [ITEM_MARK] = {
2456                 .name = "mark",
2457                 .help = "match traffic against value set in previously matched rule",
2458                 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)),
2459                 .next = NEXT(item_mark),
2460                 .call = parse_vc,
2461         },
2462         [ITEM_MARK_ID] = {
2463                 .name = "id",
2464                 .help = "Integer value to match against",
2465                 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED),
2466                              item_param),
2467                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)),
2468         },
2469         [ITEM_RAW] = {
2470                 .name = "raw",
2471                 .help = "match an arbitrary byte string",
2472                 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE),
2473                 .next = NEXT(item_raw),
2474                 .call = parse_vc,
2475         },
2476         [ITEM_RAW_RELATIVE] = {
2477                 .name = "relative",
2478                 .help = "look for pattern after the previous item",
2479                 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param),
2480                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
2481                                            relative, 1)),
2482         },
2483         [ITEM_RAW_SEARCH] = {
2484                 .name = "search",
2485                 .help = "search pattern from offset (see also limit)",
2486                 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param),
2487                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
2488                                            search, 1)),
2489         },
2490         [ITEM_RAW_OFFSET] = {
2491                 .name = "offset",
2492                 .help = "absolute or relative offset for pattern",
2493                 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param),
2494                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)),
2495         },
2496         [ITEM_RAW_LIMIT] = {
2497                 .name = "limit",
2498                 .help = "search area limit for start of pattern",
2499                 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
2500                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)),
2501         },
2502         [ITEM_RAW_PATTERN] = {
2503                 .name = "pattern",
2504                 .help = "byte string to look for",
2505                 .next = NEXT(item_raw,
2506                              NEXT_ENTRY(COMMON_STRING),
2507                              NEXT_ENTRY(ITEM_PARAM_IS,
2508                                         ITEM_PARAM_SPEC,
2509                                         ITEM_PARAM_MASK)),
2510                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern),
2511                              ARGS_ENTRY(struct rte_flow_item_raw, length),
2512                              ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw),
2513                                             ITEM_RAW_PATTERN_SIZE)),
2514         },
2515         [ITEM_ETH] = {
2516                 .name = "eth",
2517                 .help = "match Ethernet header",
2518                 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
2519                 .next = NEXT(item_eth),
2520                 .call = parse_vc,
2521         },
2522         [ITEM_ETH_DST] = {
2523                 .name = "dst",
2524                 .help = "destination MAC",
2525                 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param),
2526                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, dst)),
2527         },
2528         [ITEM_ETH_SRC] = {
2529                 .name = "src",
2530                 .help = "source MAC",
2531                 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param),
2532                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, src)),
2533         },
2534         [ITEM_ETH_TYPE] = {
2535                 .name = "type",
2536                 .help = "EtherType",
2537                 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
2538                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, type)),
2539         },
2540         [ITEM_ETH_HAS_VLAN] = {
2541                 .name = "has_vlan",
2542                 .help = "packet header contains VLAN",
2543                 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
2544                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth,
2545                                            has_vlan, 1)),
2546         },
2547         [ITEM_VLAN] = {
2548                 .name = "vlan",
2549                 .help = "match 802.1Q/ad VLAN tag",
2550                 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
2551                 .next = NEXT(item_vlan),
2552                 .call = parse_vc,
2553         },
2554         [ITEM_VLAN_TCI] = {
2555                 .name = "tci",
2556                 .help = "tag control information",
2557                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
2558                              item_param),
2559                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)),
2560         },
2561         [ITEM_VLAN_PCP] = {
2562                 .name = "pcp",
2563                 .help = "priority code point",
2564                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
2565                              item_param),
2566                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
2567                                                   tci, "\xe0\x00")),
2568         },
2569         [ITEM_VLAN_DEI] = {
2570                 .name = "dei",
2571                 .help = "drop eligible indicator",
2572                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
2573                              item_param),
2574                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
2575                                                   tci, "\x10\x00")),
2576         },
2577         [ITEM_VLAN_VID] = {
2578                 .name = "vid",
2579                 .help = "VLAN identifier",
2580                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
2581                              item_param),
2582                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
2583                                                   tci, "\x0f\xff")),
2584         },
2585         [ITEM_VLAN_INNER_TYPE] = {
2586                 .name = "inner_type",
2587                 .help = "inner EtherType",
2588                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
2589                              item_param),
2590                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan,
2591                                              inner_type)),
2592         },
2593         [ITEM_VLAN_HAS_MORE_VLAN] = {
2594                 .name = "has_more_vlan",
2595                 .help = "packet header contains another VLAN",
2596                 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED),
2597                              item_param),
2598                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan,
2599                                            has_more_vlan, 1)),
2600         },
2601         [ITEM_IPV4] = {
2602                 .name = "ipv4",
2603                 .help = "match IPv4 header",
2604                 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
2605                 .next = NEXT(item_ipv4),
2606                 .call = parse_vc,
2607         },
2608         [ITEM_IPV4_VER_IHL] = {
2609                 .name = "version_ihl",
2610                 .help = "match header length",
2611                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
2612                              item_param),
2613                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4,
2614                                      hdr.version_ihl)),
2615         },
2616         [ITEM_IPV4_TOS] = {
2617                 .name = "tos",
2618                 .help = "type of service",
2619                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
2620                              item_param),
2621                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2622                                              hdr.type_of_service)),
2623         },
2624         [ITEM_IPV4_ID] = {
2625                 .name = "packet_id",
2626                 .help = "fragment packet id",
2627                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
2628                              item_param),
2629                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2630                                              hdr.packet_id)),
2631         },
2632         [ITEM_IPV4_FRAGMENT_OFFSET] = {
2633                 .name = "fragment_offset",
2634                 .help = "fragmentation flags and fragment offset",
2635                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
2636                              item_param),
2637                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2638                                              hdr.fragment_offset)),
2639         },
2640         [ITEM_IPV4_TTL] = {
2641                 .name = "ttl",
2642                 .help = "time to live",
2643                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
2644                              item_param),
2645                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2646                                              hdr.time_to_live)),
2647         },
2648         [ITEM_IPV4_PROTO] = {
2649                 .name = "proto",
2650                 .help = "next protocol ID",
2651                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED),
2652                              item_param),
2653                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2654                                              hdr.next_proto_id)),
2655         },
2656         [ITEM_IPV4_SRC] = {
2657                 .name = "src",
2658                 .help = "source address",
2659                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR),
2660                              item_param),
2661                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2662                                              hdr.src_addr)),
2663         },
2664         [ITEM_IPV4_DST] = {
2665                 .name = "dst",
2666                 .help = "destination address",
2667                 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR),
2668                              item_param),
2669                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
2670                                              hdr.dst_addr)),
2671         },
2672         [ITEM_IPV6] = {
2673                 .name = "ipv6",
2674                 .help = "match IPv6 header",
2675                 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
2676                 .next = NEXT(item_ipv6),
2677                 .call = parse_vc,
2678         },
2679         [ITEM_IPV6_TC] = {
2680                 .name = "tc",
2681                 .help = "traffic class",
2682                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
2683                              item_param),
2684                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
2685                                                   hdr.vtc_flow,
2686                                                   "\x0f\xf0\x00\x00")),
2687         },
2688         [ITEM_IPV6_FLOW] = {
2689                 .name = "flow",
2690                 .help = "flow label",
2691                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
2692                              item_param),
2693                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
2694                                                   hdr.vtc_flow,
2695                                                   "\x00\x0f\xff\xff")),
2696         },
2697         [ITEM_IPV6_PROTO] = {
2698                 .name = "proto",
2699                 .help = "protocol (next header)",
2700                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
2701                              item_param),
2702                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2703                                              hdr.proto)),
2704         },
2705         [ITEM_IPV6_HOP] = {
2706                 .name = "hop",
2707                 .help = "hop limit",
2708                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
2709                              item_param),
2710                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2711                                              hdr.hop_limits)),
2712         },
2713         [ITEM_IPV6_SRC] = {
2714                 .name = "src",
2715                 .help = "source address",
2716                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR),
2717                              item_param),
2718                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2719                                              hdr.src_addr)),
2720         },
2721         [ITEM_IPV6_DST] = {
2722                 .name = "dst",
2723                 .help = "destination address",
2724                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR),
2725                              item_param),
2726                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
2727                                              hdr.dst_addr)),
2728         },
2729         [ITEM_IPV6_HAS_FRAG_EXT] = {
2730                 .name = "has_frag_ext",
2731                 .help = "fragment packet attribute",
2732                 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
2733                              item_param),
2734                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
2735                                            has_frag_ext, 1)),
2736         },
2737         [ITEM_ICMP] = {
2738                 .name = "icmp",
2739                 .help = "match ICMP header",
2740                 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
2741                 .next = NEXT(item_icmp),
2742                 .call = parse_vc,
2743         },
2744         [ITEM_ICMP_TYPE] = {
2745                 .name = "type",
2746                 .help = "ICMP packet type",
2747                 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED),
2748                              item_param),
2749                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
2750                                              hdr.icmp_type)),
2751         },
2752         [ITEM_ICMP_CODE] = {
2753                 .name = "code",
2754                 .help = "ICMP packet code",
2755                 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED),
2756                              item_param),
2757                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
2758                                              hdr.icmp_code)),
2759         },
2760         [ITEM_ICMP_IDENT] = {
2761                 .name = "ident",
2762                 .help = "ICMP packet identifier",
2763                 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED),
2764                              item_param),
2765                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
2766                                              hdr.icmp_ident)),
2767         },
2768         [ITEM_ICMP_SEQ] = {
2769                 .name = "seq",
2770                 .help = "ICMP packet sequence number",
2771                 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED),
2772                              item_param),
2773                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
2774                                              hdr.icmp_seq_nb)),
2775         },
2776         [ITEM_UDP] = {
2777                 .name = "udp",
2778                 .help = "match UDP header",
2779                 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
2780                 .next = NEXT(item_udp),
2781                 .call = parse_vc,
2782         },
2783         [ITEM_UDP_SRC] = {
2784                 .name = "src",
2785                 .help = "UDP source port",
2786                 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED),
2787                              item_param),
2788                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
2789                                              hdr.src_port)),
2790         },
2791         [ITEM_UDP_DST] = {
2792                 .name = "dst",
2793                 .help = "UDP destination port",
2794                 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
2795                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
2796                                              hdr.dst_port)),
2797         },
2798         [ITEM_TCP] = {
2799                 .name = "tcp",
2800                 .help = "match TCP header",
2801                 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
2802                 .next = NEXT(item_tcp),
2803                 .call = parse_vc,
2804         },
2805         [ITEM_TCP_SRC] = {
2806                 .name = "src",
2807                 .help = "TCP source port",
2808                 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
2809                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
2810                                              hdr.src_port)),
2811         },
2812         [ITEM_TCP_DST] = {
2813                 .name = "dst",
2814                 .help = "TCP destination port",
2815                 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
2816                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
2817                                              hdr.dst_port)),
2818         },
2819         [ITEM_TCP_FLAGS] = {
2820                 .name = "flags",
2821                 .help = "TCP flags",
2822                 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
2823                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
2824                                              hdr.tcp_flags)),
2825         },
2826         [ITEM_SCTP] = {
2827                 .name = "sctp",
2828                 .help = "match SCTP header",
2829                 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
2830                 .next = NEXT(item_sctp),
2831                 .call = parse_vc,
2832         },
2833         [ITEM_SCTP_SRC] = {
2834                 .name = "src",
2835                 .help = "SCTP source port",
2836                 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED),
2837                              item_param),
2838                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2839                                              hdr.src_port)),
2840         },
2841         [ITEM_SCTP_DST] = {
2842                 .name = "dst",
2843                 .help = "SCTP destination port",
2844                 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED),
2845                              item_param),
2846                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2847                                              hdr.dst_port)),
2848         },
2849         [ITEM_SCTP_TAG] = {
2850                 .name = "tag",
2851                 .help = "validation tag",
2852                 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED),
2853                              item_param),
2854                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2855                                              hdr.tag)),
2856         },
2857         [ITEM_SCTP_CKSUM] = {
2858                 .name = "cksum",
2859                 .help = "checksum",
2860                 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED),
2861                              item_param),
2862                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
2863                                              hdr.cksum)),
2864         },
2865         [ITEM_VXLAN] = {
2866                 .name = "vxlan",
2867                 .help = "match VXLAN header",
2868                 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
2869                 .next = NEXT(item_vxlan),
2870                 .call = parse_vc,
2871         },
2872         [ITEM_VXLAN_VNI] = {
2873                 .name = "vni",
2874                 .help = "VXLAN identifier",
2875                 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED),
2876                              item_param),
2877                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)),
2878         },
2879         [ITEM_VXLAN_LAST_RSVD] = {
2880                 .name = "last_rsvd",
2881                 .help = "VXLAN last reserved bits",
2882                 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED),
2883                              item_param),
2884                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan,
2885                                              rsvd1)),
2886         },
2887         [ITEM_E_TAG] = {
2888                 .name = "e_tag",
2889                 .help = "match E-Tag header",
2890                 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
2891                 .next = NEXT(item_e_tag),
2892                 .call = parse_vc,
2893         },
2894         [ITEM_E_TAG_GRP_ECID_B] = {
2895                 .name = "grp_ecid_b",
2896                 .help = "GRP and E-CID base",
2897                 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED),
2898                              item_param),
2899                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag,
2900                                                   rsvd_grp_ecid_b,
2901                                                   "\x3f\xff")),
2902         },
2903         [ITEM_NVGRE] = {
2904                 .name = "nvgre",
2905                 .help = "match NVGRE header",
2906                 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
2907                 .next = NEXT(item_nvgre),
2908                 .call = parse_vc,
2909         },
2910         [ITEM_NVGRE_TNI] = {
2911                 .name = "tni",
2912                 .help = "virtual subnet ID",
2913                 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED),
2914                              item_param),
2915                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)),
2916         },
2917         [ITEM_MPLS] = {
2918                 .name = "mpls",
2919                 .help = "match MPLS header",
2920                 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
2921                 .next = NEXT(item_mpls),
2922                 .call = parse_vc,
2923         },
2924         [ITEM_MPLS_LABEL] = {
2925                 .name = "label",
2926                 .help = "MPLS label",
2927                 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED),
2928                              item_param),
2929                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
2930                                                   label_tc_s,
2931                                                   "\xff\xff\xf0")),
2932         },
2933         [ITEM_MPLS_TC] = {
2934                 .name = "tc",
2935                 .help = "MPLS Traffic Class",
2936                 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED),
2937                              item_param),
2938                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
2939                                                   label_tc_s,
2940                                                   "\x00\x00\x0e")),
2941         },
2942         [ITEM_MPLS_S] = {
2943                 .name = "s",
2944                 .help = "MPLS Bottom-of-Stack",
2945                 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED),
2946                              item_param),
2947                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
2948                                                   label_tc_s,
2949                                                   "\x00\x00\x01")),
2950         },
2951         [ITEM_GRE] = {
2952                 .name = "gre",
2953                 .help = "match GRE header",
2954                 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
2955                 .next = NEXT(item_gre),
2956                 .call = parse_vc,
2957         },
2958         [ITEM_GRE_PROTO] = {
2959                 .name = "protocol",
2960                 .help = "GRE protocol type",
2961                 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED),
2962                              item_param),
2963                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
2964                                              protocol)),
2965         },
2966         [ITEM_GRE_C_RSVD0_VER] = {
2967                 .name = "c_rsvd0_ver",
2968                 .help =
2969                         "checksum (1b), undefined (1b), key bit (1b),"
2970                         " sequence number (1b), reserved 0 (9b),"
2971                         " version (3b)",
2972                 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED),
2973                              item_param),
2974                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
2975                                              c_rsvd0_ver)),
2976         },
2977         [ITEM_GRE_C_BIT] = {
2978                 .name = "c_bit",
2979                 .help = "checksum bit (C)",
2980                 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN),
2981                              item_param),
2982                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
2983                                                   c_rsvd0_ver,
2984                                                   "\x80\x00\x00\x00")),
2985         },
2986         [ITEM_GRE_S_BIT] = {
2987                 .name = "s_bit",
2988                 .help = "sequence number bit (S)",
2989                 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param),
2990                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
2991                                                   c_rsvd0_ver,
2992                                                   "\x10\x00\x00\x00")),
2993         },
2994         [ITEM_GRE_K_BIT] = {
2995                 .name = "k_bit",
2996                 .help = "key bit (K)",
2997                 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param),
2998                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
2999                                                   c_rsvd0_ver,
3000                                                   "\x20\x00\x00\x00")),
3001         },
3002         [ITEM_FUZZY] = {
3003                 .name = "fuzzy",
3004                 .help = "fuzzy pattern match, expect faster than default",
3005                 .priv = PRIV_ITEM(FUZZY,
3006                                 sizeof(struct rte_flow_item_fuzzy)),
3007                 .next = NEXT(item_fuzzy),
3008                 .call = parse_vc,
3009         },
3010         [ITEM_FUZZY_THRESH] = {
3011                 .name = "thresh",
3012                 .help = "match accuracy threshold",
3013                 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED),
3014                              item_param),
3015                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy,
3016                                         thresh)),
3017         },
3018         [ITEM_GTP] = {
3019                 .name = "gtp",
3020                 .help = "match GTP header",
3021                 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)),
3022                 .next = NEXT(item_gtp),
3023                 .call = parse_vc,
3024         },
3025         [ITEM_GTP_FLAGS] = {
3026                 .name = "v_pt_rsv_flags",
3027                 .help = "GTP flags",
3028                 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3029                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp,
3030                                         v_pt_rsv_flags)),
3031         },
3032         [ITEM_GTP_MSG_TYPE] = {
3033                 .name = "msg_type",
3034                 .help = "GTP message type",
3035                 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3036                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, msg_type)),
3037         },
3038         [ITEM_GTP_TEID] = {
3039                 .name = "teid",
3040                 .help = "tunnel endpoint identifier",
3041                 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3042                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, teid)),
3043         },
3044         [ITEM_GTPC] = {
3045                 .name = "gtpc",
3046                 .help = "match GTP header",
3047                 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
3048                 .next = NEXT(item_gtp),
3049                 .call = parse_vc,
3050         },
3051         [ITEM_GTPU] = {
3052                 .name = "gtpu",
3053                 .help = "match GTP header",
3054                 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)),
3055                 .next = NEXT(item_gtp),
3056                 .call = parse_vc,
3057         },
3058         [ITEM_GENEVE] = {
3059                 .name = "geneve",
3060                 .help = "match GENEVE header",
3061                 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
3062                 .next = NEXT(item_geneve),
3063                 .call = parse_vc,
3064         },
3065         [ITEM_GENEVE_VNI] = {
3066                 .name = "vni",
3067                 .help = "virtual network identifier",
3068                 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED),
3069                              item_param),
3070                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)),
3071         },
3072         [ITEM_GENEVE_PROTO] = {
3073                 .name = "protocol",
3074                 .help = "GENEVE protocol type",
3075                 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED),
3076                              item_param),
3077                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve,
3078                                              protocol)),
3079         },
3080         [ITEM_GENEVE_OPTLEN] = {
3081                 .name = "optlen",
3082                 .help = "GENEVE options length in dwords",
3083                 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED),
3084                              item_param),
3085                 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve,
3086                                                   ver_opt_len_o_c_rsvd0,
3087                                                   "\x3f\x00")),
3088         },
3089         [ITEM_VXLAN_GPE] = {
3090                 .name = "vxlan-gpe",
3091                 .help = "match VXLAN-GPE header",
3092                 .priv = PRIV_ITEM(VXLAN_GPE,
3093                                   sizeof(struct rte_flow_item_vxlan_gpe)),
3094                 .next = NEXT(item_vxlan_gpe),
3095                 .call = parse_vc,
3096         },
3097         [ITEM_VXLAN_GPE_VNI] = {
3098                 .name = "vni",
3099                 .help = "VXLAN-GPE identifier",
3100                 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED),
3101                              item_param),
3102                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe,
3103                                              vni)),
3104         },
3105         [ITEM_ARP_ETH_IPV4] = {
3106                 .name = "arp_eth_ipv4",
3107                 .help = "match ARP header for Ethernet/IPv4",
3108                 .priv = PRIV_ITEM(ARP_ETH_IPV4,
3109                                   sizeof(struct rte_flow_item_arp_eth_ipv4)),
3110                 .next = NEXT(item_arp_eth_ipv4),
3111                 .call = parse_vc,
3112         },
3113         [ITEM_ARP_ETH_IPV4_SHA] = {
3114                 .name = "sha",
3115                 .help = "sender hardware address",
3116                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR),
3117                              item_param),
3118                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
3119                                              sha)),
3120         },
3121         [ITEM_ARP_ETH_IPV4_SPA] = {
3122                 .name = "spa",
3123                 .help = "sender IPv4 address",
3124                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR),
3125                              item_param),
3126                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
3127                                              spa)),
3128         },
3129         [ITEM_ARP_ETH_IPV4_THA] = {
3130                 .name = "tha",
3131                 .help = "target hardware address",
3132                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR),
3133                              item_param),
3134                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
3135                                              tha)),
3136         },
3137         [ITEM_ARP_ETH_IPV4_TPA] = {
3138                 .name = "tpa",
3139                 .help = "target IPv4 address",
3140                 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR),
3141                              item_param),
3142                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4,
3143                                              tpa)),
3144         },
3145         [ITEM_IPV6_EXT] = {
3146                 .name = "ipv6_ext",
3147                 .help = "match presence of any IPv6 extension header",
3148                 .priv = PRIV_ITEM(IPV6_EXT,
3149                                   sizeof(struct rte_flow_item_ipv6_ext)),
3150                 .next = NEXT(item_ipv6_ext),
3151                 .call = parse_vc,
3152         },
3153         [ITEM_IPV6_EXT_NEXT_HDR] = {
3154                 .name = "next_hdr",
3155                 .help = "next header",
3156                 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED),
3157                              item_param),
3158                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext,
3159                                              next_hdr)),
3160         },
3161         [ITEM_IPV6_FRAG_EXT] = {
3162                 .name = "ipv6_frag_ext",
3163                 .help = "match presence of IPv6 fragment extension header",
3164                 .priv = PRIV_ITEM(IPV6_FRAG_EXT,
3165                                 sizeof(struct rte_flow_item_ipv6_frag_ext)),
3166                 .next = NEXT(item_ipv6_frag_ext),
3167                 .call = parse_vc,
3168         },
3169         [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = {
3170                 .name = "next_hdr",
3171                 .help = "next header",
3172                 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED),
3173                              item_param),
3174                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext,
3175                                         hdr.next_header)),
3176         },
3177         [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = {
3178                 .name = "frag_data",
3179                 .help = "fragment flags and offset",
3180                 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED),
3181                              item_param),
3182                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext,
3183                                              hdr.frag_data)),
3184         },
3185         [ITEM_IPV6_FRAG_EXT_ID] = {
3186                 .name = "packet_id",
3187                 .help = "fragment packet id",
3188                 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED),
3189                              item_param),
3190                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext,
3191                                              hdr.id)),
3192         },
3193         [ITEM_ICMP6] = {
3194                 .name = "icmp6",
3195                 .help = "match any ICMPv6 header",
3196                 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)),
3197                 .next = NEXT(item_icmp6),
3198                 .call = parse_vc,
3199         },
3200         [ITEM_ICMP6_TYPE] = {
3201                 .name = "type",
3202                 .help = "ICMPv6 type",
3203                 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED),
3204                              item_param),
3205                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6,
3206                                              type)),
3207         },
3208         [ITEM_ICMP6_CODE] = {
3209                 .name = "code",
3210                 .help = "ICMPv6 code",
3211                 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED),
3212                              item_param),
3213                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6,
3214                                              code)),
3215         },
3216         [ITEM_ICMP6_ND_NS] = {
3217                 .name = "icmp6_nd_ns",
3218                 .help = "match ICMPv6 neighbor discovery solicitation",
3219                 .priv = PRIV_ITEM(ICMP6_ND_NS,
3220                                   sizeof(struct rte_flow_item_icmp6_nd_ns)),
3221                 .next = NEXT(item_icmp6_nd_ns),
3222                 .call = parse_vc,
3223         },
3224         [ITEM_ICMP6_ND_NS_TARGET_ADDR] = {
3225                 .name = "target_addr",
3226                 .help = "target address",
3227                 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR),
3228                              item_param),
3229                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns,
3230                                              target_addr)),
3231         },
3232         [ITEM_ICMP6_ND_NA] = {
3233                 .name = "icmp6_nd_na",
3234                 .help = "match ICMPv6 neighbor discovery advertisement",
3235                 .priv = PRIV_ITEM(ICMP6_ND_NA,
3236                                   sizeof(struct rte_flow_item_icmp6_nd_na)),
3237                 .next = NEXT(item_icmp6_nd_na),
3238                 .call = parse_vc,
3239         },
3240         [ITEM_ICMP6_ND_NA_TARGET_ADDR] = {
3241                 .name = "target_addr",
3242                 .help = "target address",
3243                 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR),
3244                              item_param),
3245                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na,
3246                                              target_addr)),
3247         },
3248         [ITEM_ICMP6_ND_OPT] = {
3249                 .name = "icmp6_nd_opt",
3250                 .help = "match presence of any ICMPv6 neighbor discovery"
3251                         " option",
3252                 .priv = PRIV_ITEM(ICMP6_ND_OPT,
3253                                   sizeof(struct rte_flow_item_icmp6_nd_opt)),
3254                 .next = NEXT(item_icmp6_nd_opt),
3255                 .call = parse_vc,
3256         },
3257         [ITEM_ICMP6_ND_OPT_TYPE] = {
3258                 .name = "type",
3259                 .help = "ND option type",
3260                 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED),
3261                              item_param),
3262                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt,
3263                                              type)),
3264         },
3265         [ITEM_ICMP6_ND_OPT_SLA_ETH] = {
3266                 .name = "icmp6_nd_opt_sla_eth",
3267                 .help = "match ICMPv6 neighbor discovery source Ethernet"
3268                         " link-layer address option",
3269                 .priv = PRIV_ITEM
3270                         (ICMP6_ND_OPT_SLA_ETH,
3271                          sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)),
3272                 .next = NEXT(item_icmp6_nd_opt_sla_eth),
3273                 .call = parse_vc,
3274         },
3275         [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = {
3276                 .name = "sla",
3277                 .help = "source Ethernet LLA",
3278                 .next = NEXT(item_icmp6_nd_opt_sla_eth,
3279                              NEXT_ENTRY(COMMON_MAC_ADDR), item_param),
3280                 .args = ARGS(ARGS_ENTRY_HTON
3281                              (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)),
3282         },
3283         [ITEM_ICMP6_ND_OPT_TLA_ETH] = {
3284                 .name = "icmp6_nd_opt_tla_eth",
3285                 .help = "match ICMPv6 neighbor discovery target Ethernet"
3286                         " link-layer address option",
3287                 .priv = PRIV_ITEM
3288                         (ICMP6_ND_OPT_TLA_ETH,
3289                          sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)),
3290                 .next = NEXT(item_icmp6_nd_opt_tla_eth),
3291                 .call = parse_vc,
3292         },
3293         [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = {
3294                 .name = "tla",
3295                 .help = "target Ethernet LLA",
3296                 .next = NEXT(item_icmp6_nd_opt_tla_eth,
3297                              NEXT_ENTRY(COMMON_MAC_ADDR), item_param),
3298                 .args = ARGS(ARGS_ENTRY_HTON
3299                              (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)),
3300         },
3301         [ITEM_META] = {
3302                 .name = "meta",
3303                 .help = "match metadata header",
3304                 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)),
3305                 .next = NEXT(item_meta),
3306                 .call = parse_vc,
3307         },
3308         [ITEM_META_DATA] = {
3309                 .name = "data",
3310                 .help = "metadata value",
3311                 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED),
3312                              item_param),
3313                 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta,
3314                                              data, "\xff\xff\xff\xff")),
3315         },
3316         [ITEM_GRE_KEY] = {
3317                 .name = "gre_key",
3318                 .help = "match GRE key",
3319                 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)),
3320                 .next = NEXT(item_gre_key),
3321                 .call = parse_vc,
3322         },
3323         [ITEM_GRE_KEY_VALUE] = {
3324                 .name = "value",
3325                 .help = "key value",
3326                 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED),
3327                              item_param),
3328                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
3329         },
3330         [ITEM_GTP_PSC] = {
3331                 .name = "gtp_psc",
3332                 .help = "match GTP extension header with type 0x85",
3333                 .priv = PRIV_ITEM(GTP_PSC,
3334                                 sizeof(struct rte_flow_item_gtp_psc)),
3335                 .next = NEXT(item_gtp_psc),
3336                 .call = parse_vc,
3337         },
3338         [ITEM_GTP_PSC_QFI] = {
3339                 .name = "qfi",
3340                 .help = "QoS flow identifier",
3341                 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED),
3342                              item_param),
3343                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc,
3344                                         hdr.qfi, 6)),
3345         },
3346         [ITEM_GTP_PSC_PDU_T] = {
3347                 .name = "pdu_t",
3348                 .help = "PDU type",
3349                 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED),
3350                              item_param),
3351                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc,
3352                                         hdr.type, 4)),
3353         },
3354         [ITEM_PPPOES] = {
3355                 .name = "pppoes",
3356                 .help = "match PPPoE session header",
3357                 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)),
3358                 .next = NEXT(item_pppoes),
3359                 .call = parse_vc,
3360         },
3361         [ITEM_PPPOED] = {
3362                 .name = "pppoed",
3363                 .help = "match PPPoE discovery header",
3364                 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)),
3365                 .next = NEXT(item_pppoed),
3366                 .call = parse_vc,
3367         },
3368         [ITEM_PPPOE_SEID] = {
3369                 .name = "seid",
3370                 .help = "session identifier",
3371                 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED),
3372                              item_param),
3373                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe,
3374                                         session_id)),
3375         },
3376         [ITEM_PPPOE_PROTO_ID] = {
3377                 .name = "pppoe_proto_id",
3378                 .help = "match PPPoE session protocol identifier",
3379                 .priv = PRIV_ITEM(PPPOE_PROTO_ID,
3380                                 sizeof(struct rte_flow_item_pppoe_proto_id)),
3381                 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED),
3382                              item_param),
3383                 .args = ARGS(ARGS_ENTRY_HTON
3384                              (struct rte_flow_item_pppoe_proto_id, proto_id)),
3385                 .call = parse_vc,
3386         },
3387         [ITEM_HIGIG2] = {
3388                 .name = "higig2",
3389                 .help = "matches higig2 header",
3390                 .priv = PRIV_ITEM(HIGIG2,
3391                                 sizeof(struct rte_flow_item_higig2_hdr)),
3392                 .next = NEXT(item_higig2),
3393                 .call = parse_vc,
3394         },
3395         [ITEM_HIGIG2_CLASSIFICATION] = {
3396                 .name = "classification",
3397                 .help = "matches classification of higig2 header",
3398                 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED),
3399                              item_param),
3400                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr,
3401                                         hdr.ppt1.classification)),
3402         },
3403         [ITEM_HIGIG2_VID] = {
3404                 .name = "vid",
3405                 .help = "matches vid of higig2 header",
3406                 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED),
3407                              item_param),
3408                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr,
3409                                         hdr.ppt1.vid)),
3410         },
3411         [ITEM_TAG] = {
3412                 .name = "tag",
3413                 .help = "match tag value",
3414                 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)),
3415                 .next = NEXT(item_tag),
3416                 .call = parse_vc,
3417         },
3418         [ITEM_TAG_DATA] = {
3419                 .name = "data",
3420                 .help = "tag value to match",
3421                 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3422                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)),
3423         },
3424         [ITEM_TAG_INDEX] = {
3425                 .name = "index",
3426                 .help = "index of tag array to match",
3427                 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED),
3428                              NEXT_ENTRY(ITEM_PARAM_IS)),
3429                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)),
3430         },
3431         [ITEM_L2TPV3OIP] = {
3432                 .name = "l2tpv3oip",
3433                 .help = "match L2TPv3 over IP header",
3434                 .priv = PRIV_ITEM(L2TPV3OIP,
3435                                   sizeof(struct rte_flow_item_l2tpv3oip)),
3436                 .next = NEXT(item_l2tpv3oip),
3437                 .call = parse_vc,
3438         },
3439         [ITEM_L2TPV3OIP_SESSION_ID] = {
3440                 .name = "session_id",
3441                 .help = "session identifier",
3442                 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED),
3443                              item_param),
3444                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip,
3445                                              session_id)),
3446         },
3447         [ITEM_ESP] = {
3448                 .name = "esp",
3449                 .help = "match ESP header",
3450                 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)),
3451                 .next = NEXT(item_esp),
3452                 .call = parse_vc,
3453         },
3454         [ITEM_ESP_SPI] = {
3455                 .name = "spi",
3456                 .help = "security policy index",
3457                 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3458                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp,
3459                                 hdr.spi)),
3460         },
3461         [ITEM_AH] = {
3462                 .name = "ah",
3463                 .help = "match AH header",
3464                 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)),
3465                 .next = NEXT(item_ah),
3466                 .call = parse_vc,
3467         },
3468         [ITEM_AH_SPI] = {
3469                 .name = "spi",
3470                 .help = "security parameters index",
3471                 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3472                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)),
3473         },
3474         [ITEM_PFCP] = {
3475                 .name = "pfcp",
3476                 .help = "match pfcp header",
3477                 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
3478                 .next = NEXT(item_pfcp),
3479                 .call = parse_vc,
3480         },
3481         [ITEM_PFCP_S_FIELD] = {
3482                 .name = "s_field",
3483                 .help = "S field",
3484                 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED),
3485                              item_param),
3486                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp,
3487                                 s_field)),
3488         },
3489         [ITEM_PFCP_SEID] = {
3490                 .name = "seid",
3491                 .help = "session endpoint identifier",
3492                 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED),
3493                              item_param),
3494                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)),
3495         },
3496         [ITEM_ECPRI] = {
3497                 .name = "ecpri",
3498                 .help = "match eCPRI header",
3499                 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
3500                 .next = NEXT(item_ecpri),
3501                 .call = parse_vc,
3502         },
3503         [ITEM_ECPRI_COMMON] = {
3504                 .name = "common",
3505                 .help = "eCPRI common header",
3506                 .next = NEXT(item_ecpri_common),
3507         },
3508         [ITEM_ECPRI_COMMON_TYPE] = {
3509                 .name = "type",
3510                 .help = "type of common header",
3511                 .next = NEXT(item_ecpri_common_type),
3512                 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)),
3513         },
3514         [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = {
3515                 .name = "iq_data",
3516                 .help = "Type #0: IQ Data",
3517                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID,
3518                                         ITEM_NEXT)),
3519                 .call = parse_vc_item_ecpri_type,
3520         },
3521         [ITEM_ECPRI_MSG_IQ_DATA_PCID] = {
3522                 .name = "pc_id",
3523                 .help = "Physical Channel ID",
3524                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID,
3525                                 ITEM_ECPRI_COMMON, ITEM_NEXT),
3526                                 NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3527                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri,
3528                                 hdr.type0.pc_id)),
3529         },
3530         [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = {
3531                 .name = "rtc_ctrl",
3532                 .help = "Type #2: Real-Time Control Data",
3533                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID,
3534                                         ITEM_NEXT)),
3535                 .call = parse_vc_item_ecpri_type,
3536         },
3537         [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = {
3538                 .name = "rtc_id",
3539                 .help = "Real-Time Control Data ID",
3540                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID,
3541                                 ITEM_ECPRI_COMMON, ITEM_NEXT),
3542                                 NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3543                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri,
3544                                 hdr.type2.rtc_id)),
3545         },
3546         [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = {
3547                 .name = "delay_measure",
3548                 .help = "Type #5: One-Way Delay Measurement",
3549                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID,
3550                                         ITEM_NEXT)),
3551                 .call = parse_vc_item_ecpri_type,
3552         },
3553         [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = {
3554                 .name = "msr_id",
3555                 .help = "Measurement ID",
3556                 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID,
3557                                 ITEM_ECPRI_COMMON, ITEM_NEXT),
3558                                 NEXT_ENTRY(COMMON_UNSIGNED), item_param),
3559                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri,
3560                                 hdr.type5.msr_id)),
3561         },
3562         [ITEM_GENEVE_OPT] = {
3563                 .name = "geneve-opt",
3564                 .help = "GENEVE header option",
3565                 .priv = PRIV_ITEM(GENEVE_OPT,
3566                                   sizeof(struct rte_flow_item_geneve_opt) +
3567                                   ITEM_GENEVE_OPT_DATA_SIZE),
3568                 .next = NEXT(item_geneve_opt),
3569                 .call = parse_vc,
3570         },
3571         [ITEM_GENEVE_OPT_CLASS] = {
3572                 .name = "class",
3573                 .help = "GENEVE option class",
3574                 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED),
3575                              item_param),
3576                 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt,
3577                                              option_class)),
3578         },
3579         [ITEM_GENEVE_OPT_TYPE] = {
3580                 .name = "type",
3581                 .help = "GENEVE option type",
3582                 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED),
3583                              item_param),
3584                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt,
3585                                         option_type)),
3586         },
3587         [ITEM_GENEVE_OPT_LENGTH] = {
3588                 .name = "length",
3589                 .help = "GENEVE option data length (in 32b words)",
3590                 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED),
3591                              item_param),
3592                 .args = ARGS(ARGS_ENTRY_BOUNDED(
3593                                 struct rte_flow_item_geneve_opt, option_len,
3594                                 0, 31)),
3595         },
3596         [ITEM_GENEVE_OPT_DATA] = {
3597                 .name = "data",
3598                 .help = "GENEVE option data pattern",
3599                 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX),
3600                              item_param),
3601                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data),
3602                              ARGS_ENTRY_ARB(0, 0),
3603                              ARGS_ENTRY_ARB
3604                                 (sizeof(struct rte_flow_item_geneve_opt),
3605                                 ITEM_GENEVE_OPT_DATA_SIZE)),
3606         },
3607         [ITEM_INTEGRITY] = {
3608                 .name = "integrity",
3609                 .help = "match packet integrity",
3610                 .priv = PRIV_ITEM(INTEGRITY,
3611                                   sizeof(struct rte_flow_item_integrity)),
3612                 .next = NEXT(item_integrity),
3613                 .call = parse_vc,
3614         },
3615         [ITEM_INTEGRITY_LEVEL] = {
3616                 .name = "level",
3617                 .help = "integrity level",
3618                 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED),
3619                              item_param),
3620                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)),
3621         },
3622         [ITEM_INTEGRITY_VALUE] = {
3623                 .name = "value",
3624                 .help = "integrity value",
3625                 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED),
3626                              item_param),
3627                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)),
3628         },
3629         [ITEM_CONNTRACK] = {
3630                 .name = "conntrack",
3631                 .help = "conntrack state",
3632                 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED),
3633                              item_param),
3634                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)),
3635         },
3636         [ITEM_PORT_REPRESENTOR] = {
3637                 .name = "port_representor",
3638                 .help = "match traffic entering the embedded switch from the given ethdev",
3639                 .priv = PRIV_ITEM(PORT_REPRESENTOR,
3640                                   sizeof(struct rte_flow_item_ethdev)),
3641                 .next = NEXT(item_port_representor),
3642                 .call = parse_vc,
3643         },
3644         [ITEM_PORT_REPRESENTOR_PORT_ID] = {
3645                 .name = "port_id",
3646                 .help = "ethdev port ID",
3647                 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED),
3648                              item_param),
3649                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
3650         },
3651         [ITEM_REPRESENTED_PORT] = {
3652                 .name = "represented_port",
3653                 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev",
3654                 .priv = PRIV_ITEM(REPRESENTED_PORT,
3655                                   sizeof(struct rte_flow_item_ethdev)),
3656                 .next = NEXT(item_represented_port),
3657                 .call = parse_vc,
3658         },
3659         [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = {
3660                 .name = "ethdev_port_id",
3661                 .help = "ethdev port ID",
3662                 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED),
3663                              item_param),
3664                 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
3665         },
3666         /* Validate/create actions. */
3667         [ACTIONS] = {
3668                 .name = "actions",
3669                 .help = "submit a list of associated actions",
3670                 .next = NEXT(next_action),
3671                 .call = parse_vc,
3672         },
3673         [ACTION_NEXT] = {
3674                 .name = "/",
3675                 .help = "specify next action",
3676                 .next = NEXT(next_action),
3677         },
3678         [ACTION_END] = {
3679                 .name = "end",
3680                 .help = "end list of actions",
3681                 .priv = PRIV_ACTION(END, 0),
3682                 .call = parse_vc,
3683         },
3684         [ACTION_VOID] = {
3685                 .name = "void",
3686                 .help = "no-op action",
3687                 .priv = PRIV_ACTION(VOID, 0),
3688                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3689                 .call = parse_vc,
3690         },
3691         [ACTION_PASSTHRU] = {
3692                 .name = "passthru",
3693                 .help = "let subsequent rule process matched packets",
3694                 .priv = PRIV_ACTION(PASSTHRU, 0),
3695                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3696                 .call = parse_vc,
3697         },
3698         [ACTION_JUMP] = {
3699                 .name = "jump",
3700                 .help = "redirect traffic to a given group",
3701                 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)),
3702                 .next = NEXT(action_jump),
3703                 .call = parse_vc,
3704         },
3705         [ACTION_JUMP_GROUP] = {
3706                 .name = "group",
3707                 .help = "group to redirect traffic to",
3708                 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)),
3709                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)),
3710                 .call = parse_vc_conf,
3711         },
3712         [ACTION_MARK] = {
3713                 .name = "mark",
3714                 .help = "attach 32 bit value to packets",
3715                 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
3716                 .next = NEXT(action_mark),
3717                 .call = parse_vc,
3718         },
3719         [ACTION_MARK_ID] = {
3720                 .name = "id",
3721                 .help = "32 bit value to return with packets",
3722                 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)),
3723                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)),
3724                 .call = parse_vc_conf,
3725         },
3726         [ACTION_FLAG] = {
3727                 .name = "flag",
3728                 .help = "flag packets",
3729                 .priv = PRIV_ACTION(FLAG, 0),
3730                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3731                 .call = parse_vc,
3732         },
3733         [ACTION_QUEUE] = {
3734                 .name = "queue",
3735                 .help = "assign packets to a given queue index",
3736                 .priv = PRIV_ACTION(QUEUE,
3737                                     sizeof(struct rte_flow_action_queue)),
3738                 .next = NEXT(action_queue),
3739                 .call = parse_vc,
3740         },
3741         [ACTION_QUEUE_INDEX] = {
3742                 .name = "index",
3743                 .help = "queue index to use",
3744                 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)),
3745                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
3746                 .call = parse_vc_conf,
3747         },
3748         [ACTION_DROP] = {
3749                 .name = "drop",
3750                 .help = "drop packets (note: passthru has priority)",
3751                 .priv = PRIV_ACTION(DROP, 0),
3752                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3753                 .call = parse_vc,
3754         },
3755         [ACTION_COUNT] = {
3756                 .name = "count",
3757                 .help = "enable counters for this rule",
3758                 .priv = PRIV_ACTION(COUNT,
3759                                     sizeof(struct rte_flow_action_count)),
3760                 .next = NEXT(action_count),
3761                 .call = parse_vc,
3762         },
3763         [ACTION_COUNT_ID] = {
3764                 .name = "identifier",
3765                 .help = "counter identifier to use",
3766                 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)),
3767                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)),
3768                 .call = parse_vc_conf,
3769         },
3770         [ACTION_RSS] = {
3771                 .name = "rss",
3772                 .help = "spread packets among several queues",
3773                 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)),
3774                 .next = NEXT(action_rss),
3775                 .call = parse_vc_action_rss,
3776         },
3777         [ACTION_RSS_FUNC] = {
3778                 .name = "func",
3779                 .help = "RSS hash function to apply",
3780                 .next = NEXT(action_rss,
3781                              NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT,
3782                                         ACTION_RSS_FUNC_TOEPLITZ,
3783                                         ACTION_RSS_FUNC_SIMPLE_XOR,
3784                                         ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)),
3785         },
3786         [ACTION_RSS_FUNC_DEFAULT] = {
3787                 .name = "default",
3788                 .help = "default hash function",
3789                 .call = parse_vc_action_rss_func,
3790         },
3791         [ACTION_RSS_FUNC_TOEPLITZ] = {
3792                 .name = "toeplitz",
3793                 .help = "Toeplitz hash function",
3794                 .call = parse_vc_action_rss_func,
3795         },
3796         [ACTION_RSS_FUNC_SIMPLE_XOR] = {
3797                 .name = "simple_xor",
3798                 .help = "simple XOR hash function",
3799                 .call = parse_vc_action_rss_func,
3800         },
3801         [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = {
3802                 .name = "symmetric_toeplitz",
3803                 .help = "Symmetric Toeplitz hash function",
3804                 .call = parse_vc_action_rss_func,
3805         },
3806         [ACTION_RSS_LEVEL] = {
3807                 .name = "level",
3808                 .help = "encapsulation level for \"types\"",
3809                 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)),
3810                 .args = ARGS(ARGS_ENTRY_ARB
3811                              (offsetof(struct action_rss_data, conf) +
3812                               offsetof(struct rte_flow_action_rss, level),
3813                               sizeof(((struct rte_flow_action_rss *)0)->
3814                                      level))),
3815         },
3816         [ACTION_RSS_TYPES] = {
3817                 .name = "types",
3818                 .help = "specific RSS hash types",
3819                 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)),
3820         },
3821         [ACTION_RSS_TYPE] = {
3822                 .name = "{type}",
3823                 .help = "RSS hash type",
3824                 .call = parse_vc_action_rss_type,
3825                 .comp = comp_vc_action_rss_type,
3826         },
3827         [ACTION_RSS_KEY] = {
3828                 .name = "key",
3829                 .help = "RSS hash key",
3830                 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)),
3831                 .args = ARGS(ARGS_ENTRY_ARB
3832                              (offsetof(struct action_rss_data, conf) +
3833                               offsetof(struct rte_flow_action_rss, key),
3834                               sizeof(((struct rte_flow_action_rss *)0)->key)),
3835                              ARGS_ENTRY_ARB
3836                              (offsetof(struct action_rss_data, conf) +
3837                               offsetof(struct rte_flow_action_rss, key_len),
3838                               sizeof(((struct rte_flow_action_rss *)0)->
3839                                      key_len)),
3840                              ARGS_ENTRY(struct action_rss_data, key)),
3841         },
3842         [ACTION_RSS_KEY_LEN] = {
3843                 .name = "key_len",
3844                 .help = "RSS hash key length in bytes",
3845                 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)),
3846                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
3847                              (offsetof(struct action_rss_data, conf) +
3848                               offsetof(struct rte_flow_action_rss, key_len),
3849                               sizeof(((struct rte_flow_action_rss *)0)->
3850                                      key_len),
3851                               0,
3852                               RSS_HASH_KEY_LENGTH)),
3853         },
3854         [ACTION_RSS_QUEUES] = {
3855                 .name = "queues",
3856                 .help = "queue indices to use",
3857                 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)),
3858                 .call = parse_vc_conf,
3859         },
3860         [ACTION_RSS_QUEUE] = {
3861                 .name = "{queue}",
3862                 .help = "queue index",
3863                 .call = parse_vc_action_rss_queue,
3864                 .comp = comp_vc_action_rss_queue,
3865         },
3866         [ACTION_PF] = {
3867                 .name = "pf",
3868                 .help = "direct traffic to physical function",
3869                 .priv = PRIV_ACTION(PF, 0),
3870                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
3871                 .call = parse_vc,
3872         },
3873         [ACTION_VF] = {
3874                 .name = "vf",
3875                 .help = "direct traffic to a virtual function ID",
3876                 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)),
3877                 .next = NEXT(action_vf),
3878                 .call = parse_vc,
3879         },
3880         [ACTION_VF_ORIGINAL] = {
3881                 .name = "original",
3882                 .help = "use original VF ID if possible",
3883                 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)),
3884                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf,
3885                                            original, 1)),
3886                 .call = parse_vc_conf,
3887         },
3888         [ACTION_VF_ID] = {
3889                 .name = "id",
3890                 .help = "VF ID",
3891                 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)),
3892                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)),
3893                 .call = parse_vc_conf,
3894         },
3895         [ACTION_PHY_PORT] = {
3896                 .name = "phy_port",
3897                 .help = "direct packets to physical port index",
3898                 .priv = PRIV_ACTION(PHY_PORT,
3899                                     sizeof(struct rte_flow_action_phy_port)),
3900                 .next = NEXT(action_phy_port),
3901                 .call = parse_vc,
3902         },
3903         [ACTION_PHY_PORT_ORIGINAL] = {
3904                 .name = "original",
3905                 .help = "use original port index if possible",
3906                 .next = NEXT(action_phy_port, NEXT_ENTRY(COMMON_BOOLEAN)),
3907                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_phy_port,
3908                                            original, 1)),
3909                 .call = parse_vc_conf,
3910         },
3911         [ACTION_PHY_PORT_INDEX] = {
3912                 .name = "index",
3913                 .help = "physical port index",
3914                 .next = NEXT(action_phy_port, NEXT_ENTRY(COMMON_UNSIGNED)),
3915                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_phy_port,
3916                                         index)),
3917                 .call = parse_vc_conf,
3918         },
3919         [ACTION_PORT_ID] = {
3920                 .name = "port_id",
3921                 .help = "direct matching traffic to a given DPDK port ID",
3922                 .priv = PRIV_ACTION(PORT_ID,
3923                                     sizeof(struct rte_flow_action_port_id)),
3924                 .next = NEXT(action_port_id),
3925                 .call = parse_vc,
3926         },
3927         [ACTION_PORT_ID_ORIGINAL] = {
3928                 .name = "original",
3929                 .help = "use original DPDK port ID if possible",
3930                 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)),
3931                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id,
3932                                            original, 1)),
3933                 .call = parse_vc_conf,
3934         },
3935         [ACTION_PORT_ID_ID] = {
3936                 .name = "id",
3937                 .help = "DPDK port ID",
3938                 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)),
3939                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)),
3940                 .call = parse_vc_conf,
3941         },
3942         [ACTION_METER] = {
3943                 .name = "meter",
3944                 .help = "meter the directed packets at given id",
3945                 .priv = PRIV_ACTION(METER,
3946                                     sizeof(struct rte_flow_action_meter)),
3947                 .next = NEXT(action_meter),
3948                 .call = parse_vc,
3949         },
3950         [ACTION_METER_COLOR] = {
3951                 .name = "color",
3952                 .help = "meter color for the packets",
3953                 .priv = PRIV_ACTION(METER_COLOR,
3954                                 sizeof(struct rte_flow_action_meter_color)),
3955                 .next = NEXT(action_meter_color),
3956                 .call = parse_vc,
3957         },
3958         [ACTION_METER_COLOR_TYPE] = {
3959                 .name = "type",
3960                 .help = "specific meter color",
3961                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT),
3962                                 NEXT_ENTRY(ACTION_METER_COLOR_GREEN,
3963                                         ACTION_METER_COLOR_YELLOW,
3964                                         ACTION_METER_COLOR_RED)),
3965         },
3966         [ACTION_METER_COLOR_GREEN] = {
3967                 .name = "green",
3968                 .help = "meter color green",
3969                 .call = parse_vc_action_meter_color_type,
3970         },
3971         [ACTION_METER_COLOR_YELLOW] = {
3972                 .name = "yellow",
3973                 .help = "meter color yellow",
3974                 .call = parse_vc_action_meter_color_type,
3975         },
3976         [ACTION_METER_COLOR_RED] = {
3977                 .name = "red",
3978                 .help = "meter color red",
3979                 .call = parse_vc_action_meter_color_type,
3980         },
3981         [ACTION_METER_ID] = {
3982                 .name = "mtr_id",
3983                 .help = "meter id to use",
3984                 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)),
3985                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)),
3986                 .call = parse_vc_conf,
3987         },
3988         [ACTION_OF_SET_MPLS_TTL] = {
3989                 .name = "of_set_mpls_ttl",
3990                 .help = "OpenFlow's OFPAT_SET_MPLS_TTL",
3991                 .priv = PRIV_ACTION
3992                         (OF_SET_MPLS_TTL,
3993                          sizeof(struct rte_flow_action_of_set_mpls_ttl)),
3994                 .next = NEXT(action_of_set_mpls_ttl),
3995                 .call = parse_vc,
3996         },
3997         [ACTION_OF_SET_MPLS_TTL_MPLS_TTL] = {
3998                 .name = "mpls_ttl",
3999                 .help = "MPLS TTL",
4000                 .next = NEXT(action_of_set_mpls_ttl,
4001                              NEXT_ENTRY(COMMON_UNSIGNED)),
4002                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_set_mpls_ttl,
4003                                         mpls_ttl)),
4004                 .call = parse_vc_conf,
4005         },
4006         [ACTION_OF_DEC_MPLS_TTL] = {
4007                 .name = "of_dec_mpls_ttl",
4008                 .help = "OpenFlow's OFPAT_DEC_MPLS_TTL",
4009                 .priv = PRIV_ACTION(OF_DEC_MPLS_TTL, 0),
4010                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4011                 .call = parse_vc,
4012         },
4013         [ACTION_OF_SET_NW_TTL] = {
4014                 .name = "of_set_nw_ttl",
4015                 .help = "OpenFlow's OFPAT_SET_NW_TTL",
4016                 .priv = PRIV_ACTION
4017                         (OF_SET_NW_TTL,
4018                          sizeof(struct rte_flow_action_of_set_nw_ttl)),
4019                 .next = NEXT(action_of_set_nw_ttl),
4020                 .call = parse_vc,
4021         },
4022         [ACTION_OF_SET_NW_TTL_NW_TTL] = {
4023                 .name = "nw_ttl",
4024                 .help = "IP TTL",
4025                 .next = NEXT(action_of_set_nw_ttl, NEXT_ENTRY(COMMON_UNSIGNED)),
4026                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_set_nw_ttl,
4027                                         nw_ttl)),
4028                 .call = parse_vc_conf,
4029         },
4030         [ACTION_OF_DEC_NW_TTL] = {
4031                 .name = "of_dec_nw_ttl",
4032                 .help = "OpenFlow's OFPAT_DEC_NW_TTL",
4033                 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0),
4034                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4035                 .call = parse_vc,
4036         },
4037         [ACTION_OF_COPY_TTL_OUT] = {
4038                 .name = "of_copy_ttl_out",
4039                 .help = "OpenFlow's OFPAT_COPY_TTL_OUT",
4040                 .priv = PRIV_ACTION(OF_COPY_TTL_OUT, 0),
4041                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4042                 .call = parse_vc,
4043         },
4044         [ACTION_OF_COPY_TTL_IN] = {
4045                 .name = "of_copy_ttl_in",
4046                 .help = "OpenFlow's OFPAT_COPY_TTL_IN",
4047                 .priv = PRIV_ACTION(OF_COPY_TTL_IN, 0),
4048                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4049                 .call = parse_vc,
4050         },
4051         [ACTION_OF_POP_VLAN] = {
4052                 .name = "of_pop_vlan",
4053                 .help = "OpenFlow's OFPAT_POP_VLAN",
4054                 .priv = PRIV_ACTION(OF_POP_VLAN, 0),
4055                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4056                 .call = parse_vc,
4057         },
4058         [ACTION_OF_PUSH_VLAN] = {
4059                 .name = "of_push_vlan",
4060                 .help = "OpenFlow's OFPAT_PUSH_VLAN",
4061                 .priv = PRIV_ACTION
4062                         (OF_PUSH_VLAN,
4063                          sizeof(struct rte_flow_action_of_push_vlan)),
4064                 .next = NEXT(action_of_push_vlan),
4065                 .call = parse_vc,
4066         },
4067         [ACTION_OF_PUSH_VLAN_ETHERTYPE] = {
4068                 .name = "ethertype",
4069                 .help = "EtherType",
4070                 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)),
4071                 .args = ARGS(ARGS_ENTRY_HTON
4072                              (struct rte_flow_action_of_push_vlan,
4073                               ethertype)),
4074                 .call = parse_vc_conf,
4075         },
4076         [ACTION_OF_SET_VLAN_VID] = {
4077                 .name = "of_set_vlan_vid",
4078                 .help = "OpenFlow's OFPAT_SET_VLAN_VID",
4079                 .priv = PRIV_ACTION
4080                         (OF_SET_VLAN_VID,
4081                          sizeof(struct rte_flow_action_of_set_vlan_vid)),
4082                 .next = NEXT(action_of_set_vlan_vid),
4083                 .call = parse_vc,
4084         },
4085         [ACTION_OF_SET_VLAN_VID_VLAN_VID] = {
4086                 .name = "vlan_vid",
4087                 .help = "VLAN id",
4088                 .next = NEXT(action_of_set_vlan_vid,
4089                              NEXT_ENTRY(COMMON_UNSIGNED)),
4090                 .args = ARGS(ARGS_ENTRY_HTON
4091                              (struct rte_flow_action_of_set_vlan_vid,
4092                               vlan_vid)),
4093                 .call = parse_vc_conf,
4094         },
4095         [ACTION_OF_SET_VLAN_PCP] = {
4096                 .name = "of_set_vlan_pcp",
4097                 .help = "OpenFlow's OFPAT_SET_VLAN_PCP",
4098                 .priv = PRIV_ACTION
4099                         (OF_SET_VLAN_PCP,
4100                          sizeof(struct rte_flow_action_of_set_vlan_pcp)),
4101                 .next = NEXT(action_of_set_vlan_pcp),
4102                 .call = parse_vc,
4103         },
4104         [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = {
4105                 .name = "vlan_pcp",
4106                 .help = "VLAN priority",
4107                 .next = NEXT(action_of_set_vlan_pcp,
4108                              NEXT_ENTRY(COMMON_UNSIGNED)),
4109                 .args = ARGS(ARGS_ENTRY_HTON
4110                              (struct rte_flow_action_of_set_vlan_pcp,
4111                               vlan_pcp)),
4112                 .call = parse_vc_conf,
4113         },
4114         [ACTION_OF_POP_MPLS] = {
4115                 .name = "of_pop_mpls",
4116                 .help = "OpenFlow's OFPAT_POP_MPLS",
4117                 .priv = PRIV_ACTION(OF_POP_MPLS,
4118                                     sizeof(struct rte_flow_action_of_pop_mpls)),
4119                 .next = NEXT(action_of_pop_mpls),
4120                 .call = parse_vc,
4121         },
4122         [ACTION_OF_POP_MPLS_ETHERTYPE] = {
4123                 .name = "ethertype",
4124                 .help = "EtherType",
4125                 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)),
4126                 .args = ARGS(ARGS_ENTRY_HTON
4127                              (struct rte_flow_action_of_pop_mpls,
4128                               ethertype)),
4129                 .call = parse_vc_conf,
4130         },
4131         [ACTION_OF_PUSH_MPLS] = {
4132                 .name = "of_push_mpls",
4133                 .help = "OpenFlow's OFPAT_PUSH_MPLS",
4134                 .priv = PRIV_ACTION
4135                         (OF_PUSH_MPLS,
4136                          sizeof(struct rte_flow_action_of_push_mpls)),
4137                 .next = NEXT(action_of_push_mpls),
4138                 .call = parse_vc,
4139         },
4140         [ACTION_OF_PUSH_MPLS_ETHERTYPE] = {
4141                 .name = "ethertype",
4142                 .help = "EtherType",
4143                 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)),
4144                 .args = ARGS(ARGS_ENTRY_HTON
4145                              (struct rte_flow_action_of_push_mpls,
4146                               ethertype)),
4147                 .call = parse_vc_conf,
4148         },
4149         [ACTION_VXLAN_ENCAP] = {
4150                 .name = "vxlan_encap",
4151                 .help = "VXLAN encapsulation, uses configuration set by \"set"
4152                         " vxlan\"",
4153                 .priv = PRIV_ACTION(VXLAN_ENCAP,
4154                                     sizeof(struct action_vxlan_encap_data)),
4155                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4156                 .call = parse_vc_action_vxlan_encap,
4157         },
4158         [ACTION_VXLAN_DECAP] = {
4159                 .name = "vxlan_decap",
4160                 .help = "Performs a decapsulation action by stripping all"
4161                         " headers of the VXLAN tunnel network overlay from the"
4162                         " matched flow.",
4163                 .priv = PRIV_ACTION(VXLAN_DECAP, 0),
4164                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4165                 .call = parse_vc,
4166         },
4167         [ACTION_NVGRE_ENCAP] = {
4168                 .name = "nvgre_encap",
4169                 .help = "NVGRE encapsulation, uses configuration set by \"set"
4170                         " nvgre\"",
4171                 .priv = PRIV_ACTION(NVGRE_ENCAP,
4172                                     sizeof(struct action_nvgre_encap_data)),
4173                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4174                 .call = parse_vc_action_nvgre_encap,
4175         },
4176         [ACTION_NVGRE_DECAP] = {
4177                 .name = "nvgre_decap",
4178                 .help = "Performs a decapsulation action by stripping all"
4179                         " headers of the NVGRE tunnel network overlay from the"
4180                         " matched flow.",
4181                 .priv = PRIV_ACTION(NVGRE_DECAP, 0),
4182                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4183                 .call = parse_vc,
4184         },
4185         [ACTION_L2_ENCAP] = {
4186                 .name = "l2_encap",
4187                 .help = "l2 encap, uses configuration set by"
4188                         " \"set l2_encap\"",
4189                 .priv = PRIV_ACTION(RAW_ENCAP,
4190                                     sizeof(struct action_raw_encap_data)),
4191                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4192                 .call = parse_vc_action_l2_encap,
4193         },
4194         [ACTION_L2_DECAP] = {
4195                 .name = "l2_decap",
4196                 .help = "l2 decap, uses configuration set by"
4197                         " \"set l2_decap\"",
4198                 .priv = PRIV_ACTION(RAW_DECAP,
4199                                     sizeof(struct action_raw_decap_data)),
4200                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4201                 .call = parse_vc_action_l2_decap,
4202         },
4203         [ACTION_MPLSOGRE_ENCAP] = {
4204                 .name = "mplsogre_encap",
4205                 .help = "mplsogre encapsulation, uses configuration set by"
4206                         " \"set mplsogre_encap\"",
4207                 .priv = PRIV_ACTION(RAW_ENCAP,
4208                                     sizeof(struct action_raw_encap_data)),
4209                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4210                 .call = parse_vc_action_mplsogre_encap,
4211         },
4212         [ACTION_MPLSOGRE_DECAP] = {
4213                 .name = "mplsogre_decap",
4214                 .help = "mplsogre decapsulation, uses configuration set by"
4215                         " \"set mplsogre_decap\"",
4216                 .priv = PRIV_ACTION(RAW_DECAP,
4217                                     sizeof(struct action_raw_decap_data)),
4218                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4219                 .call = parse_vc_action_mplsogre_decap,
4220         },
4221         [ACTION_MPLSOUDP_ENCAP] = {
4222                 .name = "mplsoudp_encap",
4223                 .help = "mplsoudp encapsulation, uses configuration set by"
4224                         " \"set mplsoudp_encap\"",
4225                 .priv = PRIV_ACTION(RAW_ENCAP,
4226                                     sizeof(struct action_raw_encap_data)),
4227                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4228                 .call = parse_vc_action_mplsoudp_encap,
4229         },
4230         [ACTION_MPLSOUDP_DECAP] = {
4231                 .name = "mplsoudp_decap",
4232                 .help = "mplsoudp decapsulation, uses configuration set by"
4233                         " \"set mplsoudp_decap\"",
4234                 .priv = PRIV_ACTION(RAW_DECAP,
4235                                     sizeof(struct action_raw_decap_data)),
4236                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4237                 .call = parse_vc_action_mplsoudp_decap,
4238         },
4239         [ACTION_SET_IPV4_SRC] = {
4240                 .name = "set_ipv4_src",
4241                 .help = "Set a new IPv4 source address in the outermost"
4242                         " IPv4 header",
4243                 .priv = PRIV_ACTION(SET_IPV4_SRC,
4244                         sizeof(struct rte_flow_action_set_ipv4)),
4245                 .next = NEXT(action_set_ipv4_src),
4246                 .call = parse_vc,
4247         },
4248         [ACTION_SET_IPV4_SRC_IPV4_SRC] = {
4249                 .name = "ipv4_addr",
4250                 .help = "new IPv4 source address to set",
4251                 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)),
4252                 .args = ARGS(ARGS_ENTRY_HTON
4253                         (struct rte_flow_action_set_ipv4, ipv4_addr)),
4254                 .call = parse_vc_conf,
4255         },
4256         [ACTION_SET_IPV4_DST] = {
4257                 .name = "set_ipv4_dst",
4258                 .help = "Set a new IPv4 destination address in the outermost"
4259                         " IPv4 header",
4260                 .priv = PRIV_ACTION(SET_IPV4_DST,
4261                         sizeof(struct rte_flow_action_set_ipv4)),
4262                 .next = NEXT(action_set_ipv4_dst),
4263                 .call = parse_vc,
4264         },
4265         [ACTION_SET_IPV4_DST_IPV4_DST] = {
4266                 .name = "ipv4_addr",
4267                 .help = "new IPv4 destination address to set",
4268                 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)),
4269                 .args = ARGS(ARGS_ENTRY_HTON
4270                         (struct rte_flow_action_set_ipv4, ipv4_addr)),
4271                 .call = parse_vc_conf,
4272         },
4273         [ACTION_SET_IPV6_SRC] = {
4274                 .name = "set_ipv6_src",
4275                 .help = "Set a new IPv6 source address in the outermost"
4276                         " IPv6 header",
4277                 .priv = PRIV_ACTION(SET_IPV6_SRC,
4278                         sizeof(struct rte_flow_action_set_ipv6)),
4279                 .next = NEXT(action_set_ipv6_src),
4280                 .call = parse_vc,
4281         },
4282         [ACTION_SET_IPV6_SRC_IPV6_SRC] = {
4283                 .name = "ipv6_addr",
4284                 .help = "new IPv6 source address to set",
4285                 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)),
4286                 .args = ARGS(ARGS_ENTRY_HTON
4287                         (struct rte_flow_action_set_ipv6, ipv6_addr)),
4288                 .call = parse_vc_conf,
4289         },
4290         [ACTION_SET_IPV6_DST] = {
4291                 .name = "set_ipv6_dst",
4292                 .help = "Set a new IPv6 destination address in the outermost"
4293                         " IPv6 header",
4294                 .priv = PRIV_ACTION(SET_IPV6_DST,
4295                         sizeof(struct rte_flow_action_set_ipv6)),
4296                 .next = NEXT(action_set_ipv6_dst),
4297                 .call = parse_vc,
4298         },
4299         [ACTION_SET_IPV6_DST_IPV6_DST] = {
4300                 .name = "ipv6_addr",
4301                 .help = "new IPv6 destination address to set",
4302                 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)),
4303                 .args = ARGS(ARGS_ENTRY_HTON
4304                         (struct rte_flow_action_set_ipv6, ipv6_addr)),
4305                 .call = parse_vc_conf,
4306         },
4307         [ACTION_SET_TP_SRC] = {
4308                 .name = "set_tp_src",
4309                 .help = "set a new source port number in the outermost"
4310                         " TCP/UDP header",
4311                 .priv = PRIV_ACTION(SET_TP_SRC,
4312                         sizeof(struct rte_flow_action_set_tp)),
4313                 .next = NEXT(action_set_tp_src),
4314                 .call = parse_vc,
4315         },
4316         [ACTION_SET_TP_SRC_TP_SRC] = {
4317                 .name = "port",
4318                 .help = "new source port number to set",
4319                 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)),
4320                 .args = ARGS(ARGS_ENTRY_HTON
4321                              (struct rte_flow_action_set_tp, port)),
4322                 .call = parse_vc_conf,
4323         },
4324         [ACTION_SET_TP_DST] = {
4325                 .name = "set_tp_dst",
4326                 .help = "set a new destination port number in the outermost"
4327                         " TCP/UDP header",
4328                 .priv = PRIV_ACTION(SET_TP_DST,
4329                         sizeof(struct rte_flow_action_set_tp)),
4330                 .next = NEXT(action_set_tp_dst),
4331                 .call = parse_vc,
4332         },
4333         [ACTION_SET_TP_DST_TP_DST] = {
4334                 .name = "port",
4335                 .help = "new destination port number to set",
4336                 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)),
4337                 .args = ARGS(ARGS_ENTRY_HTON
4338                              (struct rte_flow_action_set_tp, port)),
4339                 .call = parse_vc_conf,
4340         },
4341         [ACTION_MAC_SWAP] = {
4342                 .name = "mac_swap",
4343                 .help = "Swap the source and destination MAC addresses"
4344                         " in the outermost Ethernet header",
4345                 .priv = PRIV_ACTION(MAC_SWAP, 0),
4346                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4347                 .call = parse_vc,
4348         },
4349         [ACTION_DEC_TTL] = {
4350                 .name = "dec_ttl",
4351                 .help = "decrease network TTL if available",
4352                 .priv = PRIV_ACTION(DEC_TTL, 0),
4353                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4354                 .call = parse_vc,
4355         },
4356         [ACTION_SET_TTL] = {
4357                 .name = "set_ttl",
4358                 .help = "set ttl value",
4359                 .priv = PRIV_ACTION(SET_TTL,
4360                         sizeof(struct rte_flow_action_set_ttl)),
4361                 .next = NEXT(action_set_ttl),
4362                 .call = parse_vc,
4363         },
4364         [ACTION_SET_TTL_TTL] = {
4365                 .name = "ttl_value",
4366                 .help = "new ttl value to set",
4367                 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)),
4368                 .args = ARGS(ARGS_ENTRY_HTON
4369                              (struct rte_flow_action_set_ttl, ttl_value)),
4370                 .call = parse_vc_conf,
4371         },
4372         [ACTION_SET_MAC_SRC] = {
4373                 .name = "set_mac_src",
4374                 .help = "set source mac address",
4375                 .priv = PRIV_ACTION(SET_MAC_SRC,
4376                         sizeof(struct rte_flow_action_set_mac)),
4377                 .next = NEXT(action_set_mac_src),
4378                 .call = parse_vc,
4379         },
4380         [ACTION_SET_MAC_SRC_MAC_SRC] = {
4381                 .name = "mac_addr",
4382                 .help = "new source mac address",
4383                 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)),
4384                 .args = ARGS(ARGS_ENTRY_HTON
4385                              (struct rte_flow_action_set_mac, mac_addr)),
4386                 .call = parse_vc_conf,
4387         },
4388         [ACTION_SET_MAC_DST] = {
4389                 .name = "set_mac_dst",
4390                 .help = "set destination mac address",
4391                 .priv = PRIV_ACTION(SET_MAC_DST,
4392                         sizeof(struct rte_flow_action_set_mac)),
4393                 .next = NEXT(action_set_mac_dst),
4394                 .call = parse_vc,
4395         },
4396         [ACTION_SET_MAC_DST_MAC_DST] = {
4397                 .name = "mac_addr",
4398                 .help = "new destination mac address to set",
4399                 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)),
4400                 .args = ARGS(ARGS_ENTRY_HTON
4401                              (struct rte_flow_action_set_mac, mac_addr)),
4402                 .call = parse_vc_conf,
4403         },
4404         [ACTION_INC_TCP_SEQ] = {
4405                 .name = "inc_tcp_seq",
4406                 .help = "increase TCP sequence number",
4407                 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)),
4408                 .next = NEXT(action_inc_tcp_seq),
4409                 .call = parse_vc,
4410         },
4411         [ACTION_INC_TCP_SEQ_VALUE] = {
4412                 .name = "value",
4413                 .help = "the value to increase TCP sequence number by",
4414                 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)),
4415                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
4416                 .call = parse_vc_conf,
4417         },
4418         [ACTION_DEC_TCP_SEQ] = {
4419                 .name = "dec_tcp_seq",
4420                 .help = "decrease TCP sequence number",
4421                 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)),
4422                 .next = NEXT(action_dec_tcp_seq),
4423                 .call = parse_vc,
4424         },
4425         [ACTION_DEC_TCP_SEQ_VALUE] = {
4426                 .name = "value",
4427                 .help = "the value to decrease TCP sequence number by",
4428                 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)),
4429                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
4430                 .call = parse_vc_conf,
4431         },
4432         [ACTION_INC_TCP_ACK] = {
4433                 .name = "inc_tcp_ack",
4434                 .help = "increase TCP acknowledgment number",
4435                 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)),
4436                 .next = NEXT(action_inc_tcp_ack),
4437                 .call = parse_vc,
4438         },
4439         [ACTION_INC_TCP_ACK_VALUE] = {
4440                 .name = "value",
4441                 .help = "the value to increase TCP acknowledgment number by",
4442                 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)),
4443                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
4444                 .call = parse_vc_conf,
4445         },
4446         [ACTION_DEC_TCP_ACK] = {
4447                 .name = "dec_tcp_ack",
4448                 .help = "decrease TCP acknowledgment number",
4449                 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
4450                 .next = NEXT(action_dec_tcp_ack),
4451                 .call = parse_vc,
4452         },
4453         [ACTION_DEC_TCP_ACK_VALUE] = {
4454                 .name = "value",
4455                 .help = "the value to decrease TCP acknowledgment number by",
4456                 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)),
4457                 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
4458                 .call = parse_vc_conf,
4459         },
4460         [ACTION_RAW_ENCAP] = {
4461                 .name = "raw_encap",
4462                 .help = "encapsulation data, defined by set raw_encap",
4463                 .priv = PRIV_ACTION(RAW_ENCAP,
4464                         sizeof(struct action_raw_encap_data)),
4465                 .next = NEXT(action_raw_encap),
4466                 .call = parse_vc_action_raw_encap,
4467         },
4468         [ACTION_RAW_ENCAP_INDEX] = {
4469                 .name = "index",
4470                 .help = "the index of raw_encap_confs",
4471                 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)),
4472         },
4473         [ACTION_RAW_ENCAP_INDEX_VALUE] = {
4474                 .name = "{index}",
4475                 .type = "UNSIGNED",
4476                 .help = "unsigned integer value",
4477                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4478                 .call = parse_vc_action_raw_encap_index,
4479                 .comp = comp_set_raw_index,
4480         },
4481         [ACTION_RAW_DECAP] = {
4482                 .name = "raw_decap",
4483                 .help = "decapsulation data, defined by set raw_encap",
4484                 .priv = PRIV_ACTION(RAW_DECAP,
4485                         sizeof(struct action_raw_decap_data)),
4486                 .next = NEXT(action_raw_decap),
4487                 .call = parse_vc_action_raw_decap,
4488         },
4489         [ACTION_RAW_DECAP_INDEX] = {
4490                 .name = "index",
4491                 .help = "the index of raw_encap_confs",
4492                 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)),
4493         },
4494         [ACTION_RAW_DECAP_INDEX_VALUE] = {
4495                 .name = "{index}",
4496                 .type = "UNSIGNED",
4497                 .help = "unsigned integer value",
4498                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4499                 .call = parse_vc_action_raw_decap_index,
4500                 .comp = comp_set_raw_index,
4501         },
4502         [ACTION_MODIFY_FIELD] = {
4503                 .name = "modify_field",
4504                 .help = "modify destination field with data from source field",
4505                 .priv = PRIV_ACTION(MODIFY_FIELD,
4506                         sizeof(struct rte_flow_action_modify_field)),
4507                 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)),
4508                 .call = parse_vc,
4509         },
4510         [ACTION_MODIFY_FIELD_OP] = {
4511                 .name = "op",
4512                 .help = "operation type",
4513                 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE),
4514                         NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)),
4515                 .call = parse_vc_conf,
4516         },
4517         [ACTION_MODIFY_FIELD_OP_VALUE] = {
4518                 .name = "{operation}",
4519                 .help = "operation type value",
4520                 .call = parse_vc_modify_field_op,
4521                 .comp = comp_set_modify_field_op,
4522         },
4523         [ACTION_MODIFY_FIELD_DST_TYPE] = {
4524                 .name = "dst_type",
4525                 .help = "destination field type",
4526                 .next = NEXT(action_modify_field_dst,
4527                         NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)),
4528                 .call = parse_vc_conf,
4529         },
4530         [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = {
4531                 .name = "{dst_type}",
4532                 .help = "destination field type value",
4533                 .call = parse_vc_modify_field_id,
4534                 .comp = comp_set_modify_field_id,
4535         },
4536         [ACTION_MODIFY_FIELD_DST_LEVEL] = {
4537                 .name = "dst_level",
4538                 .help = "destination field level",
4539                 .next = NEXT(action_modify_field_dst,
4540                              NEXT_ENTRY(COMMON_UNSIGNED)),
4541                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
4542                                         dst.level)),
4543                 .call = parse_vc_conf,
4544         },
4545         [ACTION_MODIFY_FIELD_DST_OFFSET] = {
4546                 .name = "dst_offset",
4547                 .help = "destination field bit offset",
4548                 .next = NEXT(action_modify_field_dst,
4549                              NEXT_ENTRY(COMMON_UNSIGNED)),
4550                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
4551                                         dst.offset)),
4552                 .call = parse_vc_conf,
4553         },
4554         [ACTION_MODIFY_FIELD_SRC_TYPE] = {
4555                 .name = "src_type",
4556                 .help = "source field type",
4557                 .next = NEXT(action_modify_field_src,
4558                         NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)),
4559                 .call = parse_vc_conf,
4560         },
4561         [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = {
4562                 .name = "{src_type}",
4563                 .help = "source field type value",
4564                 .call = parse_vc_modify_field_id,
4565                 .comp = comp_set_modify_field_id,
4566         },
4567         [ACTION_MODIFY_FIELD_SRC_LEVEL] = {
4568                 .name = "src_level",
4569                 .help = "source field level",
4570                 .next = NEXT(action_modify_field_src,
4571                              NEXT_ENTRY(COMMON_UNSIGNED)),
4572                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
4573                                         src.level)),
4574                 .call = parse_vc_conf,
4575         },
4576         [ACTION_MODIFY_FIELD_SRC_OFFSET] = {
4577                 .name = "src_offset",
4578                 .help = "source field bit offset",
4579                 .next = NEXT(action_modify_field_src,
4580                              NEXT_ENTRY(COMMON_UNSIGNED)),
4581                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
4582                                         src.offset)),
4583                 .call = parse_vc_conf,
4584         },
4585         [ACTION_MODIFY_FIELD_SRC_VALUE] = {
4586                 .name = "src_value",
4587                 .help = "source immediate value",
4588                 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH),
4589                         NEXT_ENTRY(COMMON_UNSIGNED)),
4590                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
4591                                         src.value)),
4592                 .call = parse_vc_conf,
4593         },
4594         [ACTION_MODIFY_FIELD_WIDTH] = {
4595                 .name = "width",
4596                 .help = "number of bits to copy",
4597                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT),
4598                         NEXT_ENTRY(COMMON_UNSIGNED)),
4599                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
4600                                         width)),
4601                 .call = parse_vc_conf,
4602         },
4603         /* Top level command. */
4604         [SET] = {
4605                 .name = "set",
4606                 .help = "set raw encap/decap/sample data",
4607                 .type = "set raw_encap|raw_decap <index> <pattern>"
4608                                 " or set sample_actions <index> <action>",
4609                 .next = NEXT(NEXT_ENTRY
4610                              (SET_RAW_ENCAP,
4611                               SET_RAW_DECAP,
4612                               SET_SAMPLE_ACTIONS)),
4613                 .call = parse_set_init,
4614         },
4615         /* Sub-level commands. */
4616         [SET_RAW_ENCAP] = {
4617                 .name = "raw_encap",
4618                 .help = "set raw encap data",
4619                 .next = NEXT(next_set_raw),
4620                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
4621                                 (offsetof(struct buffer, port),
4622                                  sizeof(((struct buffer *)0)->port),
4623                                  0, RAW_ENCAP_CONFS_MAX_NUM - 1)),
4624                 .call = parse_set_raw_encap_decap,
4625         },
4626         [SET_RAW_DECAP] = {
4627                 .name = "raw_decap",
4628                 .help = "set raw decap data",
4629                 .next = NEXT(next_set_raw),
4630                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
4631                                 (offsetof(struct buffer, port),
4632                                  sizeof(((struct buffer *)0)->port),
4633                                  0, RAW_ENCAP_CONFS_MAX_NUM - 1)),
4634                 .call = parse_set_raw_encap_decap,
4635         },
4636         [SET_RAW_INDEX] = {
4637                 .name = "{index}",
4638                 .type = "COMMON_UNSIGNED",
4639                 .help = "index of raw_encap/raw_decap data",
4640                 .next = NEXT(next_item),
4641                 .call = parse_port,
4642         },
4643         [SET_SAMPLE_INDEX] = {
4644                 .name = "{index}",
4645                 .type = "UNSIGNED",
4646                 .help = "index of sample actions",
4647                 .next = NEXT(next_action_sample),
4648                 .call = parse_port,
4649         },
4650         [SET_SAMPLE_ACTIONS] = {
4651                 .name = "sample_actions",
4652                 .help = "set sample actions list",
4653                 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)),
4654                 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED
4655                                 (offsetof(struct buffer, port),
4656                                  sizeof(((struct buffer *)0)->port),
4657                                  0, RAW_SAMPLE_CONFS_MAX_NUM - 1)),
4658                 .call = parse_set_sample_action,
4659         },
4660         [ACTION_SET_TAG] = {
4661                 .name = "set_tag",
4662                 .help = "set tag",
4663                 .priv = PRIV_ACTION(SET_TAG,
4664                         sizeof(struct rte_flow_action_set_tag)),
4665                 .next = NEXT(action_set_tag),
4666                 .call = parse_vc,
4667         },
4668         [ACTION_SET_TAG_INDEX] = {
4669                 .name = "index",
4670                 .help = "index of tag array",
4671                 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)),
4672                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)),
4673                 .call = parse_vc_conf,
4674         },
4675         [ACTION_SET_TAG_DATA] = {
4676                 .name = "data",
4677                 .help = "tag value",
4678                 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)),
4679                 .args = ARGS(ARGS_ENTRY
4680                              (struct rte_flow_action_set_tag, data)),
4681                 .call = parse_vc_conf,
4682         },
4683         [ACTION_SET_TAG_MASK] = {
4684                 .name = "mask",
4685                 .help = "mask for tag value",
4686                 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)),
4687                 .args = ARGS(ARGS_ENTRY
4688                              (struct rte_flow_action_set_tag, mask)),
4689                 .call = parse_vc_conf,
4690         },
4691         [ACTION_SET_META] = {
4692                 .name = "set_meta",
4693                 .help = "set metadata",
4694                 .priv = PRIV_ACTION(SET_META,
4695                         sizeof(struct rte_flow_action_set_meta)),
4696                 .next = NEXT(action_set_meta),
4697                 .call = parse_vc_action_set_meta,
4698         },
4699         [ACTION_SET_META_DATA] = {
4700                 .name = "data",
4701                 .help = "metadata value",
4702                 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)),
4703                 .args = ARGS(ARGS_ENTRY
4704                              (struct rte_flow_action_set_meta, data)),
4705                 .call = parse_vc_conf,
4706         },
4707         [ACTION_SET_META_MASK] = {
4708                 .name = "mask",
4709                 .help = "mask for metadata value",
4710                 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)),
4711                 .args = ARGS(ARGS_ENTRY
4712                              (struct rte_flow_action_set_meta, mask)),
4713                 .call = parse_vc_conf,
4714         },
4715         [ACTION_SET_IPV4_DSCP] = {
4716                 .name = "set_ipv4_dscp",
4717                 .help = "set DSCP value",
4718                 .priv = PRIV_ACTION(SET_IPV4_DSCP,
4719                         sizeof(struct rte_flow_action_set_dscp)),
4720                 .next = NEXT(action_set_ipv4_dscp),
4721                 .call = parse_vc,
4722         },
4723         [ACTION_SET_IPV4_DSCP_VALUE] = {
4724                 .name = "dscp_value",
4725                 .help = "new IPv4 DSCP value to set",
4726                 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)),
4727                 .args = ARGS(ARGS_ENTRY
4728                              (struct rte_flow_action_set_dscp, dscp)),
4729                 .call = parse_vc_conf,
4730         },
4731         [ACTION_SET_IPV6_DSCP] = {
4732                 .name = "set_ipv6_dscp",
4733                 .help = "set DSCP value",
4734                 .priv = PRIV_ACTION(SET_IPV6_DSCP,
4735                         sizeof(struct rte_flow_action_set_dscp)),
4736                 .next = NEXT(action_set_ipv6_dscp),
4737                 .call = parse_vc,
4738         },
4739         [ACTION_SET_IPV6_DSCP_VALUE] = {
4740                 .name = "dscp_value",
4741                 .help = "new IPv6 DSCP value to set",
4742                 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)),
4743                 .args = ARGS(ARGS_ENTRY
4744                              (struct rte_flow_action_set_dscp, dscp)),
4745                 .call = parse_vc_conf,
4746         },
4747         [ACTION_AGE] = {
4748                 .name = "age",
4749                 .help = "set a specific metadata header",
4750                 .next = NEXT(action_age),
4751                 .priv = PRIV_ACTION(AGE,
4752                         sizeof(struct rte_flow_action_age)),
4753                 .call = parse_vc,
4754         },
4755         [ACTION_AGE_TIMEOUT] = {
4756                 .name = "timeout",
4757                 .help = "flow age timeout value",
4758                 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age,
4759                                            timeout, 24)),
4760                 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)),
4761                 .call = parse_vc_conf,
4762         },
4763         [ACTION_SAMPLE] = {
4764                 .name = "sample",
4765                 .help = "set a sample action",
4766                 .next = NEXT(action_sample),
4767                 .priv = PRIV_ACTION(SAMPLE,
4768                         sizeof(struct action_sample_data)),
4769                 .call = parse_vc_action_sample,
4770         },
4771         [ACTION_SAMPLE_RATIO] = {
4772                 .name = "ratio",
4773                 .help = "flow sample ratio value",
4774                 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)),
4775                 .args = ARGS(ARGS_ENTRY_ARB
4776                              (offsetof(struct action_sample_data, conf) +
4777                               offsetof(struct rte_flow_action_sample, ratio),
4778                               sizeof(((struct rte_flow_action_sample *)0)->
4779                                      ratio))),
4780         },
4781         [ACTION_SAMPLE_INDEX] = {
4782                 .name = "index",
4783                 .help = "the index of sample actions list",
4784                 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)),
4785         },
4786         [ACTION_SAMPLE_INDEX_VALUE] = {
4787                 .name = "{index}",
4788                 .type = "COMMON_UNSIGNED",
4789                 .help = "unsigned integer value",
4790                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4791                 .call = parse_vc_action_sample_index,
4792                 .comp = comp_set_sample_index,
4793         },
4794         [ACTION_CONNTRACK] = {
4795                 .name = "conntrack",
4796                 .help = "create a conntrack object",
4797                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4798                 .priv = PRIV_ACTION(CONNTRACK,
4799                                     sizeof(struct rte_flow_action_conntrack)),
4800                 .call = parse_vc,
4801         },
4802         [ACTION_CONNTRACK_UPDATE] = {
4803                 .name = "conntrack_update",
4804                 .help = "update a conntrack object",
4805                 .next = NEXT(action_update_conntrack),
4806                 .priv = PRIV_ACTION(CONNTRACK,
4807                                     sizeof(struct rte_flow_modify_conntrack)),
4808                 .call = parse_vc,
4809         },
4810         [ACTION_CONNTRACK_UPDATE_DIR] = {
4811                 .name = "dir",
4812                 .help = "update a conntrack object direction",
4813                 .next = NEXT(action_update_conntrack),
4814                 .call = parse_vc_action_conntrack_update,
4815         },
4816         [ACTION_CONNTRACK_UPDATE_CTX] = {
4817                 .name = "ctx",
4818                 .help = "update a conntrack object context",
4819                 .next = NEXT(action_update_conntrack),
4820                 .call = parse_vc_action_conntrack_update,
4821         },
4822         [ACTION_PORT_REPRESENTOR] = {
4823                 .name = "port_representor",
4824                 .help = "at embedded switch level, send matching traffic to the given ethdev",
4825                 .priv = PRIV_ACTION(PORT_REPRESENTOR,
4826                                     sizeof(struct rte_flow_action_ethdev)),
4827                 .next = NEXT(action_port_representor),
4828                 .call = parse_vc,
4829         },
4830         [ACTION_PORT_REPRESENTOR_PORT_ID] = {
4831                 .name = "port_id",
4832                 .help = "ethdev port ID",
4833                 .next = NEXT(action_port_representor,
4834                              NEXT_ENTRY(COMMON_UNSIGNED)),
4835                 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev,
4836                                         port_id)),
4837                 .call = parse_vc_conf,
4838         },
4839         /* Indirect action destroy arguments. */
4840         [INDIRECT_ACTION_DESTROY_ID] = {
4841                 .name = "action_id",
4842                 .help = "specify a indirect action id to destroy",
4843                 .next = NEXT(next_ia_destroy_attr,
4844                              NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
4845                 .args = ARGS(ARGS_ENTRY_PTR(struct buffer,
4846                                             args.ia_destroy.action_id)),
4847                 .call = parse_ia_destroy,
4848         },
4849         /* Indirect action create arguments. */
4850         [INDIRECT_ACTION_CREATE_ID] = {
4851                 .name = "action_id",
4852                 .help = "specify a indirect action id to create",
4853                 .next = NEXT(next_ia_create_attr,
4854                              NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
4855                 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)),
4856         },
4857         [ACTION_INDIRECT] = {
4858                 .name = "indirect",
4859                 .help = "apply indirect action by id",
4860                 .priv = PRIV_ACTION(INDIRECT, 0),
4861                 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)),
4862                 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))),
4863                 .call = parse_vc,
4864         },
4865         [INDIRECT_ACTION_ID2PTR] = {
4866                 .name = "{action_id}",
4867                 .type = "INDIRECT_ACTION_ID",
4868                 .help = "indirect action id",
4869                 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
4870                 .call = parse_ia_id2ptr,
4871                 .comp = comp_none,
4872         },
4873         [INDIRECT_ACTION_INGRESS] = {
4874                 .name = "ingress",
4875                 .help = "affect rule to ingress",
4876                 .next = NEXT(next_ia_create_attr),
4877                 .call = parse_ia,
4878         },
4879         [INDIRECT_ACTION_EGRESS] = {
4880                 .name = "egress",
4881                 .help = "affect rule to egress",
4882                 .next = NEXT(next_ia_create_attr),
4883                 .call = parse_ia,
4884         },
4885         [INDIRECT_ACTION_TRANSFER] = {
4886                 .name = "transfer",
4887                 .help = "affect rule to transfer",
4888                 .next = NEXT(next_ia_create_attr),
4889                 .call = parse_ia,
4890         },
4891         [INDIRECT_ACTION_SPEC] = {
4892                 .name = "action",
4893                 .help = "specify action to create indirect handle",
4894                 .next = NEXT(next_action),
4895         },
4896         [ACTION_POL_G] = {
4897                 .name = "g_actions",
4898                 .help = "submit a list of associated actions for green",
4899                 .next = NEXT(next_action),
4900                 .call = parse_mp,
4901         },
4902         [ACTION_POL_Y] = {
4903                 .name = "y_actions",
4904                 .help = "submit a list of associated actions for yellow",
4905                 .next = NEXT(next_action),
4906         },
4907         [ACTION_POL_R] = {
4908                 .name = "r_actions",
4909                 .help = "submit a list of associated actions for red",
4910                 .next = NEXT(next_action),
4911         },
4912
4913         /* Top-level command. */
4914         [ADD] = {
4915                 .name = "add",
4916                 .type = "port meter policy {port_id} {arg}",
4917                 .help = "add port meter policy",
4918                 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)),
4919                 .call = parse_init,
4920         },
4921         /* Sub-level commands. */
4922         [ITEM_POL_PORT] = {
4923                 .name = "port",
4924                 .help = "add port meter policy",
4925                 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)),
4926         },
4927         [ITEM_POL_METER] = {
4928                 .name = "meter",
4929                 .help = "add port meter policy",
4930                 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)),
4931         },
4932         [ITEM_POL_POLICY] = {
4933                 .name = "policy",
4934                 .help = "add port meter policy",
4935                 .next = NEXT(NEXT_ENTRY(ACTION_POL_R),
4936                                 NEXT_ENTRY(ACTION_POL_Y),
4937                                 NEXT_ENTRY(ACTION_POL_G),
4938                                 NEXT_ENTRY(COMMON_POLICY_ID),
4939                                 NEXT_ENTRY(COMMON_PORT_ID)),
4940                 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id),
4941                                 ARGS_ENTRY(struct buffer, port)),
4942                 .call = parse_mp,
4943         },
4944 };
4945
4946 /** Remove and return last entry from argument stack. */
4947 static const struct arg *
4948 pop_args(struct context *ctx)
4949 {
4950         return ctx->args_num ? ctx->args[--ctx->args_num] : NULL;
4951 }
4952
4953 /** Add entry on top of the argument stack. */
4954 static int
4955 push_args(struct context *ctx, const struct arg *arg)
4956 {
4957         if (ctx->args_num == CTX_STACK_SIZE)
4958                 return -1;
4959         ctx->args[ctx->args_num++] = arg;
4960         return 0;
4961 }
4962
4963 /** Spread value into buffer according to bit-mask. */
4964 static size_t
4965 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg)
4966 {
4967         uint32_t i = arg->size;
4968         uint32_t end = 0;
4969         int sub = 1;
4970         int add = 0;
4971         size_t len = 0;
4972
4973         if (!arg->mask)
4974                 return 0;
4975 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
4976         if (!arg->hton) {
4977                 i = 0;
4978                 end = arg->size;
4979                 sub = 0;
4980                 add = 1;
4981         }
4982 #endif
4983         while (i != end) {
4984                 unsigned int shift = 0;
4985                 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub);
4986
4987                 for (shift = 0; arg->mask[i] >> shift; ++shift) {
4988                         if (!(arg->mask[i] & (1 << shift)))
4989                                 continue;
4990                         ++len;
4991                         if (!dst)
4992                                 continue;
4993                         *buf &= ~(1 << shift);
4994                         *buf |= (val & 1) << shift;
4995                         val >>= 1;
4996                 }
4997                 i += add;
4998         }
4999         return len;
5000 }
5001
5002 /** Compare a string with a partial one of a given length. */
5003 static int
5004 strcmp_partial(const char *full, const char *partial, size_t partial_len)
5005 {
5006         int r = strncmp(full, partial, partial_len);
5007
5008         if (r)
5009                 return r;
5010         if (strlen(full) <= partial_len)
5011                 return 0;
5012         return full[partial_len];
5013 }
5014
5015 /**
5016  * Parse a prefix length and generate a bit-mask.
5017  *
5018  * Last argument (ctx->args) is retrieved to determine mask size, storage
5019  * location and whether the result must use network byte ordering.
5020  */
5021 static int
5022 parse_prefix(struct context *ctx, const struct token *token,
5023              const char *str, unsigned int len,
5024              void *buf, unsigned int size)
5025 {
5026         const struct arg *arg = pop_args(ctx);
5027         static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff";
5028         char *end;
5029         uintmax_t u;
5030         unsigned int bytes;
5031         unsigned int extra;
5032
5033         (void)token;
5034         /* Argument is expected. */
5035         if (!arg)
5036                 return -1;
5037         errno = 0;
5038         u = strtoumax(str, &end, 0);
5039         if (errno || (size_t)(end - str) != len)
5040                 goto error;
5041         if (arg->mask) {
5042                 uintmax_t v = 0;
5043
5044                 extra = arg_entry_bf_fill(NULL, 0, arg);
5045                 if (u > extra)
5046                         goto error;
5047                 if (!ctx->object)
5048                         return len;
5049                 extra -= u;
5050                 while (u--)
5051                         (v <<= 1, v |= 1);
5052                 v <<= extra;
5053                 if (!arg_entry_bf_fill(ctx->object, v, arg) ||
5054                     !arg_entry_bf_fill(ctx->objmask, -1, arg))
5055                         goto error;
5056                 return len;
5057         }
5058         bytes = u / 8;
5059         extra = u % 8;
5060         size = arg->size;
5061         if (bytes > size || bytes + !!extra > size)
5062                 goto error;
5063         if (!ctx->object)
5064                 return len;
5065         buf = (uint8_t *)ctx->object + arg->offset;
5066 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
5067         if (!arg->hton) {
5068                 memset((uint8_t *)buf + size - bytes, 0xff, bytes);
5069                 memset(buf, 0x00, size - bytes);
5070                 if (extra)
5071                         ((uint8_t *)buf)[size - bytes - 1] = conv[extra];
5072         } else
5073 #endif
5074         {
5075                 memset(buf, 0xff, bytes);
5076                 memset((uint8_t *)buf + bytes, 0x00, size - bytes);
5077                 if (extra)
5078                         ((uint8_t *)buf)[bytes] = conv[extra];
5079         }
5080         if (ctx->objmask)
5081                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
5082         return len;
5083 error:
5084         push_args(ctx, arg);
5085         return -1;
5086 }
5087
5088 /** Default parsing function for token name matching. */
5089 static int
5090 parse_default(struct context *ctx, const struct token *token,
5091               const char *str, unsigned int len,
5092               void *buf, unsigned int size)
5093 {
5094         (void)ctx;
5095         (void)buf;
5096         (void)size;
5097         if (strcmp_partial(token->name, str, len))
5098                 return -1;
5099         return len;
5100 }
5101
5102 /** Parse flow command, initialize output buffer for subsequent tokens. */
5103 static int
5104 parse_init(struct context *ctx, const struct token *token,
5105            const char *str, unsigned int len,
5106            void *buf, unsigned int size)
5107 {
5108         struct buffer *out = buf;
5109
5110         /* Token name must match. */
5111         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5112                 return -1;
5113         /* Nothing else to do if there is no buffer. */
5114         if (!out)
5115                 return len;
5116         /* Make sure buffer is large enough. */
5117         if (size < sizeof(*out))
5118                 return -1;
5119         /* Initialize buffer. */
5120         memset(out, 0x00, sizeof(*out));
5121         memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out));
5122         ctx->objdata = 0;
5123         ctx->object = out;
5124         ctx->objmask = NULL;
5125         return len;
5126 }
5127
5128 /** Parse tokens for indirect action commands. */
5129 static int
5130 parse_ia(struct context *ctx, const struct token *token,
5131          const char *str, unsigned int len,
5132          void *buf, unsigned int size)
5133 {
5134         struct buffer *out = buf;
5135
5136         /* Token name must match. */
5137         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5138                 return -1;
5139         /* Nothing else to do if there is no buffer. */
5140         if (!out)
5141                 return len;
5142         if (!out->command) {
5143                 if (ctx->curr != INDIRECT_ACTION)
5144                         return -1;
5145                 if (sizeof(*out) > size)
5146                         return -1;
5147                 out->command = ctx->curr;
5148                 ctx->objdata = 0;
5149                 ctx->object = out;
5150                 ctx->objmask = NULL;
5151                 out->args.vc.data = (uint8_t *)out + size;
5152                 return len;
5153         }
5154         switch (ctx->curr) {
5155         case INDIRECT_ACTION_CREATE:
5156         case INDIRECT_ACTION_UPDATE:
5157                 out->args.vc.actions =
5158                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
5159                                                sizeof(double));
5160                 out->args.vc.attr.group = UINT32_MAX;
5161                 /* fallthrough */
5162         case INDIRECT_ACTION_QUERY:
5163                 out->command = ctx->curr;
5164                 ctx->objdata = 0;
5165                 ctx->object = out;
5166                 ctx->objmask = NULL;
5167                 return len;
5168         case INDIRECT_ACTION_EGRESS:
5169                 out->args.vc.attr.egress = 1;
5170                 return len;
5171         case INDIRECT_ACTION_INGRESS:
5172                 out->args.vc.attr.ingress = 1;
5173                 return len;
5174         case INDIRECT_ACTION_TRANSFER:
5175                 out->args.vc.attr.transfer = 1;
5176                 return len;
5177         default:
5178                 return -1;
5179         }
5180 }
5181
5182
5183 /** Parse tokens for indirect action destroy command. */
5184 static int
5185 parse_ia_destroy(struct context *ctx, const struct token *token,
5186                  const char *str, unsigned int len,
5187                  void *buf, unsigned int size)
5188 {
5189         struct buffer *out = buf;
5190         uint32_t *action_id;
5191
5192         /* Token name must match. */
5193         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5194                 return -1;
5195         /* Nothing else to do if there is no buffer. */
5196         if (!out)
5197                 return len;
5198         if (!out->command || out->command == INDIRECT_ACTION) {
5199                 if (ctx->curr != INDIRECT_ACTION_DESTROY)
5200                         return -1;
5201                 if (sizeof(*out) > size)
5202                         return -1;
5203                 out->command = ctx->curr;
5204                 ctx->objdata = 0;
5205                 ctx->object = out;
5206                 ctx->objmask = NULL;
5207                 out->args.ia_destroy.action_id =
5208                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
5209                                                sizeof(double));
5210                 return len;
5211         }
5212         action_id = out->args.ia_destroy.action_id
5213                     + out->args.ia_destroy.action_id_n++;
5214         if ((uint8_t *)action_id > (uint8_t *)out + size)
5215                 return -1;
5216         ctx->objdata = 0;
5217         ctx->object = action_id;
5218         ctx->objmask = NULL;
5219         return len;
5220 }
5221
5222 /** Parse tokens for meter policy action commands. */
5223 static int
5224 parse_mp(struct context *ctx, const struct token *token,
5225         const char *str, unsigned int len,
5226         void *buf, unsigned int size)
5227 {
5228         struct buffer *out = buf;
5229
5230         /* Token name must match. */
5231         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5232                 return -1;
5233         /* Nothing else to do if there is no buffer. */
5234         if (!out)
5235                 return len;
5236         if (!out->command) {
5237                 if (ctx->curr != ITEM_POL_POLICY)
5238                         return -1;
5239                 if (sizeof(*out) > size)
5240                         return -1;
5241                 out->command = ctx->curr;
5242                 ctx->objdata = 0;
5243                 ctx->object = out;
5244                 ctx->objmask = NULL;
5245                 out->args.vc.data = (uint8_t *)out + size;
5246                 return len;
5247         }
5248         switch (ctx->curr) {
5249         case ACTION_POL_G:
5250                 out->args.vc.actions =
5251                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
5252                                         sizeof(double));
5253                 out->command = ctx->curr;
5254                 ctx->objdata = 0;
5255                 ctx->object = out;
5256                 ctx->objmask = NULL;
5257                 return len;
5258         default:
5259                 return -1;
5260         }
5261 }
5262
5263 /** Parse tokens for validate/create commands. */
5264 static int
5265 parse_vc(struct context *ctx, const struct token *token,
5266          const char *str, unsigned int len,
5267          void *buf, unsigned int size)
5268 {
5269         struct buffer *out = buf;
5270         uint8_t *data;
5271         uint32_t data_size;
5272
5273         /* Token name must match. */
5274         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5275                 return -1;
5276         /* Nothing else to do if there is no buffer. */
5277         if (!out)
5278                 return len;
5279         if (!out->command) {
5280                 if (ctx->curr != VALIDATE && ctx->curr != CREATE)
5281                         return -1;
5282                 if (sizeof(*out) > size)
5283                         return -1;
5284                 out->command = ctx->curr;
5285                 ctx->objdata = 0;
5286                 ctx->object = out;
5287                 ctx->objmask = NULL;
5288                 out->args.vc.data = (uint8_t *)out + size;
5289                 return len;
5290         }
5291         ctx->objdata = 0;
5292         switch (ctx->curr) {
5293         default:
5294                 ctx->object = &out->args.vc.attr;
5295                 break;
5296         case VC_TUNNEL_SET:
5297         case VC_TUNNEL_MATCH:
5298                 ctx->object = &out->args.vc.tunnel_ops;
5299                 break;
5300         }
5301         ctx->objmask = NULL;
5302         switch (ctx->curr) {
5303         case VC_GROUP:
5304         case VC_PRIORITY:
5305                 return len;
5306         case VC_TUNNEL_SET:
5307                 out->args.vc.tunnel_ops.enabled = 1;
5308                 out->args.vc.tunnel_ops.actions = 1;
5309                 return len;
5310         case VC_TUNNEL_MATCH:
5311                 out->args.vc.tunnel_ops.enabled = 1;
5312                 out->args.vc.tunnel_ops.items = 1;
5313                 return len;
5314         case VC_INGRESS:
5315                 out->args.vc.attr.ingress = 1;
5316                 return len;
5317         case VC_EGRESS:
5318                 out->args.vc.attr.egress = 1;
5319                 return len;
5320         case VC_TRANSFER:
5321                 out->args.vc.attr.transfer = 1;
5322                 return len;
5323         case ITEM_PATTERN:
5324                 out->args.vc.pattern =
5325                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
5326                                                sizeof(double));
5327                 ctx->object = out->args.vc.pattern;
5328                 ctx->objmask = NULL;
5329                 return len;
5330         case ACTIONS:
5331                 out->args.vc.actions =
5332                         (void *)RTE_ALIGN_CEIL((uintptr_t)
5333                                                (out->args.vc.pattern +
5334                                                 out->args.vc.pattern_n),
5335                                                sizeof(double));
5336                 ctx->object = out->args.vc.actions;
5337                 ctx->objmask = NULL;
5338                 return len;
5339         default:
5340                 if (!token->priv)
5341                         return -1;
5342                 break;
5343         }
5344         if (!out->args.vc.actions) {
5345                 const struct parse_item_priv *priv = token->priv;
5346                 struct rte_flow_item *item =
5347                         out->args.vc.pattern + out->args.vc.pattern_n;
5348
5349                 data_size = priv->size * 3; /* spec, last, mask */
5350                 data = (void *)RTE_ALIGN_FLOOR((uintptr_t)
5351                                                (out->args.vc.data - data_size),
5352                                                sizeof(double));
5353                 if ((uint8_t *)item + sizeof(*item) > data)
5354                         return -1;
5355                 *item = (struct rte_flow_item){
5356                         .type = priv->type,
5357                 };
5358                 ++out->args.vc.pattern_n;
5359                 ctx->object = item;
5360                 ctx->objmask = NULL;
5361         } else {
5362                 const struct parse_action_priv *priv = token->priv;
5363                 struct rte_flow_action *action =
5364                         out->args.vc.actions + out->args.vc.actions_n;
5365
5366                 data_size = priv->size; /* configuration */
5367                 data = (void *)RTE_ALIGN_FLOOR((uintptr_t)
5368                                                (out->args.vc.data - data_size),
5369                                                sizeof(double));
5370                 if ((uint8_t *)action + sizeof(*action) > data)
5371                         return -1;
5372                 *action = (struct rte_flow_action){
5373                         .type = priv->type,
5374                         .conf = data_size ? data : NULL,
5375                 };
5376                 ++out->args.vc.actions_n;
5377                 ctx->object = action;
5378                 ctx->objmask = NULL;
5379         }
5380         memset(data, 0, data_size);
5381         out->args.vc.data = data;
5382         ctx->objdata = data_size;
5383         return len;
5384 }
5385
5386 /** Parse pattern item parameter type. */
5387 static int
5388 parse_vc_spec(struct context *ctx, const struct token *token,
5389               const char *str, unsigned int len,
5390               void *buf, unsigned int size)
5391 {
5392         struct buffer *out = buf;
5393         struct rte_flow_item *item;
5394         uint32_t data_size;
5395         int index;
5396         int objmask = 0;
5397
5398         (void)size;
5399         /* Token name must match. */
5400         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5401                 return -1;
5402         /* Parse parameter types. */
5403         switch (ctx->curr) {
5404                 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX);
5405
5406         case ITEM_PARAM_IS:
5407                 index = 0;
5408                 objmask = 1;
5409                 break;
5410         case ITEM_PARAM_SPEC:
5411                 index = 0;
5412                 break;
5413         case ITEM_PARAM_LAST:
5414                 index = 1;
5415                 break;
5416         case ITEM_PARAM_PREFIX:
5417                 /* Modify next token to expect a prefix. */
5418                 if (ctx->next_num < 2)
5419                         return -1;
5420                 ctx->next[ctx->next_num - 2] = prefix;
5421                 /* Fall through. */
5422         case ITEM_PARAM_MASK:
5423                 index = 2;
5424                 break;
5425         default:
5426                 return -1;
5427         }
5428         /* Nothing else to do if there is no buffer. */
5429         if (!out)
5430                 return len;
5431         if (!out->args.vc.pattern_n)
5432                 return -1;
5433         item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
5434         data_size = ctx->objdata / 3; /* spec, last, mask */
5435         /* Point to selected object. */
5436         ctx->object = out->args.vc.data + (data_size * index);
5437         if (objmask) {
5438                 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */
5439                 item->mask = ctx->objmask;
5440         } else
5441                 ctx->objmask = NULL;
5442         /* Update relevant item pointer. */
5443         *((const void **[]){ &item->spec, &item->last, &item->mask })[index] =
5444                 ctx->object;
5445         return len;
5446 }
5447
5448 /** Parse action configuration field. */
5449 static int
5450 parse_vc_conf(struct context *ctx, const struct token *token,
5451               const char *str, unsigned int len,
5452               void *buf, unsigned int size)
5453 {
5454         struct buffer *out = buf;
5455
5456         (void)size;
5457         /* Token name must match. */
5458         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5459                 return -1;
5460         /* Nothing else to do if there is no buffer. */
5461         if (!out)
5462                 return len;
5463         /* Point to selected object. */
5464         ctx->object = out->args.vc.data;
5465         ctx->objmask = NULL;
5466         return len;
5467 }
5468
5469 /** Parse eCPRI common header type field. */
5470 static int
5471 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
5472                          const char *str, unsigned int len,
5473                          void *buf, unsigned int size)
5474 {
5475         struct rte_flow_item_ecpri *ecpri;
5476         struct rte_flow_item_ecpri *ecpri_mask;
5477         struct rte_flow_item *item;
5478         uint32_t data_size;
5479         uint8_t msg_type;
5480         struct buffer *out = buf;
5481         const struct arg *arg;
5482
5483         (void)size;
5484         /* Token name must match. */
5485         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5486                 return -1;
5487         switch (ctx->curr) {
5488         case ITEM_ECPRI_COMMON_TYPE_IQ_DATA:
5489                 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA;
5490                 break;
5491         case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL:
5492                 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL;
5493                 break;
5494         case ITEM_ECPRI_COMMON_TYPE_DLY_MSR:
5495                 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR;
5496                 break;
5497         default:
5498                 return -1;
5499         }
5500         if (!ctx->object)
5501                 return len;
5502         arg = pop_args(ctx);
5503         if (!arg)
5504                 return -1;
5505         ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data;
5506         ecpri->hdr.common.type = msg_type;
5507         data_size = ctx->objdata / 3; /* spec, last, mask */
5508         ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data +
5509                                                     (data_size * 2));
5510         ecpri_mask->hdr.common.type = 0xFF;
5511         if (arg->hton) {
5512                 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32);
5513                 ecpri_mask->hdr.common.u32 =
5514                                 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32);
5515         }
5516         item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
5517         item->spec = ecpri;
5518         item->mask = ecpri_mask;
5519         return len;
5520 }
5521
5522 /** Parse meter color action type. */
5523 static int
5524 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token,
5525                                 const char *str, unsigned int len,
5526                                 void *buf, unsigned int size)
5527 {
5528         struct rte_flow_action *action_data;
5529         struct rte_flow_action_meter_color *conf;
5530         enum rte_color color;
5531
5532         (void)buf;
5533         (void)size;
5534         /* Token name must match. */
5535         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5536                 return -1;
5537         switch (ctx->curr) {
5538         case ACTION_METER_COLOR_GREEN:
5539                 color = RTE_COLOR_GREEN;
5540         break;
5541         case ACTION_METER_COLOR_YELLOW:
5542                 color = RTE_COLOR_YELLOW;
5543         break;
5544         case ACTION_METER_COLOR_RED:
5545                 color = RTE_COLOR_RED;
5546         break;
5547         default:
5548                 return -1;
5549         }
5550
5551         if (!ctx->object)
5552                 return len;
5553         action_data = ctx->object;
5554         conf = (struct rte_flow_action_meter_color *)
5555                                         (uintptr_t)(action_data->conf);
5556         conf->color = color;
5557         return len;
5558 }
5559
5560 /** Parse RSS action. */
5561 static int
5562 parse_vc_action_rss(struct context *ctx, const struct token *token,
5563                     const char *str, unsigned int len,
5564                     void *buf, unsigned int size)
5565 {
5566         struct buffer *out = buf;
5567         struct rte_flow_action *action;
5568         struct action_rss_data *action_rss_data;
5569         unsigned int i;
5570         int ret;
5571
5572         ret = parse_vc(ctx, token, str, len, buf, size);
5573         if (ret < 0)
5574                 return ret;
5575         /* Nothing else to do if there is no buffer. */
5576         if (!out)
5577                 return ret;
5578         if (!out->args.vc.actions_n)
5579                 return -1;
5580         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
5581         /* Point to selected object. */
5582         ctx->object = out->args.vc.data;
5583         ctx->objmask = NULL;
5584         /* Set up default configuration. */
5585         action_rss_data = ctx->object;
5586         *action_rss_data = (struct action_rss_data){
5587                 .conf = (struct rte_flow_action_rss){
5588                         .func = RTE_ETH_HASH_FUNCTION_DEFAULT,
5589                         .level = 0,
5590                         .types = rss_hf,
5591                         .key_len = 0,
5592                         .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
5593                         .key = NULL,
5594                         .queue = action_rss_data->queue,
5595                 },
5596                 .queue = { 0 },
5597         };
5598         for (i = 0; i < action_rss_data->conf.queue_num; ++i)
5599                 action_rss_data->queue[i] = i;
5600         action->conf = &action_rss_data->conf;
5601         return ret;
5602 }
5603
5604 /**
5605  * Parse func field for RSS action.
5606  *
5607  * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the
5608  * ACTION_RSS_FUNC_* index that called this function.
5609  */
5610 static int
5611 parse_vc_action_rss_func(struct context *ctx, const struct token *token,
5612                          const char *str, unsigned int len,
5613                          void *buf, unsigned int size)
5614 {
5615         struct action_rss_data *action_rss_data;
5616         enum rte_eth_hash_function func;
5617
5618         (void)buf;
5619         (void)size;
5620         /* Token name must match. */
5621         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
5622                 return -1;
5623         switch (ctx->curr) {
5624         case ACTION_RSS_FUNC_DEFAULT:
5625                 func = RTE_ETH_HASH_FUNCTION_DEFAULT;
5626                 break;
5627         case ACTION_RSS_FUNC_TOEPLITZ:
5628                 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
5629                 break;
5630         case ACTION_RSS_FUNC_SIMPLE_XOR:
5631                 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
5632                 break;
5633         case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ:
5634                 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ;
5635                 break;
5636         default:
5637                 return -1;
5638         }
5639         if (!ctx->object)
5640                 return len;
5641         action_rss_data = ctx->object;
5642         action_rss_data->conf.func = func;
5643         return len;
5644 }
5645
5646 /**
5647  * Parse type field for RSS action.
5648  *
5649  * Valid tokens are type field names and the "end" token.
5650  */
5651 static int
5652 parse_vc_action_rss_type(struct context *ctx, const struct token *token,
5653                           const char *str, unsigned int len,
5654                           void *buf, unsigned int size)
5655 {
5656         static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE);
5657         struct action_rss_data *action_rss_data;
5658         unsigned int i;
5659
5660         (void)token;
5661         (void)buf;
5662         (void)size;
5663         if (ctx->curr != ACTION_RSS_TYPE)
5664                 return -1;
5665         if (!(ctx->objdata >> 16) && ctx->object) {
5666                 action_rss_data = ctx->object;
5667                 action_rss_data->conf.types = 0;
5668         }
5669         if (!strcmp_partial("end", str, len)) {
5670                 ctx->objdata &= 0xffff;
5671                 return len;
5672         }
5673         for (i = 0; rss_type_table[i].str; ++i)
5674                 if (!strcmp_partial(rss_type_table[i].str, str, len))
5675                         break;
5676         if (!rss_type_table[i].str)
5677                 return -1;
5678         ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff);
5679         /* Repeat token. */
5680         if (ctx->next_num == RTE_DIM(ctx->next))
5681                 return -1;
5682         ctx->next[ctx->next_num++] = next;
5683         if (!ctx->object)
5684                 return len;
5685         action_rss_data = ctx->object;
5686         action_rss_data->conf.types |= rss_type_table[i].rss_type;
5687         return len;
5688 }
5689
5690 /**
5691  * Parse queue field for RSS action.
5692  *
5693  * Valid tokens are queue indices and the "end" token.
5694  */
5695 static int
5696 parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
5697                           const char *str, unsigned int len,
5698                           void *buf, unsigned int size)
5699 {
5700         static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE);
5701         struct action_rss_data *action_rss_data;
5702         const struct arg *arg;
5703         int ret;
5704         int i;
5705
5706         (void)token;
5707         (void)buf;
5708         (void)size;
5709         if (ctx->curr != ACTION_RSS_QUEUE)
5710                 return -1;
5711         i = ctx->objdata >> 16;
5712         if (!strcmp_partial("end", str, len)) {
5713                 ctx->objdata &= 0xffff;
5714                 goto end;
5715         }
5716         if (i >= ACTION_RSS_QUEUE_NUM)
5717                 return -1;
5718         arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) +
5719                              i * sizeof(action_rss_data->queue[i]),
5720                              sizeof(action_rss_data->queue[i]));
5721         if (push_args(ctx, arg))
5722                 return -1;
5723         ret = parse_int(ctx, token, str, len, NULL, 0);
5724         if (ret < 0) {
5725                 pop_args(ctx);
5726                 return -1;
5727         }
5728         ++i;
5729         ctx->objdata = i << 16 | (ctx->objdata & 0xffff);
5730         /* Repeat token. */
5731         if (ctx->next_num == RTE_DIM(ctx->next))
5732                 return -1;
5733         ctx->next[ctx->next_num++] = next;
5734 end:
5735         if (!ctx->object)
5736                 return len;
5737         action_rss_data = ctx->object;
5738         action_rss_data->conf.queue_num = i;
5739         action_rss_data->conf.queue = i ? action_rss_data->queue : NULL;
5740         return len;
5741 }
5742
5743 /** Setup VXLAN encap configuration. */
5744 static int
5745 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data)
5746 {
5747         /* Set up default configuration. */
5748         *action_vxlan_encap_data = (struct action_vxlan_encap_data){
5749                 .conf = (struct rte_flow_action_vxlan_encap){
5750                         .definition = action_vxlan_encap_data->items,
5751                 },
5752                 .items = {
5753                         {
5754                                 .type = RTE_FLOW_ITEM_TYPE_ETH,
5755                                 .spec = &action_vxlan_encap_data->item_eth,
5756                                 .mask = &rte_flow_item_eth_mask,
5757                         },
5758                         {
5759                                 .type = RTE_FLOW_ITEM_TYPE_VLAN,
5760                                 .spec = &action_vxlan_encap_data->item_vlan,
5761                                 .mask = &rte_flow_item_vlan_mask,
5762                         },
5763                         {
5764                                 .type = RTE_FLOW_ITEM_TYPE_IPV4,
5765                                 .spec = &action_vxlan_encap_data->item_ipv4,
5766                                 .mask = &rte_flow_item_ipv4_mask,
5767                         },
5768                         {
5769                                 .type = RTE_FLOW_ITEM_TYPE_UDP,
5770                                 .spec = &action_vxlan_encap_data->item_udp,
5771                                 .mask = &rte_flow_item_udp_mask,
5772                         },
5773                         {
5774                                 .type = RTE_FLOW_ITEM_TYPE_VXLAN,
5775                                 .spec = &action_vxlan_encap_data->item_vxlan,
5776                                 .mask = &rte_flow_item_vxlan_mask,
5777                         },
5778                         {
5779                                 .type = RTE_FLOW_ITEM_TYPE_END,
5780                         },
5781                 },
5782                 .item_eth.type = 0,
5783                 .item_vlan = {
5784                         .tci = vxlan_encap_conf.vlan_tci,
5785                         .inner_type = 0,
5786                 },
5787                 .item_ipv4.hdr = {
5788                         .src_addr = vxlan_encap_conf.ipv4_src,
5789                         .dst_addr = vxlan_encap_conf.ipv4_dst,
5790                 },
5791                 .item_udp.hdr = {
5792                         .src_port = vxlan_encap_conf.udp_src,
5793                         .dst_port = vxlan_encap_conf.udp_dst,
5794                 },
5795                 .item_vxlan.flags = 0,
5796         };
5797         memcpy(action_vxlan_encap_data->item_eth.dst.addr_bytes,
5798                vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
5799         memcpy(action_vxlan_encap_data->item_eth.src.addr_bytes,
5800                vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
5801         if (!vxlan_encap_conf.select_ipv4) {
5802                 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr,
5803                        &vxlan_encap_conf.ipv6_src,
5804                        sizeof(vxlan_encap_conf.ipv6_src));
5805                 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr,
5806                        &vxlan_encap_conf.ipv6_dst,
5807                        sizeof(vxlan_encap_conf.ipv6_dst));
5808                 action_vxlan_encap_data->items[2] = (struct rte_flow_item){
5809                         .type = RTE_FLOW_ITEM_TYPE_IPV6,
5810                         .spec = &action_vxlan_encap_data->item_ipv6,
5811                         .mask = &rte_flow_item_ipv6_mask,
5812                 };
5813         }
5814         if (!vxlan_encap_conf.select_vlan)
5815                 action_vxlan_encap_data->items[1].type =
5816                         RTE_FLOW_ITEM_TYPE_VOID;
5817         if (vxlan_encap_conf.select_tos_ttl) {
5818                 if (vxlan_encap_conf.select_ipv4) {
5819                         static struct rte_flow_item_ipv4 ipv4_mask_tos;
5820
5821                         memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask,
5822                                sizeof(ipv4_mask_tos));
5823                         ipv4_mask_tos.hdr.type_of_service = 0xff;
5824                         ipv4_mask_tos.hdr.time_to_live = 0xff;
5825                         action_vxlan_encap_data->item_ipv4.hdr.type_of_service =
5826                                         vxlan_encap_conf.ip_tos;
5827                         action_vxlan_encap_data->item_ipv4.hdr.time_to_live =
5828                                         vxlan_encap_conf.ip_ttl;
5829                         action_vxlan_encap_data->items[2].mask =
5830                                                         &ipv4_mask_tos;
5831                 } else {
5832                         static struct rte_flow_item_ipv6 ipv6_mask_tos;
5833
5834                         memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask,
5835                                sizeof(ipv6_mask_tos));
5836                         ipv6_mask_tos.hdr.vtc_flow |=
5837                                 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT);
5838                         ipv6_mask_tos.hdr.hop_limits = 0xff;
5839                         action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |=
5840                                 rte_cpu_to_be_32
5841                                         ((uint32_t)vxlan_encap_conf.ip_tos <<
5842                                          RTE_IPV6_HDR_TC_SHIFT);
5843                         action_vxlan_encap_data->item_ipv6.hdr.hop_limits =
5844                                         vxlan_encap_conf.ip_ttl;
5845                         action_vxlan_encap_data->items[2].mask =
5846                                                         &ipv6_mask_tos;
5847                 }
5848         }
5849         memcpy(action_vxlan_encap_data->item_vxlan.vni, vxlan_encap_conf.vni,
5850                RTE_DIM(vxlan_encap_conf.vni));
5851         return 0;
5852 }
5853
5854 /** Parse VXLAN encap action. */
5855 static int
5856 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token,
5857                             const char *str, unsigned int len,
5858                             void *buf, unsigned int size)
5859 {
5860         struct buffer *out = buf;
5861         struct rte_flow_action *action;
5862         struct action_vxlan_encap_data *action_vxlan_encap_data;
5863         int ret;
5864
5865         ret = parse_vc(ctx, token, str, len, buf, size);
5866         if (ret < 0)
5867                 return ret;
5868         /* Nothing else to do if there is no buffer. */
5869         if (!out)
5870                 return ret;
5871         if (!out->args.vc.actions_n)
5872                 return -1;
5873         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
5874         /* Point to selected object. */
5875         ctx->object = out->args.vc.data;
5876         ctx->objmask = NULL;
5877         action_vxlan_encap_data = ctx->object;
5878         parse_setup_vxlan_encap_data(action_vxlan_encap_data);
5879         action->conf = &action_vxlan_encap_data->conf;
5880         return ret;
5881 }
5882
5883 /** Setup NVGRE encap configuration. */
5884 static int
5885 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data)
5886 {
5887         /* Set up default configuration. */
5888         *action_nvgre_encap_data = (struct action_nvgre_encap_data){
5889                 .conf = (struct rte_flow_action_nvgre_encap){
5890                         .definition = action_nvgre_encap_data->items,
5891                 },
5892                 .items = {
5893                         {
5894                                 .type = RTE_FLOW_ITEM_TYPE_ETH,
5895                                 .spec = &action_nvgre_encap_data->item_eth,
5896                                 .mask = &rte_flow_item_eth_mask,
5897                         },
5898                         {
5899                                 .type = RTE_FLOW_ITEM_TYPE_VLAN,
5900                                 .spec = &action_nvgre_encap_data->item_vlan,
5901                                 .mask = &rte_flow_item_vlan_mask,
5902                         },
5903                         {
5904                                 .type = RTE_FLOW_ITEM_TYPE_IPV4,
5905                                 .spec = &action_nvgre_encap_data->item_ipv4,
5906                                 .mask = &rte_flow_item_ipv4_mask,
5907                         },
5908                         {
5909                                 .type = RTE_FLOW_ITEM_TYPE_NVGRE,
5910                                 .spec = &action_nvgre_encap_data->item_nvgre,
5911                                 .mask = &rte_flow_item_nvgre_mask,
5912                         },
5913                         {
5914                                 .type = RTE_FLOW_ITEM_TYPE_END,
5915                         },
5916                 },
5917                 .item_eth.type = 0,
5918                 .item_vlan = {
5919                         .tci = nvgre_encap_conf.vlan_tci,
5920                         .inner_type = 0,
5921                 },
5922                 .item_ipv4.hdr = {
5923                        .src_addr = nvgre_encap_conf.ipv4_src,
5924                        .dst_addr = nvgre_encap_conf.ipv4_dst,
5925                 },
5926                 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000),
5927                 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB),
5928                 .item_nvgre.flow_id = 0,
5929         };
5930         memcpy(action_nvgre_encap_data->item_eth.dst.addr_bytes,
5931                nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
5932         memcpy(action_nvgre_encap_data->item_eth.src.addr_bytes,
5933                nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
5934         if (!nvgre_encap_conf.select_ipv4) {
5935                 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr,
5936                        &nvgre_encap_conf.ipv6_src,
5937                        sizeof(nvgre_encap_conf.ipv6_src));
5938                 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr,
5939                        &nvgre_encap_conf.ipv6_dst,
5940                        sizeof(nvgre_encap_conf.ipv6_dst));
5941                 action_nvgre_encap_data->items[2] = (struct rte_flow_item){
5942                         .type = RTE_FLOW_ITEM_TYPE_IPV6,
5943                         .spec = &action_nvgre_encap_data->item_ipv6,
5944                         .mask = &rte_flow_item_ipv6_mask,
5945                 };
5946         }
5947         if (!nvgre_encap_conf.select_vlan)
5948                 action_nvgre_encap_data->items[1].type =
5949                         RTE_FLOW_ITEM_TYPE_VOID;
5950         memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni,
5951                RTE_DIM(nvgre_encap_conf.tni));
5952         return 0;
5953 }
5954
5955 /** Parse NVGRE encap action. */
5956 static int
5957 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token,
5958                             const char *str, unsigned int len,
5959                             void *buf, unsigned int size)
5960 {
5961         struct buffer *out = buf;
5962         struct rte_flow_action *action;
5963         struct action_nvgre_encap_data *action_nvgre_encap_data;
5964         int ret;
5965
5966         ret = parse_vc(ctx, token, str, len, buf, size);
5967         if (ret < 0)
5968                 return ret;
5969         /* Nothing else to do if there is no buffer. */
5970         if (!out)
5971                 return ret;
5972         if (!out->args.vc.actions_n)
5973                 return -1;
5974         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
5975         /* Point to selected object. */
5976         ctx->object = out->args.vc.data;
5977         ctx->objmask = NULL;
5978         action_nvgre_encap_data = ctx->object;
5979         parse_setup_nvgre_encap_data(action_nvgre_encap_data);
5980         action->conf = &action_nvgre_encap_data->conf;
5981         return ret;
5982 }
5983
5984 /** Parse l2 encap action. */
5985 static int
5986 parse_vc_action_l2_encap(struct context *ctx, const struct token *token,
5987                          const char *str, unsigned int len,
5988                          void *buf, unsigned int size)
5989 {
5990         struct buffer *out = buf;
5991         struct rte_flow_action *action;
5992         struct action_raw_encap_data *action_encap_data;
5993         struct rte_flow_item_eth eth = { .type = 0, };
5994         struct rte_flow_item_vlan vlan = {
5995                 .tci = mplsoudp_encap_conf.vlan_tci,
5996                 .inner_type = 0,
5997         };
5998         uint8_t *header;
5999         int ret;
6000
6001         ret = parse_vc(ctx, token, str, len, buf, size);
6002         if (ret < 0)
6003                 return ret;
6004         /* Nothing else to do if there is no buffer. */
6005         if (!out)
6006                 return ret;
6007         if (!out->args.vc.actions_n)
6008                 return -1;
6009         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6010         /* Point to selected object. */
6011         ctx->object = out->args.vc.data;
6012         ctx->objmask = NULL;
6013         /* Copy the headers to the buffer. */
6014         action_encap_data = ctx->object;
6015         *action_encap_data = (struct action_raw_encap_data) {
6016                 .conf = (struct rte_flow_action_raw_encap){
6017                         .data = action_encap_data->data,
6018                 },
6019                 .data = {},
6020         };
6021         header = action_encap_data->data;
6022         if (l2_encap_conf.select_vlan)
6023                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
6024         else if (l2_encap_conf.select_ipv4)
6025                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
6026         else
6027                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
6028         memcpy(eth.dst.addr_bytes,
6029                l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
6030         memcpy(eth.src.addr_bytes,
6031                l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
6032         memcpy(header, &eth, sizeof(eth));
6033         header += sizeof(eth);
6034         if (l2_encap_conf.select_vlan) {
6035                 if (l2_encap_conf.select_ipv4)
6036                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
6037                 else
6038                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
6039                 memcpy(header, &vlan, sizeof(vlan));
6040                 header += sizeof(vlan);
6041         }
6042         action_encap_data->conf.size = header -
6043                 action_encap_data->data;
6044         action->conf = &action_encap_data->conf;
6045         return ret;
6046 }
6047
6048 /** Parse l2 decap action. */
6049 static int
6050 parse_vc_action_l2_decap(struct context *ctx, const struct token *token,
6051                          const char *str, unsigned int len,
6052                          void *buf, unsigned int size)
6053 {
6054         struct buffer *out = buf;
6055         struct rte_flow_action *action;
6056         struct action_raw_decap_data *action_decap_data;
6057         struct rte_flow_item_eth eth = { .type = 0, };
6058         struct rte_flow_item_vlan vlan = {
6059                 .tci = mplsoudp_encap_conf.vlan_tci,
6060                 .inner_type = 0,
6061         };
6062         uint8_t *header;
6063         int ret;
6064
6065         ret = parse_vc(ctx, token, str, len, buf, size);
6066         if (ret < 0)
6067                 return ret;
6068         /* Nothing else to do if there is no buffer. */
6069         if (!out)
6070                 return ret;
6071         if (!out->args.vc.actions_n)
6072                 return -1;
6073         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6074         /* Point to selected object. */
6075         ctx->object = out->args.vc.data;
6076         ctx->objmask = NULL;
6077         /* Copy the headers to the buffer. */
6078         action_decap_data = ctx->object;
6079         *action_decap_data = (struct action_raw_decap_data) {
6080                 .conf = (struct rte_flow_action_raw_decap){
6081                         .data = action_decap_data->data,
6082                 },
6083                 .data = {},
6084         };
6085         header = action_decap_data->data;
6086         if (l2_decap_conf.select_vlan)
6087                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
6088         memcpy(header, &eth, sizeof(eth));
6089         header += sizeof(eth);
6090         if (l2_decap_conf.select_vlan) {
6091                 memcpy(header, &vlan, sizeof(vlan));
6092                 header += sizeof(vlan);
6093         }
6094         action_decap_data->conf.size = header -
6095                 action_decap_data->data;
6096         action->conf = &action_decap_data->conf;
6097         return ret;
6098 }
6099
6100 #define ETHER_TYPE_MPLS_UNICAST 0x8847
6101
6102 /** Parse MPLSOGRE encap action. */
6103 static int
6104 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token,
6105                                const char *str, unsigned int len,
6106                                void *buf, unsigned int size)
6107 {
6108         struct buffer *out = buf;
6109         struct rte_flow_action *action;
6110         struct action_raw_encap_data *action_encap_data;
6111         struct rte_flow_item_eth eth = { .type = 0, };
6112         struct rte_flow_item_vlan vlan = {
6113                 .tci = mplsogre_encap_conf.vlan_tci,
6114                 .inner_type = 0,
6115         };
6116         struct rte_flow_item_ipv4 ipv4 = {
6117                 .hdr =  {
6118                         .src_addr = mplsogre_encap_conf.ipv4_src,
6119                         .dst_addr = mplsogre_encap_conf.ipv4_dst,
6120                         .next_proto_id = IPPROTO_GRE,
6121                         .version_ihl = RTE_IPV4_VHL_DEF,
6122                         .time_to_live = IPDEFTTL,
6123                 },
6124         };
6125         struct rte_flow_item_ipv6 ipv6 = {
6126                 .hdr =  {
6127                         .proto = IPPROTO_GRE,
6128                         .hop_limits = IPDEFTTL,
6129                 },
6130         };
6131         struct rte_flow_item_gre gre = {
6132                 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST),
6133         };
6134         struct rte_flow_item_mpls mpls = {
6135                 .ttl = 0,
6136         };
6137         uint8_t *header;
6138         int ret;
6139
6140         ret = parse_vc(ctx, token, str, len, buf, size);
6141         if (ret < 0)
6142                 return ret;
6143         /* Nothing else to do if there is no buffer. */
6144         if (!out)
6145                 return ret;
6146         if (!out->args.vc.actions_n)
6147                 return -1;
6148         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6149         /* Point to selected object. */
6150         ctx->object = out->args.vc.data;
6151         ctx->objmask = NULL;
6152         /* Copy the headers to the buffer. */
6153         action_encap_data = ctx->object;
6154         *action_encap_data = (struct action_raw_encap_data) {
6155                 .conf = (struct rte_flow_action_raw_encap){
6156                         .data = action_encap_data->data,
6157                 },
6158                 .data = {},
6159                 .preserve = {},
6160         };
6161         header = action_encap_data->data;
6162         if (mplsogre_encap_conf.select_vlan)
6163                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
6164         else if (mplsogre_encap_conf.select_ipv4)
6165                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
6166         else
6167                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
6168         memcpy(eth.dst.addr_bytes,
6169                mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
6170         memcpy(eth.src.addr_bytes,
6171                mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
6172         memcpy(header, &eth, sizeof(eth));
6173         header += sizeof(eth);
6174         if (mplsogre_encap_conf.select_vlan) {
6175                 if (mplsogre_encap_conf.select_ipv4)
6176                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
6177                 else
6178                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
6179                 memcpy(header, &vlan, sizeof(vlan));
6180                 header += sizeof(vlan);
6181         }
6182         if (mplsogre_encap_conf.select_ipv4) {
6183                 memcpy(header, &ipv4, sizeof(ipv4));
6184                 header += sizeof(ipv4);
6185         } else {
6186                 memcpy(&ipv6.hdr.src_addr,
6187                        &mplsogre_encap_conf.ipv6_src,
6188                        sizeof(mplsogre_encap_conf.ipv6_src));
6189                 memcpy(&ipv6.hdr.dst_addr,
6190                        &mplsogre_encap_conf.ipv6_dst,
6191                        sizeof(mplsogre_encap_conf.ipv6_dst));
6192                 memcpy(header, &ipv6, sizeof(ipv6));
6193                 header += sizeof(ipv6);
6194         }
6195         memcpy(header, &gre, sizeof(gre));
6196         header += sizeof(gre);
6197         memcpy(mpls.label_tc_s, mplsogre_encap_conf.label,
6198                RTE_DIM(mplsogre_encap_conf.label));
6199         mpls.label_tc_s[2] |= 0x1;
6200         memcpy(header, &mpls, sizeof(mpls));
6201         header += sizeof(mpls);
6202         action_encap_data->conf.size = header -
6203                 action_encap_data->data;
6204         action->conf = &action_encap_data->conf;
6205         return ret;
6206 }
6207
6208 /** Parse MPLSOGRE decap action. */
6209 static int
6210 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token,
6211                                const char *str, unsigned int len,
6212                                void *buf, unsigned int size)
6213 {
6214         struct buffer *out = buf;
6215         struct rte_flow_action *action;
6216         struct action_raw_decap_data *action_decap_data;
6217         struct rte_flow_item_eth eth = { .type = 0, };
6218         struct rte_flow_item_vlan vlan = {.tci = 0};
6219         struct rte_flow_item_ipv4 ipv4 = {
6220                 .hdr =  {
6221                         .next_proto_id = IPPROTO_GRE,
6222                 },
6223         };
6224         struct rte_flow_item_ipv6 ipv6 = {
6225                 .hdr =  {
6226                         .proto = IPPROTO_GRE,
6227                 },
6228         };
6229         struct rte_flow_item_gre gre = {
6230                 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST),
6231         };
6232         struct rte_flow_item_mpls mpls;
6233         uint8_t *header;
6234         int ret;
6235
6236         ret = parse_vc(ctx, token, str, len, buf, size);
6237         if (ret < 0)
6238                 return ret;
6239         /* Nothing else to do if there is no buffer. */
6240         if (!out)
6241                 return ret;
6242         if (!out->args.vc.actions_n)
6243                 return -1;
6244         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6245         /* Point to selected object. */
6246         ctx->object = out->args.vc.data;
6247         ctx->objmask = NULL;
6248         /* Copy the headers to the buffer. */
6249         action_decap_data = ctx->object;
6250         *action_decap_data = (struct action_raw_decap_data) {
6251                 .conf = (struct rte_flow_action_raw_decap){
6252                         .data = action_decap_data->data,
6253                 },
6254                 .data = {},
6255         };
6256         header = action_decap_data->data;
6257         if (mplsogre_decap_conf.select_vlan)
6258                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
6259         else if (mplsogre_encap_conf.select_ipv4)
6260                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
6261         else
6262                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
6263         memcpy(eth.dst.addr_bytes,
6264                mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
6265         memcpy(eth.src.addr_bytes,
6266                mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
6267         memcpy(header, &eth, sizeof(eth));
6268         header += sizeof(eth);
6269         if (mplsogre_encap_conf.select_vlan) {
6270                 if (mplsogre_encap_conf.select_ipv4)
6271                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
6272                 else
6273                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
6274                 memcpy(header, &vlan, sizeof(vlan));
6275                 header += sizeof(vlan);
6276         }
6277         if (mplsogre_encap_conf.select_ipv4) {
6278                 memcpy(header, &ipv4, sizeof(ipv4));
6279                 header += sizeof(ipv4);
6280         } else {
6281                 memcpy(header, &ipv6, sizeof(ipv6));
6282                 header += sizeof(ipv6);
6283         }
6284         memcpy(header, &gre, sizeof(gre));
6285         header += sizeof(gre);
6286         memset(&mpls, 0, sizeof(mpls));
6287         memcpy(header, &mpls, sizeof(mpls));
6288         header += sizeof(mpls);
6289         action_decap_data->conf.size = header -
6290                 action_decap_data->data;
6291         action->conf = &action_decap_data->conf;
6292         return ret;
6293 }
6294
6295 /** Parse MPLSOUDP encap action. */
6296 static int
6297 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token,
6298                                const char *str, unsigned int len,
6299                                void *buf, unsigned int size)
6300 {
6301         struct buffer *out = buf;
6302         struct rte_flow_action *action;
6303         struct action_raw_encap_data *action_encap_data;
6304         struct rte_flow_item_eth eth = { .type = 0, };
6305         struct rte_flow_item_vlan vlan = {
6306                 .tci = mplsoudp_encap_conf.vlan_tci,
6307                 .inner_type = 0,
6308         };
6309         struct rte_flow_item_ipv4 ipv4 = {
6310                 .hdr =  {
6311                         .src_addr = mplsoudp_encap_conf.ipv4_src,
6312                         .dst_addr = mplsoudp_encap_conf.ipv4_dst,
6313                         .next_proto_id = IPPROTO_UDP,
6314                         .version_ihl = RTE_IPV4_VHL_DEF,
6315                         .time_to_live = IPDEFTTL,
6316                 },
6317         };
6318         struct rte_flow_item_ipv6 ipv6 = {
6319                 .hdr =  {
6320                         .proto = IPPROTO_UDP,
6321                         .hop_limits = IPDEFTTL,
6322                 },
6323         };
6324         struct rte_flow_item_udp udp = {
6325                 .hdr = {
6326                         .src_port = mplsoudp_encap_conf.udp_src,
6327                         .dst_port = mplsoudp_encap_conf.udp_dst,
6328                 },
6329         };
6330         struct rte_flow_item_mpls mpls;
6331         uint8_t *header;
6332         int ret;
6333
6334         ret = parse_vc(ctx, token, str, len, buf, size);
6335         if (ret < 0)
6336                 return ret;
6337         /* Nothing else to do if there is no buffer. */
6338         if (!out)
6339                 return ret;
6340         if (!out->args.vc.actions_n)
6341                 return -1;
6342         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6343         /* Point to selected object. */
6344         ctx->object = out->args.vc.data;
6345         ctx->objmask = NULL;
6346         /* Copy the headers to the buffer. */
6347         action_encap_data = ctx->object;
6348         *action_encap_data = (struct action_raw_encap_data) {
6349                 .conf = (struct rte_flow_action_raw_encap){
6350                         .data = action_encap_data->data,
6351                 },
6352                 .data = {},
6353                 .preserve = {},
6354         };
6355         header = action_encap_data->data;
6356         if (mplsoudp_encap_conf.select_vlan)
6357                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
6358         else if (mplsoudp_encap_conf.select_ipv4)
6359                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
6360         else
6361                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
6362         memcpy(eth.dst.addr_bytes,
6363                mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
6364         memcpy(eth.src.addr_bytes,
6365                mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
6366         memcpy(header, &eth, sizeof(eth));
6367         header += sizeof(eth);
6368         if (mplsoudp_encap_conf.select_vlan) {
6369                 if (mplsoudp_encap_conf.select_ipv4)
6370                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
6371                 else
6372                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
6373                 memcpy(header, &vlan, sizeof(vlan));
6374                 header += sizeof(vlan);
6375         }
6376         if (mplsoudp_encap_conf.select_ipv4) {
6377                 memcpy(header, &ipv4, sizeof(ipv4));
6378                 header += sizeof(ipv4);
6379         } else {
6380                 memcpy(&ipv6.hdr.src_addr,
6381                        &mplsoudp_encap_conf.ipv6_src,
6382                        sizeof(mplsoudp_encap_conf.ipv6_src));
6383                 memcpy(&ipv6.hdr.dst_addr,
6384                        &mplsoudp_encap_conf.ipv6_dst,
6385                        sizeof(mplsoudp_encap_conf.ipv6_dst));
6386                 memcpy(header, &ipv6, sizeof(ipv6));
6387                 header += sizeof(ipv6);
6388         }
6389         memcpy(header, &udp, sizeof(udp));
6390         header += sizeof(udp);
6391         memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label,
6392                RTE_DIM(mplsoudp_encap_conf.label));
6393         mpls.label_tc_s[2] |= 0x1;
6394         memcpy(header, &mpls, sizeof(mpls));
6395         header += sizeof(mpls);
6396         action_encap_data->conf.size = header -
6397                 action_encap_data->data;
6398         action->conf = &action_encap_data->conf;
6399         return ret;
6400 }
6401
6402 /** Parse MPLSOUDP decap action. */
6403 static int
6404 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token,
6405                                const char *str, unsigned int len,
6406                                void *buf, unsigned int size)
6407 {
6408         struct buffer *out = buf;
6409         struct rte_flow_action *action;
6410         struct action_raw_decap_data *action_decap_data;
6411         struct rte_flow_item_eth eth = { .type = 0, };
6412         struct rte_flow_item_vlan vlan = {.tci = 0};
6413         struct rte_flow_item_ipv4 ipv4 = {
6414                 .hdr =  {
6415                         .next_proto_id = IPPROTO_UDP,
6416                 },
6417         };
6418         struct rte_flow_item_ipv6 ipv6 = {
6419                 .hdr =  {
6420                         .proto = IPPROTO_UDP,
6421                 },
6422         };
6423         struct rte_flow_item_udp udp = {
6424                 .hdr = {
6425                         .dst_port = rte_cpu_to_be_16(6635),
6426                 },
6427         };
6428         struct rte_flow_item_mpls mpls;
6429         uint8_t *header;
6430         int ret;
6431
6432         ret = parse_vc(ctx, token, str, len, buf, size);
6433         if (ret < 0)
6434                 return ret;
6435         /* Nothing else to do if there is no buffer. */
6436         if (!out)
6437                 return ret;
6438         if (!out->args.vc.actions_n)
6439                 return -1;
6440         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6441         /* Point to selected object. */
6442         ctx->object = out->args.vc.data;
6443         ctx->objmask = NULL;
6444         /* Copy the headers to the buffer. */
6445         action_decap_data = ctx->object;
6446         *action_decap_data = (struct action_raw_decap_data) {
6447                 .conf = (struct rte_flow_action_raw_decap){
6448                         .data = action_decap_data->data,
6449                 },
6450                 .data = {},
6451         };
6452         header = action_decap_data->data;
6453         if (mplsoudp_decap_conf.select_vlan)
6454                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
6455         else if (mplsoudp_encap_conf.select_ipv4)
6456                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
6457         else
6458                 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
6459         memcpy(eth.dst.addr_bytes,
6460                mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
6461         memcpy(eth.src.addr_bytes,
6462                mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
6463         memcpy(header, &eth, sizeof(eth));
6464         header += sizeof(eth);
6465         if (mplsoudp_encap_conf.select_vlan) {
6466                 if (mplsoudp_encap_conf.select_ipv4)
6467                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
6468                 else
6469                         vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
6470                 memcpy(header, &vlan, sizeof(vlan));
6471                 header += sizeof(vlan);
6472         }
6473         if (mplsoudp_encap_conf.select_ipv4) {
6474                 memcpy(header, &ipv4, sizeof(ipv4));
6475                 header += sizeof(ipv4);
6476         } else {
6477                 memcpy(header, &ipv6, sizeof(ipv6));
6478                 header += sizeof(ipv6);
6479         }
6480         memcpy(header, &udp, sizeof(udp));
6481         header += sizeof(udp);
6482         memset(&mpls, 0, sizeof(mpls));
6483         memcpy(header, &mpls, sizeof(mpls));
6484         header += sizeof(mpls);
6485         action_decap_data->conf.size = header -
6486                 action_decap_data->data;
6487         action->conf = &action_decap_data->conf;
6488         return ret;
6489 }
6490
6491 static int
6492 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token,
6493                                 const char *str, unsigned int len, void *buf,
6494                                 unsigned int size)
6495 {
6496         struct action_raw_decap_data *action_raw_decap_data;
6497         struct rte_flow_action *action;
6498         const struct arg *arg;
6499         struct buffer *out = buf;
6500         int ret;
6501         uint16_t idx;
6502
6503         RTE_SET_USED(token);
6504         RTE_SET_USED(buf);
6505         RTE_SET_USED(size);
6506         arg = ARGS_ENTRY_ARB_BOUNDED
6507                 (offsetof(struct action_raw_decap_data, idx),
6508                  sizeof(((struct action_raw_decap_data *)0)->idx),
6509                  0, RAW_ENCAP_CONFS_MAX_NUM - 1);
6510         if (push_args(ctx, arg))
6511                 return -1;
6512         ret = parse_int(ctx, token, str, len, NULL, 0);
6513         if (ret < 0) {
6514                 pop_args(ctx);
6515                 return -1;
6516         }
6517         if (!ctx->object)
6518                 return len;
6519         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6520         action_raw_decap_data = ctx->object;
6521         idx = action_raw_decap_data->idx;
6522         action_raw_decap_data->conf.data = raw_decap_confs[idx].data;
6523         action_raw_decap_data->conf.size = raw_decap_confs[idx].size;
6524         action->conf = &action_raw_decap_data->conf;
6525         return len;
6526 }
6527
6528
6529 static int
6530 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token,
6531                                 const char *str, unsigned int len, void *buf,
6532                                 unsigned int size)
6533 {
6534         struct action_raw_encap_data *action_raw_encap_data;
6535         struct rte_flow_action *action;
6536         const struct arg *arg;
6537         struct buffer *out = buf;
6538         int ret;
6539         uint16_t idx;
6540
6541         RTE_SET_USED(token);
6542         RTE_SET_USED(buf);
6543         RTE_SET_USED(size);
6544         if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE)
6545                 return -1;
6546         arg = ARGS_ENTRY_ARB_BOUNDED
6547                 (offsetof(struct action_raw_encap_data, idx),
6548                  sizeof(((struct action_raw_encap_data *)0)->idx),
6549                  0, RAW_ENCAP_CONFS_MAX_NUM - 1);
6550         if (push_args(ctx, arg))
6551                 return -1;
6552         ret = parse_int(ctx, token, str, len, NULL, 0);
6553         if (ret < 0) {
6554                 pop_args(ctx);
6555                 return -1;
6556         }
6557         if (!ctx->object)
6558                 return len;
6559         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6560         action_raw_encap_data = ctx->object;
6561         idx = action_raw_encap_data->idx;
6562         action_raw_encap_data->conf.data = raw_encap_confs[idx].data;
6563         action_raw_encap_data->conf.size = raw_encap_confs[idx].size;
6564         action_raw_encap_data->conf.preserve = NULL;
6565         action->conf = &action_raw_encap_data->conf;
6566         return len;
6567 }
6568
6569 static int
6570 parse_vc_action_raw_encap(struct context *ctx, const struct token *token,
6571                           const char *str, unsigned int len, void *buf,
6572                           unsigned int size)
6573 {
6574         struct buffer *out = buf;
6575         struct rte_flow_action *action;
6576         struct action_raw_encap_data *action_raw_encap_data = NULL;
6577         int ret;
6578
6579         ret = parse_vc(ctx, token, str, len, buf, size);
6580         if (ret < 0)
6581                 return ret;
6582         /* Nothing else to do if there is no buffer. */
6583         if (!out)
6584                 return ret;
6585         if (!out->args.vc.actions_n)
6586                 return -1;
6587         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6588         /* Point to selected object. */
6589         ctx->object = out->args.vc.data;
6590         ctx->objmask = NULL;
6591         /* Copy the headers to the buffer. */
6592         action_raw_encap_data = ctx->object;
6593         action_raw_encap_data->conf.data = raw_encap_confs[0].data;
6594         action_raw_encap_data->conf.preserve = NULL;
6595         action_raw_encap_data->conf.size = raw_encap_confs[0].size;
6596         action->conf = &action_raw_encap_data->conf;
6597         return ret;
6598 }
6599
6600 static int
6601 parse_vc_action_raw_decap(struct context *ctx, const struct token *token,
6602                           const char *str, unsigned int len, void *buf,
6603                           unsigned int size)
6604 {
6605         struct buffer *out = buf;
6606         struct rte_flow_action *action;
6607         struct action_raw_decap_data *action_raw_decap_data = NULL;
6608         int ret;
6609
6610         ret = parse_vc(ctx, token, str, len, buf, size);
6611         if (ret < 0)
6612                 return ret;
6613         /* Nothing else to do if there is no buffer. */
6614         if (!out)
6615                 return ret;
6616         if (!out->args.vc.actions_n)
6617                 return -1;
6618         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6619         /* Point to selected object. */
6620         ctx->object = out->args.vc.data;
6621         ctx->objmask = NULL;
6622         /* Copy the headers to the buffer. */
6623         action_raw_decap_data = ctx->object;
6624         action_raw_decap_data->conf.data = raw_decap_confs[0].data;
6625         action_raw_decap_data->conf.size = raw_decap_confs[0].size;
6626         action->conf = &action_raw_decap_data->conf;
6627         return ret;
6628 }
6629
6630 static int
6631 parse_vc_action_set_meta(struct context *ctx, const struct token *token,
6632                          const char *str, unsigned int len, void *buf,
6633                          unsigned int size)
6634 {
6635         int ret;
6636
6637         ret = parse_vc(ctx, token, str, len, buf, size);
6638         if (ret < 0)
6639                 return ret;
6640         ret = rte_flow_dynf_metadata_register();
6641         if (ret < 0)
6642                 return -1;
6643         return len;
6644 }
6645
6646 static int
6647 parse_vc_action_sample(struct context *ctx, const struct token *token,
6648                          const char *str, unsigned int len, void *buf,
6649                          unsigned int size)
6650 {
6651         struct buffer *out = buf;
6652         struct rte_flow_action *action;
6653         struct action_sample_data *action_sample_data = NULL;
6654         static struct rte_flow_action end_action = {
6655                 RTE_FLOW_ACTION_TYPE_END, 0
6656         };
6657         int ret;
6658
6659         ret = parse_vc(ctx, token, str, len, buf, size);
6660         if (ret < 0)
6661                 return ret;
6662         /* Nothing else to do if there is no buffer. */
6663         if (!out)
6664                 return ret;
6665         if (!out->args.vc.actions_n)
6666                 return -1;
6667         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6668         /* Point to selected object. */
6669         ctx->object = out->args.vc.data;
6670         ctx->objmask = NULL;
6671         /* Copy the headers to the buffer. */
6672         action_sample_data = ctx->object;
6673         action_sample_data->conf.actions = &end_action;
6674         action->conf = &action_sample_data->conf;
6675         return ret;
6676 }
6677
6678 static int
6679 parse_vc_action_sample_index(struct context *ctx, const struct token *token,
6680                                 const char *str, unsigned int len, void *buf,
6681                                 unsigned int size)
6682 {
6683         struct action_sample_data *action_sample_data;
6684         struct rte_flow_action *action;
6685         const struct arg *arg;
6686         struct buffer *out = buf;
6687         int ret;
6688         uint16_t idx;
6689
6690         RTE_SET_USED(token);
6691         RTE_SET_USED(buf);
6692         RTE_SET_USED(size);
6693         if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE)
6694                 return -1;
6695         arg = ARGS_ENTRY_ARB_BOUNDED
6696                 (offsetof(struct action_sample_data, idx),
6697                  sizeof(((struct action_sample_data *)0)->idx),
6698                  0, RAW_SAMPLE_CONFS_MAX_NUM - 1);
6699         if (push_args(ctx, arg))
6700                 return -1;
6701         ret = parse_int(ctx, token, str, len, NULL, 0);
6702         if (ret < 0) {
6703                 pop_args(ctx);
6704                 return -1;
6705         }
6706         if (!ctx->object)
6707                 return len;
6708         action = &out->args.vc.actions[out->args.vc.actions_n - 1];
6709         action_sample_data = ctx->object;
6710         idx = action_sample_data->idx;
6711         action_sample_data->conf.actions = raw_sample_confs[idx].data;
6712         action->conf = &action_sample_data->conf;
6713         return len;
6714 }
6715
6716 /** Parse operation for modify_field command. */
6717 static int
6718 parse_vc_modify_field_op(struct context *ctx, const struct token *token,
6719                          const char *str, unsigned int len, void *buf,
6720                          unsigned int size)
6721 {
6722         struct rte_flow_action_modify_field *action_modify_field;
6723         unsigned int i;
6724
6725         (void)token;
6726         (void)buf;
6727         (void)size;
6728         if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE)
6729                 return -1;
6730         for (i = 0; modify_field_ops[i]; ++i)
6731                 if (!strcmp_partial(modify_field_ops[i], str, len))
6732                         break;
6733         if (!modify_field_ops[i])
6734                 return -1;
6735         if (!ctx->object)
6736                 return len;
6737         action_modify_field = ctx->object;
6738         action_modify_field->operation = (enum rte_flow_modify_op)i;
6739         return len;
6740 }
6741
6742 /** Parse id for modify_field command. */
6743 static int
6744 parse_vc_modify_field_id(struct context *ctx, const struct token *token,
6745                          const char *str, unsigned int len, void *buf,
6746                          unsigned int size)
6747 {
6748         struct rte_flow_action_modify_field *action_modify_field;
6749         unsigned int i;
6750
6751         (void)token;
6752         (void)buf;
6753         (void)size;
6754         if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE &&
6755                 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)
6756                 return -1;
6757         for (i = 0; modify_field_ids[i]; ++i)
6758                 if (!strcmp_partial(modify_field_ids[i], str, len))
6759                         break;
6760         if (!modify_field_ids[i])
6761                 return -1;
6762         if (!ctx->object)
6763                 return len;
6764         action_modify_field = ctx->object;
6765         if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE)
6766                 action_modify_field->dst.field = (enum rte_flow_field_id)i;
6767         else
6768                 action_modify_field->src.field = (enum rte_flow_field_id)i;
6769         return len;
6770 }
6771
6772 /** Parse the conntrack update, not a rte_flow_action. */
6773 static int
6774 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token,
6775                          const char *str, unsigned int len, void *buf,
6776                          unsigned int size)
6777 {
6778         struct buffer *out = buf;
6779         struct rte_flow_modify_conntrack *ct_modify = NULL;
6780
6781         (void)size;
6782         if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX &&
6783             ctx->curr != ACTION_CONNTRACK_UPDATE_DIR)
6784                 return -1;
6785         /* Token name must match. */
6786         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6787                 return -1;
6788         /* Nothing else to do if there is no buffer. */
6789         if (!out)
6790                 return len;
6791         ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data;
6792         if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) {
6793                 ct_modify->new_ct.is_original_dir =
6794                                 conntrack_context.is_original_dir;
6795                 ct_modify->direction = 1;
6796         } else {
6797                 uint32_t old_dir;
6798
6799                 old_dir = ct_modify->new_ct.is_original_dir;
6800                 memcpy(&ct_modify->new_ct, &conntrack_context,
6801                        sizeof(conntrack_context));
6802                 ct_modify->new_ct.is_original_dir = old_dir;
6803                 ct_modify->state = 1;
6804         }
6805         return len;
6806 }
6807
6808 /** Parse tokens for destroy command. */
6809 static int
6810 parse_destroy(struct context *ctx, const struct token *token,
6811               const char *str, unsigned int len,
6812               void *buf, unsigned int size)
6813 {
6814         struct buffer *out = buf;
6815
6816         /* Token name must match. */
6817         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6818                 return -1;
6819         /* Nothing else to do if there is no buffer. */
6820         if (!out)
6821                 return len;
6822         if (!out->command) {
6823                 if (ctx->curr != DESTROY)
6824                         return -1;
6825                 if (sizeof(*out) > size)
6826                         return -1;
6827                 out->command = ctx->curr;
6828                 ctx->objdata = 0;
6829                 ctx->object = out;
6830                 ctx->objmask = NULL;
6831                 out->args.destroy.rule =
6832                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
6833                                                sizeof(double));
6834                 return len;
6835         }
6836         if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) +
6837              sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size)
6838                 return -1;
6839         ctx->objdata = 0;
6840         ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++;
6841         ctx->objmask = NULL;
6842         return len;
6843 }
6844
6845 /** Parse tokens for flush command. */
6846 static int
6847 parse_flush(struct context *ctx, const struct token *token,
6848             const char *str, unsigned int len,
6849             void *buf, unsigned int size)
6850 {
6851         struct buffer *out = buf;
6852
6853         /* Token name must match. */
6854         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6855                 return -1;
6856         /* Nothing else to do if there is no buffer. */
6857         if (!out)
6858                 return len;
6859         if (!out->command) {
6860                 if (ctx->curr != FLUSH)
6861                         return -1;
6862                 if (sizeof(*out) > size)
6863                         return -1;
6864                 out->command = ctx->curr;
6865                 ctx->objdata = 0;
6866                 ctx->object = out;
6867                 ctx->objmask = NULL;
6868         }
6869         return len;
6870 }
6871
6872 /** Parse tokens for dump command. */
6873 static int
6874 parse_dump(struct context *ctx, const struct token *token,
6875             const char *str, unsigned int len,
6876             void *buf, unsigned int size)
6877 {
6878         struct buffer *out = buf;
6879
6880         /* Token name must match. */
6881         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6882                 return -1;
6883         /* Nothing else to do if there is no buffer. */
6884         if (!out)
6885                 return len;
6886         if (!out->command) {
6887                 if (ctx->curr != DUMP)
6888                         return -1;
6889                 if (sizeof(*out) > size)
6890                         return -1;
6891                 out->command = ctx->curr;
6892                 ctx->objdata = 0;
6893                 ctx->object = out;
6894                 ctx->objmask = NULL;
6895                 return len;
6896         }
6897         switch (ctx->curr) {
6898         case DUMP_ALL:
6899         case DUMP_ONE:
6900                 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false;
6901                 out->command = ctx->curr;
6902                 ctx->objdata = 0;
6903                 ctx->object = out;
6904                 ctx->objmask = NULL;
6905                 return len;
6906         default:
6907                 return -1;
6908         }
6909 }
6910
6911 /** Parse tokens for query command. */
6912 static int
6913 parse_query(struct context *ctx, const struct token *token,
6914             const char *str, unsigned int len,
6915             void *buf, unsigned int size)
6916 {
6917         struct buffer *out = buf;
6918
6919         /* Token name must match. */
6920         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6921                 return -1;
6922         /* Nothing else to do if there is no buffer. */
6923         if (!out)
6924                 return len;
6925         if (!out->command) {
6926                 if (ctx->curr != QUERY)
6927                         return -1;
6928                 if (sizeof(*out) > size)
6929                         return -1;
6930                 out->command = ctx->curr;
6931                 ctx->objdata = 0;
6932                 ctx->object = out;
6933                 ctx->objmask = NULL;
6934         }
6935         return len;
6936 }
6937
6938 /** Parse action names. */
6939 static int
6940 parse_action(struct context *ctx, const struct token *token,
6941              const char *str, unsigned int len,
6942              void *buf, unsigned int size)
6943 {
6944         struct buffer *out = buf;
6945         const struct arg *arg = pop_args(ctx);
6946         unsigned int i;
6947
6948         (void)size;
6949         /* Argument is expected. */
6950         if (!arg)
6951                 return -1;
6952         /* Parse action name. */
6953         for (i = 0; next_action[i]; ++i) {
6954                 const struct parse_action_priv *priv;
6955
6956                 token = &token_list[next_action[i]];
6957                 if (strcmp_partial(token->name, str, len))
6958                         continue;
6959                 priv = token->priv;
6960                 if (!priv)
6961                         goto error;
6962                 if (out)
6963                         memcpy((uint8_t *)ctx->object + arg->offset,
6964                                &priv->type,
6965                                arg->size);
6966                 return len;
6967         }
6968 error:
6969         push_args(ctx, arg);
6970         return -1;
6971 }
6972
6973 /** Parse tokens for list command. */
6974 static int
6975 parse_list(struct context *ctx, const struct token *token,
6976            const char *str, unsigned int len,
6977            void *buf, unsigned int size)
6978 {
6979         struct buffer *out = buf;
6980
6981         /* Token name must match. */
6982         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
6983                 return -1;
6984         /* Nothing else to do if there is no buffer. */
6985         if (!out)
6986                 return len;
6987         if (!out->command) {
6988                 if (ctx->curr != LIST)
6989                         return -1;
6990                 if (sizeof(*out) > size)
6991                         return -1;
6992                 out->command = ctx->curr;
6993                 ctx->objdata = 0;
6994                 ctx->object = out;
6995                 ctx->objmask = NULL;
6996                 out->args.list.group =
6997                         (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
6998                                                sizeof(double));
6999                 return len;
7000         }
7001         if (((uint8_t *)(out->args.list.group + out->args.list.group_n) +
7002              sizeof(*out->args.list.group)) > (uint8_t *)out + size)
7003                 return -1;
7004         ctx->objdata = 0;
7005         ctx->object = out->args.list.group + out->args.list.group_n++;
7006         ctx->objmask = NULL;
7007         return len;
7008 }
7009
7010 /** Parse tokens for list all aged flows command. */
7011 static int
7012 parse_aged(struct context *ctx, const struct token *token,
7013            const char *str, unsigned int len,
7014            void *buf, unsigned int size)
7015 {
7016         struct buffer *out = buf;
7017
7018         /* Token name must match. */
7019         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7020                 return -1;
7021         /* Nothing else to do if there is no buffer. */
7022         if (!out)
7023                 return len;
7024         if (!out->command) {
7025                 if (ctx->curr != AGED)
7026                         return -1;
7027                 if (sizeof(*out) > size)
7028                         return -1;
7029                 out->command = ctx->curr;
7030                 ctx->objdata = 0;
7031                 ctx->object = out;
7032                 ctx->objmask = NULL;
7033         }
7034         if (ctx->curr == AGED_DESTROY)
7035                 out->args.aged.destroy = 1;
7036         return len;
7037 }
7038
7039 /** Parse tokens for isolate command. */
7040 static int
7041 parse_isolate(struct context *ctx, const struct token *token,
7042               const char *str, unsigned int len,
7043               void *buf, unsigned int size)
7044 {
7045         struct buffer *out = buf;
7046
7047         /* Token name must match. */
7048         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7049                 return -1;
7050         /* Nothing else to do if there is no buffer. */
7051         if (!out)
7052                 return len;
7053         if (!out->command) {
7054                 if (ctx->curr != ISOLATE)
7055                         return -1;
7056                 if (sizeof(*out) > size)
7057                         return -1;
7058                 out->command = ctx->curr;
7059                 ctx->objdata = 0;
7060                 ctx->object = out;
7061                 ctx->objmask = NULL;
7062         }
7063         return len;
7064 }
7065
7066 static int
7067 parse_tunnel(struct context *ctx, const struct token *token,
7068              const char *str, unsigned int len,
7069              void *buf, unsigned int size)
7070 {
7071         struct buffer *out = buf;
7072
7073         /* Token name must match. */
7074         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7075                 return -1;
7076         /* Nothing else to do if there is no buffer. */
7077         if (!out)
7078                 return len;
7079         if (!out->command) {
7080                 if (ctx->curr != TUNNEL)
7081                         return -1;
7082                 if (sizeof(*out) > size)
7083                         return -1;
7084                 out->command = ctx->curr;
7085                 ctx->objdata = 0;
7086                 ctx->object = out;
7087                 ctx->objmask = NULL;
7088         } else {
7089                 switch (ctx->curr) {
7090                 default:
7091                         break;
7092                 case TUNNEL_CREATE:
7093                 case TUNNEL_DESTROY:
7094                 case TUNNEL_LIST:
7095                         out->command = ctx->curr;
7096                         break;
7097                 case TUNNEL_CREATE_TYPE:
7098                 case TUNNEL_DESTROY_ID:
7099                         ctx->object = &out->args.vc.tunnel_ops;
7100                         break;
7101                 }
7102         }
7103
7104         return len;
7105 }
7106
7107 /**
7108  * Parse signed/unsigned integers 8 to 64-bit long.
7109  *
7110  * Last argument (ctx->args) is retrieved to determine integer type and
7111  * storage location.
7112  */
7113 static int
7114 parse_int(struct context *ctx, const struct token *token,
7115           const char *str, unsigned int len,
7116           void *buf, unsigned int size)
7117 {
7118         const struct arg *arg = pop_args(ctx);
7119         uintmax_t u;
7120         char *end;
7121
7122         (void)token;
7123         /* Argument is expected. */
7124         if (!arg)
7125                 return -1;
7126         errno = 0;
7127         u = arg->sign ?
7128                 (uintmax_t)strtoimax(str, &end, 0) :
7129                 strtoumax(str, &end, 0);
7130         if (errno || (size_t)(end - str) != len)
7131                 goto error;
7132         if (arg->bounded &&
7133             ((arg->sign && ((intmax_t)u < (intmax_t)arg->min ||
7134                             (intmax_t)u > (intmax_t)arg->max)) ||
7135              (!arg->sign && (u < arg->min || u > arg->max))))
7136                 goto error;
7137         if (!ctx->object)
7138                 return len;
7139         if (arg->mask) {
7140                 if (!arg_entry_bf_fill(ctx->object, u, arg) ||
7141                     !arg_entry_bf_fill(ctx->objmask, -1, arg))
7142                         goto error;
7143                 return len;
7144         }
7145         buf = (uint8_t *)ctx->object + arg->offset;
7146         size = arg->size;
7147         if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t))
7148                 return -1;
7149 objmask:
7150         switch (size) {
7151         case sizeof(uint8_t):
7152                 *(uint8_t *)buf = u;
7153                 break;
7154         case sizeof(uint16_t):
7155                 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u;
7156                 break;
7157         case sizeof(uint8_t [3]):
7158 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
7159                 if (!arg->hton) {
7160                         ((uint8_t *)buf)[0] = u;
7161                         ((uint8_t *)buf)[1] = u >> 8;
7162                         ((uint8_t *)buf)[2] = u >> 16;
7163                         break;
7164                 }
7165 #endif
7166                 ((uint8_t *)buf)[0] = u >> 16;
7167                 ((uint8_t *)buf)[1] = u >> 8;
7168                 ((uint8_t *)buf)[2] = u;
7169                 break;
7170         case sizeof(uint32_t):
7171                 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u;
7172                 break;
7173         case sizeof(uint64_t):
7174                 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u;
7175                 break;
7176         default:
7177                 goto error;
7178         }
7179         if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) {
7180                 u = -1;
7181                 buf = (uint8_t *)ctx->objmask + arg->offset;
7182                 goto objmask;
7183         }
7184         return len;
7185 error:
7186         push_args(ctx, arg);
7187         return -1;
7188 }
7189
7190 /**
7191  * Parse a string.
7192  *
7193  * Three arguments (ctx->args) are retrieved from the stack to store data,
7194  * its actual length and address (in that order).
7195  */
7196 static int
7197 parse_string(struct context *ctx, const struct token *token,
7198              const char *str, unsigned int len,
7199              void *buf, unsigned int size)
7200 {
7201         const struct arg *arg_data = pop_args(ctx);
7202         const struct arg *arg_len = pop_args(ctx);
7203         const struct arg *arg_addr = pop_args(ctx);
7204         char tmp[16]; /* Ought to be enough. */
7205         int ret;
7206
7207         /* Arguments are expected. */
7208         if (!arg_data)
7209                 return -1;
7210         if (!arg_len) {
7211                 push_args(ctx, arg_data);
7212                 return -1;
7213         }
7214         if (!arg_addr) {
7215                 push_args(ctx, arg_len);
7216                 push_args(ctx, arg_data);
7217                 return -1;
7218         }
7219         size = arg_data->size;
7220         /* Bit-mask fill is not supported. */
7221         if (arg_data->mask || size < len)
7222                 goto error;
7223         if (!ctx->object)
7224                 return len;
7225         /* Let parse_int() fill length information first. */
7226         ret = snprintf(tmp, sizeof(tmp), "%u", len);
7227         if (ret < 0)
7228                 goto error;
7229         push_args(ctx, arg_len);
7230         ret = parse_int(ctx, token, tmp, ret, NULL, 0);
7231         if (ret < 0) {
7232                 pop_args(ctx);
7233                 goto error;
7234         }
7235         buf = (uint8_t *)ctx->object + arg_data->offset;
7236         /* Output buffer is not necessarily NUL-terminated. */
7237         memcpy(buf, str, len);
7238         memset((uint8_t *)buf + len, 0x00, size - len);
7239         if (ctx->objmask)
7240                 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len);
7241         /* Save address if requested. */
7242         if (arg_addr->size) {
7243                 memcpy((uint8_t *)ctx->object + arg_addr->offset,
7244                        (void *[]){
7245                         (uint8_t *)ctx->object + arg_data->offset
7246                        },
7247                        arg_addr->size);
7248                 if (ctx->objmask)
7249                         memcpy((uint8_t *)ctx->objmask + arg_addr->offset,
7250                                (void *[]){
7251                                 (uint8_t *)ctx->objmask + arg_data->offset
7252                                },
7253                                arg_addr->size);
7254         }
7255         return len;
7256 error:
7257         push_args(ctx, arg_addr);
7258         push_args(ctx, arg_len);
7259         push_args(ctx, arg_data);
7260         return -1;
7261 }
7262
7263 static int
7264 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size)
7265 {
7266         char *c = NULL;
7267         uint32_t i, len;
7268         char tmp[3];
7269
7270         /* Check input parameters */
7271         if ((src == NULL) ||
7272                 (dst == NULL) ||
7273                 (size == NULL) ||
7274                 (*size == 0))
7275                 return -1;
7276
7277         /* Convert chars to bytes */
7278         for (i = 0, len = 0; i < *size; i += 2) {
7279                 snprintf(tmp, 3, "%s", src + i);
7280                 dst[len++] = strtoul(tmp, &c, 16);
7281                 if (*c != 0) {
7282                         len--;
7283                         dst[len] = 0;
7284                         *size = len;
7285                         return -1;
7286                 }
7287         }
7288         dst[len] = 0;
7289         *size = len;
7290
7291         return 0;
7292 }
7293
7294 static int
7295 parse_hex(struct context *ctx, const struct token *token,
7296                 const char *str, unsigned int len,
7297                 void *buf, unsigned int size)
7298 {
7299         const struct arg *arg_data = pop_args(ctx);
7300         const struct arg *arg_len = pop_args(ctx);
7301         const struct arg *arg_addr = pop_args(ctx);
7302         char tmp[16]; /* Ought to be enough. */
7303         int ret;
7304         unsigned int hexlen = len;
7305         unsigned int length = 256;
7306         uint8_t hex_tmp[length];
7307
7308         /* Arguments are expected. */
7309         if (!arg_data)
7310                 return -1;
7311         if (!arg_len) {
7312                 push_args(ctx, arg_data);
7313                 return -1;
7314         }
7315         if (!arg_addr) {
7316                 push_args(ctx, arg_len);
7317                 push_args(ctx, arg_data);
7318                 return -1;
7319         }
7320         size = arg_data->size;
7321         /* Bit-mask fill is not supported. */
7322         if (arg_data->mask)
7323                 goto error;
7324         if (!ctx->object)
7325                 return len;
7326
7327         /* translate bytes string to array. */
7328         if (str[0] == '0' && ((str[1] == 'x') ||
7329                         (str[1] == 'X'))) {
7330                 str += 2;
7331                 hexlen -= 2;
7332         }
7333         if (hexlen > length)
7334                 return -1;
7335         ret = parse_hex_string(str, hex_tmp, &hexlen);
7336         if (ret < 0)
7337                 goto error;
7338         /* Let parse_int() fill length information first. */
7339         ret = snprintf(tmp, sizeof(tmp), "%u", hexlen);
7340         if (ret < 0)
7341                 goto error;
7342         /* Save length if requested. */
7343         if (arg_len->size) {
7344                 push_args(ctx, arg_len);
7345                 ret = parse_int(ctx, token, tmp, ret, NULL, 0);
7346                 if (ret < 0) {
7347                         pop_args(ctx);
7348                         goto error;
7349                 }
7350         }
7351         buf = (uint8_t *)ctx->object + arg_data->offset;
7352         /* Output buffer is not necessarily NUL-terminated. */
7353         memcpy(buf, hex_tmp, hexlen);
7354         memset((uint8_t *)buf + hexlen, 0x00, size - hexlen);
7355         if (ctx->objmask)
7356                 memset((uint8_t *)ctx->objmask + arg_data->offset,
7357                                         0xff, hexlen);
7358         /* Save address if requested. */
7359         if (arg_addr->size) {
7360                 memcpy((uint8_t *)ctx->object + arg_addr->offset,
7361                        (void *[]){
7362                         (uint8_t *)ctx->object + arg_data->offset
7363                        },
7364                        arg_addr->size);
7365                 if (ctx->objmask)
7366                         memcpy((uint8_t *)ctx->objmask + arg_addr->offset,
7367                                (void *[]){
7368                                 (uint8_t *)ctx->objmask + arg_data->offset
7369                                },
7370                                arg_addr->size);
7371         }
7372         return len;
7373 error:
7374         push_args(ctx, arg_addr);
7375         push_args(ctx, arg_len);
7376         push_args(ctx, arg_data);
7377         return -1;
7378
7379 }
7380
7381 /**
7382  * Parse a zero-ended string.
7383  */
7384 static int
7385 parse_string0(struct context *ctx, const struct token *token __rte_unused,
7386              const char *str, unsigned int len,
7387              void *buf, unsigned int size)
7388 {
7389         const struct arg *arg_data = pop_args(ctx);
7390
7391         /* Arguments are expected. */
7392         if (!arg_data)
7393                 return -1;
7394         size = arg_data->size;
7395         /* Bit-mask fill is not supported. */
7396         if (arg_data->mask || size < len + 1)
7397                 goto error;
7398         if (!ctx->object)
7399                 return len;
7400         buf = (uint8_t *)ctx->object + arg_data->offset;
7401         strncpy(buf, str, len);
7402         if (ctx->objmask)
7403                 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len);
7404         return len;
7405 error:
7406         push_args(ctx, arg_data);
7407         return -1;
7408 }
7409
7410 /**
7411  * Parse a MAC address.
7412  *
7413  * Last argument (ctx->args) is retrieved to determine storage size and
7414  * location.
7415  */
7416 static int
7417 parse_mac_addr(struct context *ctx, const struct token *token,
7418                const char *str, unsigned int len,
7419                void *buf, unsigned int size)
7420 {
7421         const struct arg *arg = pop_args(ctx);
7422         struct rte_ether_addr tmp;
7423         int ret;
7424
7425         (void)token;
7426         /* Argument is expected. */
7427         if (!arg)
7428                 return -1;
7429         size = arg->size;
7430         /* Bit-mask fill is not supported. */
7431         if (arg->mask || size != sizeof(tmp))
7432                 goto error;
7433         /* Only network endian is supported. */
7434         if (!arg->hton)
7435                 goto error;
7436         ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
7437         if (ret < 0 || (unsigned int)ret != len)
7438                 goto error;
7439         if (!ctx->object)
7440                 return len;
7441         buf = (uint8_t *)ctx->object + arg->offset;
7442         memcpy(buf, &tmp, size);
7443         if (ctx->objmask)
7444                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
7445         return len;
7446 error:
7447         push_args(ctx, arg);
7448         return -1;
7449 }
7450
7451 /**
7452  * Parse an IPv4 address.
7453  *
7454  * Last argument (ctx->args) is retrieved to determine storage size and
7455  * location.
7456  */
7457 static int
7458 parse_ipv4_addr(struct context *ctx, const struct token *token,
7459                 const char *str, unsigned int len,
7460                 void *buf, unsigned int size)
7461 {
7462         const struct arg *arg = pop_args(ctx);
7463         char str2[len + 1];
7464         struct in_addr tmp;
7465         int ret;
7466
7467         /* Argument is expected. */
7468         if (!arg)
7469                 return -1;
7470         size = arg->size;
7471         /* Bit-mask fill is not supported. */
7472         if (arg->mask || size != sizeof(tmp))
7473                 goto error;
7474         /* Only network endian is supported. */
7475         if (!arg->hton)
7476                 goto error;
7477         memcpy(str2, str, len);
7478         str2[len] = '\0';
7479         ret = inet_pton(AF_INET, str2, &tmp);
7480         if (ret != 1) {
7481                 /* Attempt integer parsing. */
7482                 push_args(ctx, arg);
7483                 return parse_int(ctx, token, str, len, buf, size);
7484         }
7485         if (!ctx->object)
7486                 return len;
7487         buf = (uint8_t *)ctx->object + arg->offset;
7488         memcpy(buf, &tmp, size);
7489         if (ctx->objmask)
7490                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
7491         return len;
7492 error:
7493         push_args(ctx, arg);
7494         return -1;
7495 }
7496
7497 /**
7498  * Parse an IPv6 address.
7499  *
7500  * Last argument (ctx->args) is retrieved to determine storage size and
7501  * location.
7502  */
7503 static int
7504 parse_ipv6_addr(struct context *ctx, const struct token *token,
7505                 const char *str, unsigned int len,
7506                 void *buf, unsigned int size)
7507 {
7508         const struct arg *arg = pop_args(ctx);
7509         char str2[len + 1];
7510         struct in6_addr tmp;
7511         int ret;
7512
7513         (void)token;
7514         /* Argument is expected. */
7515         if (!arg)
7516                 return -1;
7517         size = arg->size;
7518         /* Bit-mask fill is not supported. */
7519         if (arg->mask || size != sizeof(tmp))
7520                 goto error;
7521         /* Only network endian is supported. */
7522         if (!arg->hton)
7523                 goto error;
7524         memcpy(str2, str, len);
7525         str2[len] = '\0';
7526         ret = inet_pton(AF_INET6, str2, &tmp);
7527         if (ret != 1)
7528                 goto error;
7529         if (!ctx->object)
7530                 return len;
7531         buf = (uint8_t *)ctx->object + arg->offset;
7532         memcpy(buf, &tmp, size);
7533         if (ctx->objmask)
7534                 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
7535         return len;
7536 error:
7537         push_args(ctx, arg);
7538         return -1;
7539 }
7540
7541 /** Boolean values (even indices stand for false). */
7542 static const char *const boolean_name[] = {
7543         "0", "1",
7544         "false", "true",
7545         "no", "yes",
7546         "N", "Y",
7547         "off", "on",
7548         NULL,
7549 };
7550
7551 /**
7552  * Parse a boolean value.
7553  *
7554  * Last argument (ctx->args) is retrieved to determine storage size and
7555  * location.
7556  */
7557 static int
7558 parse_boolean(struct context *ctx, const struct token *token,
7559               const char *str, unsigned int len,
7560               void *buf, unsigned int size)
7561 {
7562         const struct arg *arg = pop_args(ctx);
7563         unsigned int i;
7564         int ret;
7565
7566         /* Argument is expected. */
7567         if (!arg)
7568                 return -1;
7569         for (i = 0; boolean_name[i]; ++i)
7570                 if (!strcmp_partial(boolean_name[i], str, len))
7571                         break;
7572         /* Process token as integer. */
7573         if (boolean_name[i])
7574                 str = i & 1 ? "1" : "0";
7575         push_args(ctx, arg);
7576         ret = parse_int(ctx, token, str, strlen(str), buf, size);
7577         return ret > 0 ? (int)len : ret;
7578 }
7579
7580 /** Parse port and update context. */
7581 static int
7582 parse_port(struct context *ctx, const struct token *token,
7583            const char *str, unsigned int len,
7584            void *buf, unsigned int size)
7585 {
7586         struct buffer *out = &(struct buffer){ .port = 0 };
7587         int ret;
7588
7589         if (buf)
7590                 out = buf;
7591         else {
7592                 ctx->objdata = 0;
7593                 ctx->object = out;
7594                 ctx->objmask = NULL;
7595                 size = sizeof(*out);
7596         }
7597         ret = parse_int(ctx, token, str, len, out, size);
7598         if (ret >= 0)
7599                 ctx->port = out->port;
7600         if (!buf)
7601                 ctx->object = NULL;
7602         return ret;
7603 }
7604
7605 static int
7606 parse_ia_id2ptr(struct context *ctx, const struct token *token,
7607                 const char *str, unsigned int len,
7608                 void *buf, unsigned int size)
7609 {
7610         struct rte_flow_action *action = ctx->object;
7611         uint32_t id;
7612         int ret;
7613
7614         (void)buf;
7615         (void)size;
7616         ctx->objdata = 0;
7617         ctx->object = &id;
7618         ctx->objmask = NULL;
7619         ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id));
7620         ctx->object = action;
7621         if (ret != (int)len)
7622                 return ret;
7623         /* set indirect action */
7624         if (action) {
7625                 action->conf = port_action_handle_get_by_id(ctx->port, id);
7626                 ret = (action->conf) ? ret : -1;
7627         }
7628         return ret;
7629 }
7630
7631 /** Parse set command, initialize output buffer for subsequent tokens. */
7632 static int
7633 parse_set_raw_encap_decap(struct context *ctx, const struct token *token,
7634                           const char *str, unsigned int len,
7635                           void *buf, unsigned int size)
7636 {
7637         struct buffer *out = buf;
7638
7639         /* Token name must match. */
7640         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7641                 return -1;
7642         /* Nothing else to do if there is no buffer. */
7643         if (!out)
7644                 return len;
7645         /* Make sure buffer is large enough. */
7646         if (size < sizeof(*out))
7647                 return -1;
7648         ctx->objdata = 0;
7649         ctx->objmask = NULL;
7650         ctx->object = out;
7651         if (!out->command)
7652                 return -1;
7653         out->command = ctx->curr;
7654         /* For encap/decap we need is pattern */
7655         out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
7656                                                        sizeof(double));
7657         return len;
7658 }
7659
7660 /** Parse set command, initialize output buffer for subsequent tokens. */
7661 static int
7662 parse_set_sample_action(struct context *ctx, const struct token *token,
7663                           const char *str, unsigned int len,
7664                           void *buf, unsigned int size)
7665 {
7666         struct buffer *out = buf;
7667
7668         /* Token name must match. */
7669         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7670                 return -1;
7671         /* Nothing else to do if there is no buffer. */
7672         if (!out)
7673                 return len;
7674         /* Make sure buffer is large enough. */
7675         if (size < sizeof(*out))
7676                 return -1;
7677         ctx->objdata = 0;
7678         ctx->objmask = NULL;
7679         ctx->object = out;
7680         if (!out->command)
7681                 return -1;
7682         out->command = ctx->curr;
7683         /* For sampler we need is actions */
7684         out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
7685                                                        sizeof(double));
7686         return len;
7687 }
7688
7689 /**
7690  * Parse set raw_encap/raw_decap command,
7691  * initialize output buffer for subsequent tokens.
7692  */
7693 static int
7694 parse_set_init(struct context *ctx, const struct token *token,
7695                const char *str, unsigned int len,
7696                void *buf, unsigned int size)
7697 {
7698         struct buffer *out = buf;
7699
7700         /* Token name must match. */
7701         if (parse_default(ctx, token, str, len, NULL, 0) < 0)
7702                 return -1;
7703         /* Nothing else to do if there is no buffer. */
7704         if (!out)
7705                 return len;
7706         /* Make sure buffer is large enough. */
7707         if (size < sizeof(*out))
7708                 return -1;
7709         /* Initialize buffer. */
7710         memset(out, 0x00, sizeof(*out));
7711         memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out));
7712         ctx->objdata = 0;
7713         ctx->object = out;
7714         ctx->objmask = NULL;
7715         if (!out->command) {
7716                 if (ctx->curr != SET)
7717                         return -1;
7718                 if (sizeof(*out) > size)
7719                         return -1;
7720                 out->command = ctx->curr;
7721                 out->args.vc.data = (uint8_t *)out + size;
7722                 ctx->object  = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
7723                                                        sizeof(double));
7724         }
7725         return len;
7726 }
7727
7728 /** No completion. */
7729 static int
7730 comp_none(struct context *ctx, const struct token *token,
7731           unsigned int ent, char *buf, unsigned int size)
7732 {
7733         (void)ctx;
7734         (void)token;
7735         (void)ent;
7736         (void)buf;
7737         (void)size;
7738         return 0;
7739 }
7740
7741 /** Complete boolean values. */
7742 static int
7743 comp_boolean(struct context *ctx, const struct token *token,
7744              unsigned int ent, char *buf, unsigned int size)
7745 {
7746         unsigned int i;
7747
7748         (void)ctx;
7749         (void)token;
7750         for (i = 0; boolean_name[i]; ++i)
7751                 if (buf && i == ent)
7752                         return strlcpy(buf, boolean_name[i], size);
7753         if (buf)
7754                 return -1;
7755         return i;
7756 }
7757
7758 /** Complete action names. */
7759 static int
7760 comp_action(struct context *ctx, const struct token *token,
7761             unsigned int ent, char *buf, unsigned int size)
7762 {
7763         unsigned int i;
7764
7765         (void)ctx;
7766         (void)token;
7767         for (i = 0; next_action[i]; ++i)
7768                 if (buf && i == ent)
7769                         return strlcpy(buf, token_list[next_action[i]].name,
7770                                        size);
7771         if (buf)
7772                 return -1;
7773         return i;
7774 }
7775
7776 /** Complete available ports. */
7777 static int
7778 comp_port(struct context *ctx, const struct token *token,
7779           unsigned int ent, char *buf, unsigned int size)
7780 {
7781         unsigned int i = 0;
7782         portid_t p;
7783
7784         (void)ctx;
7785         (void)token;
7786         RTE_ETH_FOREACH_DEV(p) {
7787                 if (buf && i == ent)
7788                         return snprintf(buf, size, "%u", p);
7789                 ++i;
7790         }
7791         if (buf)
7792                 return -1;
7793         return i;
7794 }
7795
7796 /** Complete available rule IDs. */
7797 static int
7798 comp_rule_id(struct context *ctx, const struct token *token,
7799              unsigned int ent, char *buf, unsigned int size)
7800 {
7801         unsigned int i = 0;
7802         struct rte_port *port;
7803         struct port_flow *pf;
7804
7805         (void)token;
7806         if (port_id_is_invalid(ctx->port, DISABLED_WARN) ||
7807             ctx->port == (portid_t)RTE_PORT_ALL)
7808                 return -1;
7809         port = &ports[ctx->port];
7810         for (pf = port->flow_list; pf != NULL; pf = pf->next) {
7811                 if (buf && i == ent)
7812                         return snprintf(buf, size, "%u", pf->id);
7813                 ++i;
7814         }
7815         if (buf)
7816                 return -1;
7817         return i;
7818 }
7819
7820 /** Complete type field for RSS action. */
7821 static int
7822 comp_vc_action_rss_type(struct context *ctx, const struct token *token,
7823                         unsigned int ent, char *buf, unsigned int size)
7824 {
7825         unsigned int i;
7826
7827         (void)ctx;
7828         (void)token;
7829         for (i = 0; rss_type_table[i].str; ++i)
7830                 ;
7831         if (!buf)
7832                 return i + 1;
7833         if (ent < i)
7834                 return strlcpy(buf, rss_type_table[ent].str, size);
7835         if (ent == i)
7836                 return snprintf(buf, size, "end");
7837         return -1;
7838 }
7839
7840 /** Complete queue field for RSS action. */
7841 static int
7842 comp_vc_action_rss_queue(struct context *ctx, const struct token *token,
7843                          unsigned int ent, char *buf, unsigned int size)
7844 {
7845         (void)ctx;
7846         (void)token;
7847         if (!buf)
7848                 return nb_rxq + 1;
7849         if (ent < nb_rxq)
7850                 return snprintf(buf, size, "%u", ent);
7851         if (ent == nb_rxq)
7852                 return snprintf(buf, size, "end");
7853         return -1;
7854 }
7855
7856 /** Complete index number for set raw_encap/raw_decap commands. */
7857 static int
7858 comp_set_raw_index(struct context *ctx, const struct token *token,
7859                    unsigned int ent, char *buf, unsigned int size)
7860 {
7861         uint16_t idx = 0;
7862         uint16_t nb = 0;
7863
7864         RTE_SET_USED(ctx);
7865         RTE_SET_USED(token);
7866         for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) {
7867                 if (buf && idx == ent)
7868                         return snprintf(buf, size, "%u", idx);
7869                 ++nb;
7870         }
7871         return nb;
7872 }
7873
7874 /** Complete index number for set raw_encap/raw_decap commands. */
7875 static int
7876 comp_set_sample_index(struct context *ctx, const struct token *token,
7877                    unsigned int ent, char *buf, unsigned int size)
7878 {
7879         uint16_t idx = 0;
7880         uint16_t nb = 0;
7881
7882         RTE_SET_USED(ctx);
7883         RTE_SET_USED(token);
7884         for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) {
7885                 if (buf && idx == ent)
7886                         return snprintf(buf, size, "%u", idx);
7887                 ++nb;
7888         }
7889         return nb;
7890 }
7891
7892 /** Complete operation for modify_field command. */
7893 static int
7894 comp_set_modify_field_op(struct context *ctx, const struct token *token,
7895                    unsigned int ent, char *buf, unsigned int size)
7896 {
7897         uint16_t idx = 0;
7898
7899         RTE_SET_USED(ctx);
7900         RTE_SET_USED(token);
7901         for (idx = 0; modify_field_ops[idx]; ++idx)
7902                 ;
7903         if (!buf)
7904                 return idx + 1;
7905         if (ent < idx)
7906                 return strlcpy(buf, modify_field_ops[ent], size);
7907         return -1;
7908 }
7909
7910 /** Complete field id for modify_field command. */
7911 static int
7912 comp_set_modify_field_id(struct context *ctx, const struct token *token,
7913                    unsigned int ent, char *buf, unsigned int size)
7914 {
7915         uint16_t idx = 0;
7916
7917         RTE_SET_USED(ctx);
7918         RTE_SET_USED(token);
7919         for (idx = 0; modify_field_ids[idx]; ++idx)
7920                 ;
7921         if (!buf)
7922                 return idx + 1;
7923         if (ent < idx)
7924                 return strlcpy(buf, modify_field_ids[ent], size);
7925         return -1;
7926 }
7927
7928 /** Internal context. */
7929 static struct context cmd_flow_context;
7930
7931 /** Global parser instance (cmdline API). */
7932 cmdline_parse_inst_t cmd_flow;
7933 cmdline_parse_inst_t cmd_set_raw;
7934
7935 /** Initialize context. */
7936 static void
7937 cmd_flow_context_init(struct context *ctx)
7938 {
7939         /* A full memset() is not necessary. */
7940         ctx->curr = ZERO;
7941         ctx->prev = ZERO;
7942         ctx->next_num = 0;
7943         ctx->args_num = 0;
7944         ctx->eol = 0;
7945         ctx->last = 0;
7946         ctx->port = 0;
7947         ctx->objdata = 0;
7948         ctx->object = NULL;
7949         ctx->objmask = NULL;
7950 }
7951
7952 /** Parse a token (cmdline API). */
7953 static int
7954 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result,
7955                unsigned int size)
7956 {
7957         struct context *ctx = &cmd_flow_context;
7958         const struct token *token;
7959         const enum index *list;
7960         int len;
7961         int i;
7962
7963         (void)hdr;
7964         token = &token_list[ctx->curr];
7965         /* Check argument length. */
7966         ctx->eol = 0;
7967         ctx->last = 1;
7968         for (len = 0; src[len]; ++len)
7969                 if (src[len] == '#' || isspace(src[len]))
7970                         break;
7971         if (!len)
7972                 return -1;
7973         /* Last argument and EOL detection. */
7974         for (i = len; src[i]; ++i)
7975                 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n')
7976                         break;
7977                 else if (!isspace(src[i])) {
7978                         ctx->last = 0;
7979                         break;
7980                 }
7981         for (; src[i]; ++i)
7982                 if (src[i] == '\r' || src[i] == '\n') {
7983                         ctx->eol = 1;
7984                         break;
7985                 }
7986         /* Initialize context if necessary. */
7987         if (!ctx->next_num) {
7988                 if (!token->next)
7989                         return 0;
7990                 ctx->next[ctx->next_num++] = token->next[0];
7991         }
7992         /* Process argument through candidates. */
7993         ctx->prev = ctx->curr;
7994         list = ctx->next[ctx->next_num - 1];
7995         for (i = 0; list[i]; ++i) {
7996                 const struct token *next = &token_list[list[i]];
7997                 int tmp;
7998
7999                 ctx->curr = list[i];
8000                 if (next->call)
8001                         tmp = next->call(ctx, next, src, len, result, size);
8002                 else
8003                         tmp = parse_default(ctx, next, src, len, result, size);
8004                 if (tmp == -1 || tmp != len)
8005                         continue;
8006                 token = next;
8007                 break;
8008         }
8009         if (!list[i])
8010                 return -1;
8011         --ctx->next_num;
8012         /* Push subsequent tokens if any. */
8013         if (token->next)
8014                 for (i = 0; token->next[i]; ++i) {
8015                         if (ctx->next_num == RTE_DIM(ctx->next))
8016                                 return -1;
8017                         ctx->next[ctx->next_num++] = token->next[i];
8018                 }
8019         /* Push arguments if any. */
8020         if (token->args)
8021                 for (i = 0; token->args[i]; ++i) {
8022                         if (ctx->args_num == RTE_DIM(ctx->args))
8023                                 return -1;
8024                         ctx->args[ctx->args_num++] = token->args[i];
8025                 }
8026         return len;
8027 }
8028
8029 /** Return number of completion entries (cmdline API). */
8030 static int
8031 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr)
8032 {
8033         struct context *ctx = &cmd_flow_context;
8034         const struct token *token = &token_list[ctx->curr];
8035         const enum index *list;
8036         int i;
8037
8038         (void)hdr;
8039         /* Count number of tokens in current list. */
8040         if (ctx->next_num)
8041                 list = ctx->next[ctx->next_num - 1];
8042         else
8043                 list = token->next[0];
8044         for (i = 0; list[i]; ++i)
8045                 ;
8046         if (!i)
8047                 return 0;
8048         /*
8049          * If there is a single token, use its completion callback, otherwise
8050          * return the number of entries.
8051          */
8052         token = &token_list[list[0]];
8053         if (i == 1 && token->comp) {
8054                 /* Save index for cmd_flow_get_help(). */
8055                 ctx->prev = list[0];
8056                 return token->comp(ctx, token, 0, NULL, 0);
8057         }
8058         return i;
8059 }
8060
8061 /** Return a completion entry (cmdline API). */
8062 static int
8063 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index,
8064                           char *dst, unsigned int size)
8065 {
8066         struct context *ctx = &cmd_flow_context;
8067         const struct token *token = &token_list[ctx->curr];
8068         const enum index *list;
8069         int i;
8070
8071         (void)hdr;
8072         /* Count number of tokens in current list. */
8073         if (ctx->next_num)
8074                 list = ctx->next[ctx->next_num - 1];
8075         else
8076                 list = token->next[0];
8077         for (i = 0; list[i]; ++i)
8078                 ;
8079         if (!i)
8080                 return -1;
8081         /* If there is a single token, use its completion callback. */
8082         token = &token_list[list[0]];
8083         if (i == 1 && token->comp) {
8084                 /* Save index for cmd_flow_get_help(). */
8085                 ctx->prev = list[0];
8086                 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0;
8087         }
8088         /* Otherwise make sure the index is valid and use defaults. */
8089         if (index >= i)
8090                 return -1;
8091         token = &token_list[list[index]];
8092         strlcpy(dst, token->name, size);
8093         /* Save index for cmd_flow_get_help(). */
8094         ctx->prev = list[index];
8095         return 0;
8096 }
8097
8098 /** Populate help strings for current token (cmdline API). */
8099 static int
8100 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size)
8101 {
8102         struct context *ctx = &cmd_flow_context;
8103         const struct token *token = &token_list[ctx->prev];
8104
8105         (void)hdr;
8106         if (!size)
8107                 return -1;
8108         /* Set token type and update global help with details. */
8109         strlcpy(dst, (token->type ? token->type : "TOKEN"), size);
8110         if (token->help)
8111                 cmd_flow.help_str = token->help;
8112         else
8113                 cmd_flow.help_str = token->name;
8114         return 0;
8115 }
8116
8117 /** Token definition template (cmdline API). */
8118 static struct cmdline_token_hdr cmd_flow_token_hdr = {
8119         .ops = &(struct cmdline_token_ops){
8120                 .parse = cmd_flow_parse,
8121                 .complete_get_nb = cmd_flow_complete_get_nb,
8122                 .complete_get_elt = cmd_flow_complete_get_elt,
8123                 .get_help = cmd_flow_get_help,
8124         },
8125         .offset = 0,
8126 };
8127
8128 /** Populate the next dynamic token. */
8129 static void
8130 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr,
8131              cmdline_parse_token_hdr_t **hdr_inst)
8132 {
8133         struct context *ctx = &cmd_flow_context;
8134
8135         /* Always reinitialize context before requesting the first token. */
8136         if (!(hdr_inst - cmd_flow.tokens))
8137                 cmd_flow_context_init(ctx);
8138         /* Return NULL when no more tokens are expected. */
8139         if (!ctx->next_num && ctx->curr) {
8140                 *hdr = NULL;
8141                 return;
8142         }
8143         /* Determine if command should end here. */
8144         if (ctx->eol && ctx->last && ctx->next_num) {
8145                 const enum index *list = ctx->next[ctx->next_num - 1];
8146                 int i;
8147
8148                 for (i = 0; list[i]; ++i) {
8149                         if (list[i] != END)
8150                                 continue;
8151                         *hdr = NULL;
8152                         return;
8153                 }
8154         }
8155         *hdr = &cmd_flow_token_hdr;
8156 }
8157
8158 /** Dispatch parsed buffer to function calls. */
8159 static void
8160 cmd_flow_parsed(const struct buffer *in)
8161 {
8162         switch (in->command) {
8163         case INDIRECT_ACTION_CREATE:
8164                 port_action_handle_create(
8165                                 in->port, in->args.vc.attr.group,
8166                                 &((const struct rte_flow_indir_action_conf) {
8167                                         .ingress = in->args.vc.attr.ingress,
8168                                         .egress = in->args.vc.attr.egress,
8169                                         .transfer = in->args.vc.attr.transfer,
8170                                 }),
8171                                 in->args.vc.actions);
8172                 break;
8173         case INDIRECT_ACTION_DESTROY:
8174                 port_action_handle_destroy(in->port,
8175                                            in->args.ia_destroy.action_id_n,
8176                                            in->args.ia_destroy.action_id);
8177                 break;
8178         case INDIRECT_ACTION_UPDATE:
8179                 port_action_handle_update(in->port, in->args.vc.attr.group,
8180                                           in->args.vc.actions);
8181                 break;
8182         case INDIRECT_ACTION_QUERY:
8183                 port_action_handle_query(in->port, in->args.ia.action_id);
8184                 break;
8185         case VALIDATE:
8186                 port_flow_validate(in->port, &in->args.vc.attr,
8187                                    in->args.vc.pattern, in->args.vc.actions,
8188                                    &in->args.vc.tunnel_ops);
8189                 break;
8190         case CREATE:
8191                 port_flow_create(in->port, &in->args.vc.attr,
8192                                  in->args.vc.pattern, in->args.vc.actions,
8193                                  &in->args.vc.tunnel_ops);
8194                 break;
8195         case DESTROY:
8196                 port_flow_destroy(in->port, in->args.destroy.rule_n,
8197                                   in->args.destroy.rule);
8198                 break;
8199         case FLUSH:
8200                 port_flow_flush(in->port);
8201                 break;
8202         case DUMP_ONE:
8203         case DUMP_ALL:
8204                 port_flow_dump(in->port, in->args.dump.mode,
8205                                 in->args.dump.rule, in->args.dump.file);
8206                 break;
8207         case QUERY:
8208                 port_flow_query(in->port, in->args.query.rule,
8209                                 &in->args.query.action);
8210                 break;
8211         case LIST:
8212                 port_flow_list(in->port, in->args.list.group_n,
8213                                in->args.list.group);
8214                 break;
8215         case ISOLATE:
8216                 port_flow_isolate(in->port, in->args.isolate.set);
8217                 break;
8218         case AGED:
8219                 port_flow_aged(in->port, in->args.aged.destroy);
8220                 break;
8221         case TUNNEL_CREATE:
8222                 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops);
8223                 break;
8224         case TUNNEL_DESTROY:
8225                 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id);
8226                 break;
8227         case TUNNEL_LIST:
8228                 port_flow_tunnel_list(in->port);
8229                 break;
8230         case ACTION_POL_G:
8231                 port_meter_policy_add(in->port, in->args.policy.policy_id,
8232                                         in->args.vc.actions);
8233                 break;
8234         default:
8235                 break;
8236         }
8237 }
8238
8239 /** Token generator and output processing callback (cmdline API). */
8240 static void
8241 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2)
8242 {
8243         if (cl == NULL)
8244                 cmd_flow_tok(arg0, arg2);
8245         else
8246                 cmd_flow_parsed(arg0);
8247 }
8248
8249 /** Global parser instance (cmdline API). */
8250 cmdline_parse_inst_t cmd_flow = {
8251         .f = cmd_flow_cb,
8252         .data = NULL, /**< Unused. */
8253         .help_str = NULL, /**< Updated by cmd_flow_get_help(). */
8254         .tokens = {
8255                 NULL,
8256         }, /**< Tokens are returned by cmd_flow_tok(). */
8257 };
8258
8259 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */
8260
8261 static void
8262 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto)
8263 {
8264         struct rte_ipv4_hdr *ipv4;
8265         struct rte_ether_hdr *eth;
8266         struct rte_ipv6_hdr *ipv6;
8267         struct rte_vxlan_hdr *vxlan;
8268         struct rte_vxlan_gpe_hdr *gpe;
8269         struct rte_flow_item_nvgre *nvgre;
8270         uint32_t ipv6_vtc_flow;
8271
8272         switch (item->type) {
8273         case RTE_FLOW_ITEM_TYPE_ETH:
8274                 eth = (struct rte_ether_hdr *)buf;
8275                 if (next_proto)
8276                         eth->ether_type = rte_cpu_to_be_16(next_proto);
8277                 break;
8278         case RTE_FLOW_ITEM_TYPE_IPV4:
8279                 ipv4 = (struct rte_ipv4_hdr *)buf;
8280                 if (!ipv4->version_ihl)
8281                         ipv4->version_ihl = RTE_IPV4_VHL_DEF;
8282                 if (next_proto && ipv4->next_proto_id == 0)
8283                         ipv4->next_proto_id = (uint8_t)next_proto;
8284                 break;
8285         case RTE_FLOW_ITEM_TYPE_IPV6:
8286                 ipv6 = (struct rte_ipv6_hdr *)buf;
8287                 if (next_proto && ipv6->proto == 0)
8288                         ipv6->proto = (uint8_t)next_proto;
8289                 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow);
8290                 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */
8291                 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */
8292                 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow);
8293                 break;
8294         case RTE_FLOW_ITEM_TYPE_VXLAN:
8295                 vxlan = (struct rte_vxlan_hdr *)buf;
8296                 vxlan->vx_flags = 0x08;
8297                 break;
8298         case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
8299                 gpe = (struct rte_vxlan_gpe_hdr *)buf;
8300                 gpe->vx_flags = 0x0C;
8301                 break;
8302         case RTE_FLOW_ITEM_TYPE_NVGRE:
8303                 nvgre = (struct rte_flow_item_nvgre *)buf;
8304                 nvgre->protocol = rte_cpu_to_be_16(0x6558);
8305                 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000);
8306                 break;
8307         default:
8308                 break;
8309         }
8310 }
8311
8312 /** Helper of get item's default mask. */
8313 static const void *
8314 flow_item_default_mask(const struct rte_flow_item *item)
8315 {
8316         const void *mask = NULL;
8317         static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX);
8318
8319         switch (item->type) {
8320         case RTE_FLOW_ITEM_TYPE_ANY:
8321                 mask = &rte_flow_item_any_mask;
8322                 break;
8323         case RTE_FLOW_ITEM_TYPE_VF:
8324                 mask = &rte_flow_item_vf_mask;
8325                 break;
8326         case RTE_FLOW_ITEM_TYPE_PORT_ID:
8327                 mask = &rte_flow_item_port_id_mask;
8328                 break;
8329         case RTE_FLOW_ITEM_TYPE_RAW:
8330                 mask = &rte_flow_item_raw_mask;
8331                 break;
8332         case RTE_FLOW_ITEM_TYPE_ETH:
8333                 mask = &rte_flow_item_eth_mask;
8334                 break;
8335         case RTE_FLOW_ITEM_TYPE_VLAN:
8336                 mask = &rte_flow_item_vlan_mask;
8337                 break;
8338         case RTE_FLOW_ITEM_TYPE_IPV4:
8339                 mask = &rte_flow_item_ipv4_mask;
8340                 break;
8341         case RTE_FLOW_ITEM_TYPE_IPV6:
8342                 mask = &rte_flow_item_ipv6_mask;
8343                 break;
8344         case RTE_FLOW_ITEM_TYPE_ICMP:
8345                 mask = &rte_flow_item_icmp_mask;
8346                 break;
8347         case RTE_FLOW_ITEM_TYPE_UDP:
8348                 mask = &rte_flow_item_udp_mask;
8349                 break;
8350         case RTE_FLOW_ITEM_TYPE_TCP:
8351                 mask = &rte_flow_item_tcp_mask;
8352                 break;
8353         case RTE_FLOW_ITEM_TYPE_SCTP:
8354                 mask = &rte_flow_item_sctp_mask;
8355                 break;
8356         case RTE_FLOW_ITEM_TYPE_VXLAN:
8357                 mask = &rte_flow_item_vxlan_mask;
8358                 break;
8359         case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
8360                 mask = &rte_flow_item_vxlan_gpe_mask;
8361                 break;
8362         case RTE_FLOW_ITEM_TYPE_E_TAG:
8363                 mask = &rte_flow_item_e_tag_mask;
8364                 break;
8365         case RTE_FLOW_ITEM_TYPE_NVGRE:
8366                 mask = &rte_flow_item_nvgre_mask;
8367                 break;
8368         case RTE_FLOW_ITEM_TYPE_MPLS:
8369                 mask = &rte_flow_item_mpls_mask;
8370                 break;
8371         case RTE_FLOW_ITEM_TYPE_GRE:
8372                 mask = &rte_flow_item_gre_mask;
8373                 break;
8374         case RTE_FLOW_ITEM_TYPE_GRE_KEY:
8375                 mask = &gre_key_default_mask;
8376                 break;
8377         case RTE_FLOW_ITEM_TYPE_META:
8378                 mask = &rte_flow_item_meta_mask;
8379                 break;
8380         case RTE_FLOW_ITEM_TYPE_FUZZY:
8381                 mask = &rte_flow_item_fuzzy_mask;
8382                 break;
8383         case RTE_FLOW_ITEM_TYPE_GTP:
8384                 mask = &rte_flow_item_gtp_mask;
8385                 break;
8386         case RTE_FLOW_ITEM_TYPE_GTP_PSC:
8387                 mask = &rte_flow_item_gtp_psc_mask;
8388                 break;
8389         case RTE_FLOW_ITEM_TYPE_GENEVE:
8390                 mask = &rte_flow_item_geneve_mask;
8391                 break;
8392         case RTE_FLOW_ITEM_TYPE_GENEVE_OPT:
8393                 mask = &rte_flow_item_geneve_opt_mask;
8394                 break;
8395         case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID:
8396                 mask = &rte_flow_item_pppoe_proto_id_mask;
8397                 break;
8398         case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
8399                 mask = &rte_flow_item_l2tpv3oip_mask;
8400                 break;
8401         case RTE_FLOW_ITEM_TYPE_ESP:
8402                 mask = &rte_flow_item_esp_mask;
8403                 break;
8404         case RTE_FLOW_ITEM_TYPE_AH:
8405                 mask = &rte_flow_item_ah_mask;
8406                 break;
8407         case RTE_FLOW_ITEM_TYPE_PFCP:
8408                 mask = &rte_flow_item_pfcp_mask;
8409                 break;
8410         case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
8411         case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
8412                 mask = &rte_flow_item_ethdev_mask;
8413                 break;
8414         default:
8415                 break;
8416         }
8417         return mask;
8418 }
8419
8420 /** Dispatch parsed buffer to function calls. */
8421 static void
8422 cmd_set_raw_parsed_sample(const struct buffer *in)
8423 {
8424         uint32_t n = in->args.vc.actions_n;
8425         uint32_t i = 0;
8426         struct rte_flow_action *action = NULL;
8427         struct rte_flow_action *data = NULL;
8428         const struct rte_flow_action_rss *rss = NULL;
8429         size_t size = 0;
8430         uint16_t idx = in->port; /* We borrow port field as index */
8431         uint32_t max_size = sizeof(struct rte_flow_action) *
8432                                                 ACTION_SAMPLE_ACTIONS_NUM;
8433
8434         RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS);
8435         data = (struct rte_flow_action *)&raw_sample_confs[idx].data;
8436         memset(data, 0x00, max_size);
8437         for (; i <= n - 1; i++) {
8438                 action = in->args.vc.actions + i;
8439                 if (action->type == RTE_FLOW_ACTION_TYPE_END)
8440                         break;
8441                 switch (action->type) {
8442                 case RTE_FLOW_ACTION_TYPE_MARK:
8443                         size = sizeof(struct rte_flow_action_mark);
8444                         rte_memcpy(&sample_mark[idx],
8445                                 (const void *)action->conf, size);
8446                         action->conf = &sample_mark[idx];
8447                         break;
8448                 case RTE_FLOW_ACTION_TYPE_COUNT:
8449                         size = sizeof(struct rte_flow_action_count);
8450                         rte_memcpy(&sample_count[idx],
8451                                 (const void *)action->conf, size);
8452                         action->conf = &sample_count[idx];
8453                         break;
8454                 case RTE_FLOW_ACTION_TYPE_QUEUE:
8455                         size = sizeof(struct rte_flow_action_queue);
8456                         rte_memcpy(&sample_queue[idx],
8457                                 (const void *)action->conf, size);
8458                         action->conf = &sample_queue[idx];
8459                         break;
8460                 case RTE_FLOW_ACTION_TYPE_RSS:
8461                         size = sizeof(struct rte_flow_action_rss);
8462                         rss = action->conf;
8463                         rte_memcpy(&sample_rss_data[idx].conf,
8464                                    (const void *)rss, size);
8465                         if (rss->key_len && rss->key) {
8466                                 sample_rss_data[idx].conf.key =
8467                                                 sample_rss_data[idx].key;
8468                                 rte_memcpy((void *)((uintptr_t)
8469                                            sample_rss_data[idx].conf.key),
8470                                            (const void *)rss->key,
8471                                            sizeof(uint8_t) * rss->key_len);
8472                         }
8473                         if (rss->queue_num && rss->queue) {
8474                                 sample_rss_data[idx].conf.queue =
8475                                                 sample_rss_data[idx].queue;
8476                                 rte_memcpy((void *)((uintptr_t)
8477                                            sample_rss_data[idx].conf.queue),
8478                                            (const void *)rss->queue,
8479                                            sizeof(uint16_t) * rss->queue_num);
8480                         }
8481                         action->conf = &sample_rss_data[idx].conf;
8482                         break;
8483                 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
8484                         size = sizeof(struct rte_flow_action_raw_encap);
8485                         rte_memcpy(&sample_encap[idx],
8486                                 (const void *)action->conf, size);
8487                         action->conf = &sample_encap[idx];
8488                         break;
8489                 case RTE_FLOW_ACTION_TYPE_PORT_ID:
8490                         size = sizeof(struct rte_flow_action_port_id);
8491                         rte_memcpy(&sample_port_id[idx],
8492                                 (const void *)action->conf, size);
8493                         action->conf = &sample_port_id[idx];
8494                         break;
8495                 case RTE_FLOW_ACTION_TYPE_PF:
8496                         break;
8497                 case RTE_FLOW_ACTION_TYPE_VF:
8498                         size = sizeof(struct rte_flow_action_vf);
8499                         rte_memcpy(&sample_vf[idx],
8500                                         (const void *)action->conf, size);
8501                         action->conf = &sample_vf[idx];
8502                         break;
8503                 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
8504                         size = sizeof(struct rte_flow_action_vxlan_encap);
8505                         parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]);
8506                         action->conf = &sample_vxlan_encap[idx].conf;
8507                         break;
8508                 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
8509                         size = sizeof(struct rte_flow_action_nvgre_encap);
8510                         parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]);
8511                         action->conf = &sample_nvgre_encap[idx];
8512                         break;
8513                 default:
8514                         fprintf(stderr, "Error - Not supported action\n");
8515                         return;
8516                 }
8517                 rte_memcpy(data, action, sizeof(struct rte_flow_action));
8518                 data++;
8519         }
8520 }
8521
8522 /** Dispatch parsed buffer to function calls. */
8523 static void
8524 cmd_set_raw_parsed(const struct buffer *in)
8525 {
8526         uint32_t n = in->args.vc.pattern_n;
8527         int i = 0;
8528         struct rte_flow_item *item = NULL;
8529         size_t size = 0;
8530         uint8_t *data = NULL;
8531         uint8_t *data_tail = NULL;
8532         size_t *total_size = NULL;
8533         uint16_t upper_layer = 0;
8534         uint16_t proto = 0;
8535         uint16_t idx = in->port; /* We borrow port field as index */
8536         int gtp_psc = -1; /* GTP PSC option index. */
8537
8538         if (in->command == SET_SAMPLE_ACTIONS)
8539                 return cmd_set_raw_parsed_sample(in);
8540         RTE_ASSERT(in->command == SET_RAW_ENCAP ||
8541                    in->command == SET_RAW_DECAP);
8542         if (in->command == SET_RAW_ENCAP) {
8543                 total_size = &raw_encap_confs[idx].size;
8544                 data = (uint8_t *)&raw_encap_confs[idx].data;
8545         } else {
8546                 total_size = &raw_decap_confs[idx].size;
8547                 data = (uint8_t *)&raw_decap_confs[idx].data;
8548         }
8549         *total_size = 0;
8550         memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA);
8551         /* process hdr from upper layer to low layer (L3/L4 -> L2). */
8552         data_tail = data + ACTION_RAW_ENCAP_MAX_DATA;
8553         for (i = n - 1 ; i >= 0; --i) {
8554                 const struct rte_flow_item_gtp *gtp;
8555                 const struct rte_flow_item_geneve_opt *opt;
8556
8557                 item = in->args.vc.pattern + i;
8558                 if (item->spec == NULL)
8559                         item->spec = flow_item_default_mask(item);
8560                 switch (item->type) {
8561                 case RTE_FLOW_ITEM_TYPE_ETH:
8562                         size = sizeof(struct rte_ether_hdr);
8563                         break;
8564                 case RTE_FLOW_ITEM_TYPE_VLAN:
8565                         size = sizeof(struct rte_vlan_hdr);
8566                         proto = RTE_ETHER_TYPE_VLAN;
8567                         break;
8568                 case RTE_FLOW_ITEM_TYPE_IPV4:
8569                         size = sizeof(struct rte_ipv4_hdr);
8570                         proto = RTE_ETHER_TYPE_IPV4;
8571                         break;
8572                 case RTE_FLOW_ITEM_TYPE_IPV6:
8573                         size = sizeof(struct rte_ipv6_hdr);
8574                         proto = RTE_ETHER_TYPE_IPV6;
8575                         break;
8576                 case RTE_FLOW_ITEM_TYPE_UDP:
8577                         size = sizeof(struct rte_udp_hdr);
8578                         proto = 0x11;
8579                         break;
8580                 case RTE_FLOW_ITEM_TYPE_TCP:
8581                         size = sizeof(struct rte_tcp_hdr);
8582                         proto = 0x06;
8583                         break;
8584                 case RTE_FLOW_ITEM_TYPE_VXLAN:
8585                         size = sizeof(struct rte_vxlan_hdr);
8586                         break;
8587                 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
8588                         size = sizeof(struct rte_vxlan_gpe_hdr);
8589                         break;
8590                 case RTE_FLOW_ITEM_TYPE_GRE:
8591                         size = sizeof(struct rte_gre_hdr);
8592                         proto = 0x2F;
8593                         break;
8594                 case RTE_FLOW_ITEM_TYPE_GRE_KEY:
8595                         size = sizeof(rte_be32_t);
8596                         proto = 0x0;
8597                         break;
8598                 case RTE_FLOW_ITEM_TYPE_MPLS:
8599                         size = sizeof(struct rte_mpls_hdr);
8600                         proto = 0x0;
8601                         break;
8602                 case RTE_FLOW_ITEM_TYPE_NVGRE:
8603                         size = sizeof(struct rte_flow_item_nvgre);
8604                         proto = 0x2F;
8605                         break;
8606                 case RTE_FLOW_ITEM_TYPE_GENEVE:
8607                         size = sizeof(struct rte_geneve_hdr);
8608                         break;
8609                 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT:
8610                         opt = (const struct rte_flow_item_geneve_opt *)
8611                                                                 item->spec;
8612                         size = offsetof(struct rte_flow_item_geneve_opt, data);
8613                         if (opt->option_len && opt->data) {
8614                                 *total_size += opt->option_len *
8615                                                sizeof(uint32_t);
8616                                 rte_memcpy(data_tail - (*total_size),
8617                                            opt->data,
8618                                            opt->option_len * sizeof(uint32_t));
8619                         }
8620                         break;
8621                 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
8622                         size = sizeof(rte_be32_t);
8623                         proto = 0x73;
8624                         break;
8625                 case RTE_FLOW_ITEM_TYPE_ESP:
8626                         size = sizeof(struct rte_esp_hdr);
8627                         proto = 0x32;
8628                         break;
8629                 case RTE_FLOW_ITEM_TYPE_AH:
8630                         size = sizeof(struct rte_flow_item_ah);
8631                         proto = 0x33;
8632                         break;
8633                 case RTE_FLOW_ITEM_TYPE_GTP:
8634                         if (gtp_psc < 0) {
8635                                 size = sizeof(struct rte_gtp_hdr);
8636                                 break;
8637                         }
8638                         if (gtp_psc != i + 1) {
8639                                 fprintf(stderr,
8640                                         "Error - GTP PSC does not follow GTP\n");
8641                                 goto error;
8642                         }
8643                         gtp = item->spec;
8644                         if ((gtp->v_pt_rsv_flags & 0x07) != 0x04) {
8645                                 /* Only E flag should be set. */
8646                                 fprintf(stderr,
8647                                         "Error - GTP unsupported flags\n");
8648                                 goto error;
8649                         } else {
8650                                 struct rte_gtp_hdr_ext_word ext_word = {
8651                                         .next_ext = 0x85
8652                                 };
8653
8654                                 /* We have to add GTP header extra word. */
8655                                 *total_size += sizeof(ext_word);
8656                                 rte_memcpy(data_tail - (*total_size),
8657                                            &ext_word, sizeof(ext_word));
8658                         }
8659                         size = sizeof(struct rte_gtp_hdr);
8660                         break;
8661                 case RTE_FLOW_ITEM_TYPE_GTP_PSC:
8662                         if (gtp_psc >= 0) {
8663                                 fprintf(stderr,
8664                                         "Error - Multiple GTP PSC items\n");
8665                                 goto error;
8666                         } else {
8667                                 const struct rte_flow_item_gtp_psc
8668                                         *opt = item->spec;
8669                                 struct {
8670                                         uint8_t len;
8671                                         uint8_t pdu_type:4;
8672                                         uint8_t qfi:6;
8673                                         uint8_t next;
8674                                 } psc;
8675                                 psc.len = sizeof(psc);
8676                                 psc.pdu_type = opt->hdr.type;
8677                                 psc.qfi = opt->hdr.qfi;
8678                                 psc.next = 0;
8679                                 *total_size += sizeof(psc);
8680                                 rte_memcpy(data_tail - (*total_size),
8681                                            &psc, sizeof(psc));
8682                                 gtp_psc = i;
8683                                 size = 0;
8684                         }
8685                         break;
8686                 case RTE_FLOW_ITEM_TYPE_PFCP:
8687                         size = sizeof(struct rte_flow_item_pfcp);
8688                         break;
8689                 default:
8690                         fprintf(stderr, "Error - Not supported item\n");
8691                         goto error;
8692                 }
8693                 *total_size += size;
8694                 rte_memcpy(data_tail - (*total_size), item->spec, size);
8695                 /* update some fields which cannot be set by cmdline */
8696                 update_fields((data_tail - (*total_size)), item,
8697                               upper_layer);
8698                 upper_layer = proto;
8699         }
8700         if (verbose_level & 0x1)
8701                 printf("total data size is %zu\n", (*total_size));
8702         RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA);
8703         memmove(data, (data_tail - (*total_size)), *total_size);
8704         return;
8705
8706 error:
8707         *total_size = 0;
8708         memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA);
8709 }
8710
8711 /** Populate help strings for current token (cmdline API). */
8712 static int
8713 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst,
8714                      unsigned int size)
8715 {
8716         struct context *ctx = &cmd_flow_context;
8717         const struct token *token = &token_list[ctx->prev];
8718
8719         (void)hdr;
8720         if (!size)
8721                 return -1;
8722         /* Set token type and update global help with details. */
8723         snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN"));
8724         if (token->help)
8725                 cmd_set_raw.help_str = token->help;
8726         else
8727                 cmd_set_raw.help_str = token->name;
8728         return 0;
8729 }
8730
8731 /** Token definition template (cmdline API). */
8732 static struct cmdline_token_hdr cmd_set_raw_token_hdr = {
8733         .ops = &(struct cmdline_token_ops){
8734                 .parse = cmd_flow_parse,
8735                 .complete_get_nb = cmd_flow_complete_get_nb,
8736                 .complete_get_elt = cmd_flow_complete_get_elt,
8737                 .get_help = cmd_set_raw_get_help,
8738         },
8739         .offset = 0,
8740 };
8741
8742 /** Populate the next dynamic token. */
8743 static void
8744 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr,
8745              cmdline_parse_token_hdr_t **hdr_inst)
8746 {
8747         struct context *ctx = &cmd_flow_context;
8748
8749         /* Always reinitialize context before requesting the first token. */
8750         if (!(hdr_inst - cmd_set_raw.tokens)) {
8751                 cmd_flow_context_init(ctx);
8752                 ctx->curr = START_SET;
8753         }
8754         /* Return NULL when no more tokens are expected. */
8755         if (!ctx->next_num && (ctx->curr != START_SET)) {
8756                 *hdr = NULL;
8757                 return;
8758         }
8759         /* Determine if command should end here. */
8760         if (ctx->eol && ctx->last && ctx->next_num) {
8761                 const enum index *list = ctx->next[ctx->next_num - 1];
8762                 int i;
8763
8764                 for (i = 0; list[i]; ++i) {
8765                         if (list[i] != END)
8766                                 continue;
8767                         *hdr = NULL;
8768                         return;
8769                 }
8770         }
8771         *hdr = &cmd_set_raw_token_hdr;
8772 }
8773
8774 /** Token generator and output processing callback (cmdline API). */
8775 static void
8776 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2)
8777 {
8778         if (cl == NULL)
8779                 cmd_set_raw_tok(arg0, arg2);
8780         else
8781                 cmd_set_raw_parsed(arg0);
8782 }
8783
8784 /** Global parser instance (cmdline API). */
8785 cmdline_parse_inst_t cmd_set_raw = {
8786         .f = cmd_set_raw_cb,
8787         .data = NULL, /**< Unused. */
8788         .help_str = NULL, /**< Updated by cmd_flow_get_help(). */
8789         .tokens = {
8790                 NULL,
8791         }, /**< Tokens are returned by cmd_flow_tok(). */
8792 };
8793
8794 /* *** display raw_encap/raw_decap buf */
8795 struct cmd_show_set_raw_result {
8796         cmdline_fixed_string_t cmd_show;
8797         cmdline_fixed_string_t cmd_what;
8798         cmdline_fixed_string_t cmd_all;
8799         uint16_t cmd_index;
8800 };
8801
8802 static void
8803 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data)
8804 {
8805         struct cmd_show_set_raw_result *res = parsed_result;
8806         uint16_t index = res->cmd_index;
8807         uint8_t all = 0;
8808         uint8_t *raw_data = NULL;
8809         size_t raw_size = 0;
8810         char title[16] = {0};
8811
8812         RTE_SET_USED(cl);
8813         RTE_SET_USED(data);
8814         if (!strcmp(res->cmd_all, "all")) {
8815                 all = 1;
8816                 index = 0;
8817         } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) {
8818                 fprintf(stderr, "index should be 0-%u\n",
8819                         RAW_ENCAP_CONFS_MAX_NUM - 1);
8820                 return;
8821         }
8822         do {
8823                 if (!strcmp(res->cmd_what, "raw_encap")) {
8824                         raw_data = (uint8_t *)&raw_encap_confs[index].data;
8825                         raw_size = raw_encap_confs[index].size;
8826                         snprintf(title, 16, "\nindex: %u", index);
8827                         rte_hexdump(stdout, title, raw_data, raw_size);
8828                 } else {
8829                         raw_data = (uint8_t *)&raw_decap_confs[index].data;
8830                         raw_size = raw_decap_confs[index].size;
8831                         snprintf(title, 16, "\nindex: %u", index);
8832                         rte_hexdump(stdout, title, raw_data, raw_size);
8833                 }
8834         } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM);
8835 }
8836
8837 cmdline_parse_token_string_t cmd_show_set_raw_cmd_show =
8838         TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
8839                         cmd_show, "show");
8840 cmdline_parse_token_string_t cmd_show_set_raw_cmd_what =
8841         TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
8842                         cmd_what, "raw_encap#raw_decap");
8843 cmdline_parse_token_num_t cmd_show_set_raw_cmd_index =
8844         TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result,
8845                         cmd_index, RTE_UINT16);
8846 cmdline_parse_token_string_t cmd_show_set_raw_cmd_all =
8847         TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
8848                         cmd_all, "all");
8849 cmdline_parse_inst_t cmd_show_set_raw = {
8850         .f = cmd_show_set_raw_parsed,
8851         .data = NULL,
8852         .help_str = "show <raw_encap|raw_decap> <index>",
8853         .tokens = {
8854                 (void *)&cmd_show_set_raw_cmd_show,
8855                 (void *)&cmd_show_set_raw_cmd_what,
8856                 (void *)&cmd_show_set_raw_cmd_index,
8857                 NULL,
8858         },
8859 };
8860 cmdline_parse_inst_t cmd_show_set_raw_all = {
8861         .f = cmd_show_set_raw_parsed,
8862         .data = NULL,
8863         .help_str = "show <raw_encap|raw_decap> all",
8864         .tokens = {
8865                 (void *)&cmd_show_set_raw_cmd_show,
8866                 (void *)&cmd_show_set_raw_cmd_what,
8867                 (void *)&cmd_show_set_raw_cmd_all,
8868                 NULL,
8869         },
8870 };