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