[l2l3 stack] implements new arp state machine & arp buffering
[samplevnf.git] / common / VIL / pipeline_arpicmp / pipeline_arpicmp.c
1 /*
2 // Copyright (c) 2017 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include <cmdline_parse.h>
18 #include <cmdline_parse_num.h>
19 #include <cmdline_parse_string.h>
20 #include <cmdline_parse_ipaddr.h>
21 #include <cmdline_parse_etheraddr.h>
22
23 #include "app.h"
24 #include "pipeline_common_fe.h"
25 #include "pipeline_arpicmp_be.h"
26 #include "pipeline_arpicmp.h"
27 #include "vnf_common.h"
28
29 #include "app.h"
30 #include "vnf_common.h"
31 #ifndef VNF_ACL
32 #include "lib_arp.h"
33 #endif
34
35 #include <rte_ip.h>
36 #include <rte_udp.h>
37 #include <rte_string_fns.h>
38
39 uint16_t verbose_level = 1; /**< should be Silent by default. */
40 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
41
42 /*
43  * Work-around of a compilation error with ICC on invocations of the
44  * rte_be_to_cpu_16() function.
45  */
46 #ifdef __GCC__
47 #define RTE_BE_TO_CPU_16(be_16_v)  rte_be_to_cpu_16((be_16_v))
48 #define RTE_CPU_TO_BE_16(cpu_16_v) rte_cpu_to_be_16((cpu_16_v))
49 #else
50 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
51 #define RTE_BE_TO_CPU_16(be_16_v)  (be_16_v)
52 #define RTE_CPU_TO_BE_16(cpu_16_v) (cpu_16_v)
53 #else
54 #define RTE_BE_TO_CPU_16(be_16_v) \
55         ((uint16_t) ((((be_16_v) & 0xFF) << 8) | ((be_16_v) >> 8)))
56 #define RTE_CPU_TO_BE_16(cpu_16_v) \
57         ((uint16_t) ((((cpu_16_v) & 0xFF) << 8) | ((cpu_16_v) >> 8)))
58 #endif
59 #endif
60
61 /*
62  * arp add
63  */
64
65 struct cmd_arp_add_result {
66         cmdline_fixed_string_t p_string;
67         uint32_t p;
68         cmdline_fixed_string_t arpadd_string;
69         uint32_t port_id;
70         cmdline_ipaddr_t ip;
71         struct ether_addr macaddr;
72
73 };
74
75 static void
76 cmd_arp_add_parsed(void *parsed_result,
77                          __rte_unused struct cmdline *cl, __rte_unused void *data)
78 {
79         struct cmd_arp_add_result *params = parsed_result;
80         uint8_t ipv6[16];
81
82         #if 0
83         struct pipeline_arp_icmp_arp_key key;
84         key.type = PIPELINE_ARP_ICMP_ARP_IPV4;
85         key.key.ipv4.port_id = params->port_id;
86         key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
87         populate_arp_entry(&req->macaddr, rte_bswap32(req->key.key.ipv4.ip),
88                 req->key.key.ipv4.port_id);
89         #endif
90         if (params->ip.family == AF_INET) {
91                 populate_arp_entry(&params->macaddr,
92                                          rte_cpu_to_be_32(params->ip.addr.
93                                                                 ipv4.s_addr),
94                                          params->port_id
95                                          , STATIC_ARP
96                                 );
97         } else {
98                 memcpy(ipv6, params->ip.addr.ipv6.s6_addr, 16);
99                 populate_nd_entry(&params->macaddr, ipv6, params->port_id
100                                 #ifndef VNF_ACL
101                                 , STATIC_ND
102                                 #endif
103                                 );
104         }
105 }
106
107 static cmdline_parse_token_string_t cmd_arp_add_p_string =
108 TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, p_string,
109                          "p");
110
111 static cmdline_parse_token_num_t cmd_arp_add_p =
112 TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, p, UINT32);
113
114 static cmdline_parse_token_string_t cmd_arp_add_arp_string =
115 TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, arpadd_string, "arpadd");
116
117 static cmdline_parse_token_num_t cmd_arp_add_port_id =
118 TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, port_id, UINT32);
119
120 static cmdline_parse_token_ipaddr_t cmd_arp_add_ip =
121 TOKEN_IPADDR_INITIALIZER(struct cmd_arp_add_result, ip);
122
123 static cmdline_parse_token_etheraddr_t cmd_arp_add_macaddr =
124 TOKEN_ETHERADDR_INITIALIZER(struct cmd_arp_add_result, macaddr);
125
126 static cmdline_parse_inst_t cmd_arp_add = {
127         .f = cmd_arp_add_parsed,
128         .data = NULL,
129         .help_str = "ARP add",
130         .tokens = {
131                          (void *)&cmd_arp_add_p_string,
132                          (void *)&cmd_arp_add_p,
133                          (void *)&cmd_arp_add_arp_string,
134                          (void *)&cmd_arp_add_port_id,
135                          (void *)&cmd_arp_add_ip,
136                          (void *)&cmd_arp_add_macaddr,
137                          NULL,
138                          },
139 };
140
141 /*
142  * arp del
143  */
144
145 struct cmd_arp_del_result {
146         cmdline_fixed_string_t p_string;
147         uint32_t p;
148         cmdline_fixed_string_t arp_string;
149         uint32_t port_id;
150         cmdline_ipaddr_t ip;
151 };
152
153 static void
154 cmd_arp_del_parsed(void *parsed_result,
155                          __rte_unused struct cmdline *cl, __rte_unused void *data)
156 {
157         struct cmd_arp_del_result *params = parsed_result;
158         uint8_t ipv6[16];
159
160         #if 0
161         struct pipeline_arp_icmp_arp_key key;
162         key.type = PIPELINE_ARP_ICMP_ARP_IPV4;
163         key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
164         key.key.ipv4.port_id = params->port_id;
165         remove_arp_entry(rte_bswap32(req->key.key.ipv4.ip),
166                 req->key.key.ipv4.port_id);
167         #endif
168         struct arp_key_ipv4 arp_key;
169         arp_key.port_id = params->port_id;
170         arp_key.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
171         arp_key.filler1 = 0;
172         arp_key.filler2 = 0;
173         arp_key.filler3 = 0;
174
175         struct arp_entry_data *new_arp_data = retrieve_arp_entry(arp_key, STATIC_ARP);
176
177         if (params->ip.family == AF_INET) {
178                 remove_arp_entry(new_arp_data, &arp_key);
179         } else {
180                 memcpy(ipv6, params->ip.addr.ipv6.s6_addr, 16);
181                 remove_nd_entry_ipv6(ipv6, params->port_id);
182         }
183 }
184
185 static cmdline_parse_token_string_t cmd_arp_del_p_string =
186 TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, p_string,
187                          "p");
188
189 static cmdline_parse_token_num_t cmd_arp_del_p =
190 TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, p, UINT32);
191
192 static cmdline_parse_token_string_t cmd_arp_del_arp_string =
193 TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "arpdel");
194
195 static cmdline_parse_token_num_t cmd_arp_del_port_id =
196 TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, port_id, UINT32);
197
198 static cmdline_parse_token_ipaddr_t cmd_arp_del_ip =
199 TOKEN_IPADDR_INITIALIZER(struct cmd_arp_del_result, ip);
200
201 static cmdline_parse_inst_t cmd_arp_del = {
202         .f = cmd_arp_del_parsed,
203         .data = NULL,
204         .help_str = "ARP delete",
205         .tokens = {
206                          (void *)&cmd_arp_del_p_string,
207                          (void *)&cmd_arp_del_p,
208                          (void *)&cmd_arp_del_arp_string,
209                          (void *)&cmd_arp_del_port_id,
210                          (void *)&cmd_arp_del_ip,
211                          NULL,
212                          },
213 };
214
215 /*
216  * arp req
217  */
218
219 /*Re-uses delete structures*/
220
221 static void
222 cmd_arp_req_parsed(void *parsed_result,
223                          __rte_unused struct cmdline *cl, __rte_unused void *data)
224 {
225         struct cmd_arp_del_result *params = parsed_result;
226         /*struct app_params *app = data;*/
227
228         struct arp_key_ipv4 key;
229 /*      int status;*/
230
231 /*      key.type = ARP_IPV4;*/
232 /*      key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);*/
233 /*      key.key.ipv4.port_id = params->port_id;*/
234         key.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
235         key.port_id = params->port_id;
236         key.filler1 = 0;
237         key.filler2 = 0;
238         key.filler3 = 0;
239
240         struct arp_entry_data *arp_data = retrieve_arp_entry(key, STATIC_ARP);
241
242         if (arp_data) {
243                 if (ARPICMP_DEBUG)
244                         printf("ARP entry exists for ip 0x%x, port %d\n",
245                                                  params->ip.addr.ipv4.s_addr, params->port_id);
246                 return;
247         }
248         /* else request an arp*/
249         if (ARPICMP_DEBUG)
250                 printf("ARP - requesting arp for ip 0x%x, port %d\n",
251                                          params->ip.addr.ipv4.s_addr, params->port_id);
252
253         #ifdef VNF_ACL
254         request_arp_wrap(params->port_id, params->ip.addr.ipv4.s_addr);
255         #else
256         request_arp(params->port_id, params->ip.addr.ipv4.s_addr);
257         #endif
258         /*give pipeline number too*/
259 }
260
261 static cmdline_parse_token_string_t cmd_arp_req_string =
262 TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "arpreq");
263
264 static cmdline_parse_inst_t cmd_arp_req = {
265         .f = cmd_arp_req_parsed,
266         .data = NULL,
267         .help_str = "ARP request",
268         .tokens = {
269                          (void *)&cmd_arp_del_p_string,
270                          (void *)&cmd_arp_del_p,
271                          (void *)&cmd_arp_req_string,
272                          (void *)&cmd_arp_del_port_id,
273                          (void *)&cmd_arp_del_ip,
274                          NULL,
275                          },
276 };
277
278 /*
279  * arpicmp echo req
280  */
281
282 /*Re-uses delete structures*/
283
284 static void
285 cmd_icmp_echo_req_parsed(void *parsed_result,
286                          __rte_unused struct cmdline *cl,
287                          __rte_unused void *data)
288 {
289         struct cmd_arp_del_result *params = parsed_result;
290
291         if (ARPICMP_DEBUG)
292                 printf("Echo Req Handler ip %x, port %d\n",
293                                          params->ip.addr.ipv4.s_addr, params->port_id);
294
295         request_echo(params->port_id, params->ip.addr.ipv4.s_addr);
296 }
297
298 static cmdline_parse_token_string_t cmd_icmp_echo_req_string =
299 TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "icmpecho");
300
301 static cmdline_parse_inst_t cmd_icmp_echo_req = {
302         .f = cmd_icmp_echo_req_parsed,
303         .data = NULL,
304         .help_str = "ICMP echo request",
305         .tokens = {
306                          (void *)&cmd_arp_del_p_string,
307                          (void *)&cmd_arp_del_p,
308                          (void *)&cmd_icmp_echo_req_string,
309                          (void *)&cmd_arp_del_port_id,
310                          (void *)&cmd_arp_del_ip,
311                          NULL,
312                          },
313 };
314
315 /*
316  * arp ls
317  */
318
319 struct cmd_arp_ls_result {
320         cmdline_fixed_string_t p_string;
321         uint32_t p;
322         cmdline_fixed_string_t arp_string;
323         uint32_t ip_type;
324 };
325
326 static void
327 cmd_arp_ls_parsed(__rte_unused void *parsed_result,
328                         __rte_unused struct cmdline *cl, __rte_unused void *data)
329 {
330         struct cmd_arp_ls_result *params = parsed_result;
331
332         if (!params->ip_type) {
333                 printf("\nARP table ...\n");
334                 printf("-------------\n");
335                 print_arp_table();
336         } else {
337                 printf("\nND IPv6 table:\n");
338                 printf("--------------\n");
339                 print_nd_table();
340         }
341 }
342
343 static cmdline_parse_token_string_t cmd_arp_ls_p_string =
344 TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, p_string,
345                          "p");
346
347 static cmdline_parse_token_num_t cmd_arp_ls_p =
348 TOKEN_NUM_INITIALIZER(struct cmd_arp_ls_result, p, UINT32);
349
350 static cmdline_parse_token_string_t cmd_arp_ls_arp_string =
351 TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, arp_string,
352                          "arpls");
353
354 static cmdline_parse_token_num_t cmd_arp_ls_ip_type =
355 TOKEN_NUM_INITIALIZER(struct cmd_arp_ls_result, ip_type, UINT32);
356
357 static cmdline_parse_inst_t cmd_arp_ls = {
358         .f = cmd_arp_ls_parsed,
359         .data = NULL,
360         .help_str = "ARP list",
361         .tokens = {
362                          (void *)&cmd_arp_ls_p_string,
363                          (void *)&cmd_arp_ls_p,
364                          (void *)&cmd_arp_ls_arp_string,
365                          (void *)&cmd_arp_ls_ip_type,
366                          NULL,
367                          },
368 };
369
370 /*
371  * show ports info
372  */
373
374 struct cmd_show_ports_info_result {
375         cmdline_fixed_string_t p_string;
376         uint32_t p;
377         cmdline_fixed_string_t arp_string;
378 };
379
380 static void
381 cmd_show_ports_info_parsed(__rte_unused void *parsed_result,
382                                  __rte_unused struct cmdline *cl,
383                                  __rte_unused void *data)
384 {
385         show_ports_info();
386 }
387
388 static cmdline_parse_token_string_t cmd_show_ports_info_string =
389 TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, arp_string,
390                          "showPortsInfo");
391
392 static cmdline_parse_inst_t cmd_show_ports_info = {
393         .f = cmd_show_ports_info_parsed,
394         .data = NULL,
395         .help_str = "show ports info",
396         .tokens = {
397                          (void *)&cmd_arp_ls_p_string,
398                          (void *)&cmd_arp_ls_p,
399                          (void *)&cmd_show_ports_info_string,
400                          NULL,
401                          },
402 };
403
404 #ifndef VNF_ACL
405 struct cmd_arp_dbg_result {
406         cmdline_fixed_string_t arpdbg_str;
407         uint32_t flag;
408 };
409
410 cmdline_parse_token_string_t cmd_arp_dbg_string =
411         TOKEN_STRING_INITIALIZER(struct cmd_arp_dbg_result, arpdbg_str,
412                 "arpdbg");
413 cmdline_parse_token_num_t cmd_arp_dbg_flag =
414         TOKEN_NUM_INITIALIZER(struct cmd_arp_dbg_result, flag, UINT32);
415
416 static void
417 cmd_arp_dbg_parse(
418                 void *parsed_result,
419                 __attribute__((unused)) struct cmdline *cl,
420                 __rte_unused void *data)
421 {
422         struct cmd_arp_dbg_result *params = parsed_result;
423         if(params)
424         {
425                 set_arpdebug(params->flag);
426         }
427         else
428         {
429                 printf("%s: Params is NULL",__FUNCTION__);
430         }
431 }
432
433 cmdline_parse_inst_t cmd_arp_dbg = {
434         .f = cmd_arp_dbg_parse,
435         .data = NULL,
436         .help_str = "Turn on/off(1/0) arp debug",
437         .tokens = {
438                 (void *)&cmd_arp_dbg_string,
439                 (void *)&cmd_arp_dbg_flag,
440                 NULL,
441         },
442 };
443
444 struct cmd_arp_timer_result {
445         cmdline_fixed_string_t arptimer_str;
446         uint32_t arptimer_val;
447 };
448
449 cmdline_parse_token_string_t cmd_arp_timer_string =
450         TOKEN_STRING_INITIALIZER(struct cmd_arp_timer_result, arptimer_str,
451                 "arptimerexpiry");
452 cmdline_parse_token_num_t cmd_arp_timer_val =
453         TOKEN_NUM_INITIALIZER(struct cmd_arp_timer_result, arptimer_val, UINT32);
454
455 static void
456 cmd_arp_timer_parse(
457                 void *parsed_result,
458                 __attribute__((unused)) struct cmdline *cl,
459                 __rte_unused void *data)
460 {
461         struct cmd_arp_timer_result *params = parsed_result;
462         if(params)
463         {
464                 set_arptimeout(params->arptimer_val);
465         }
466         else
467         {
468                 printf("%s: Params is NULL",__FUNCTION__);
469         }
470 }
471
472 cmdline_parse_inst_t cmd_arp_timer = {
473         .f = cmd_arp_timer_parse,
474         .data = NULL,
475         .help_str = "Timer expiry val by def 10 sec",
476         .tokens = {
477                 (void *)&cmd_arp_timer_string,
478                 (void *)&cmd_arp_timer_val,
479                 NULL,
480         },
481 };
482 #endif
483
484 /*
485  * Forwarding of packets in I/O mode.
486  * Forward packets "as-is".
487  * This is the fastest possible forwarding operation, as it does not access
488  * to packets data.
489  */
490         static void
491 pkt_burst_io_forward(struct fwd_stream *fs)
492 {
493         struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
494         uint16_t nb_rx;
495         uint16_t nb_tx;
496
497         #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
498         uint64_t start_tsc;
499         uint64_t end_tsc;
500         uint64_t core_cycles;
501         #endif
502
503         #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
504         start_tsc = rte_rdtsc();
505         #endif
506
507         /*
508          * Receive a burst of packets and forward them.
509          */
510         nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
511                         nb_pkt_per_burst);
512         if (unlikely(nb_rx == 0))
513                 return;
514
515         #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
516         fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
517         #endif
518
519         fs->rx_packets += nb_rx;
520         nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
521         fs->tx_packets += nb_tx;
522
523         #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
524         fs->tx_burst_stats.pkt_burst_spread[nb_tx]++;
525         #endif
526
527         if (unlikely(nb_tx < nb_rx)) {
528                 fs->fwd_dropped += (nb_rx - nb_tx);
529                 do {
530                         rte_pktmbuf_free(pkts_burst[nb_tx]);
531                 } while (++nb_tx < nb_rx);
532         }
533
534         #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
535         end_tsc = rte_rdtsc();
536         core_cycles = (end_tsc - start_tsc);
537         fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
538         #endif
539 }
540
541
542 struct fwd_engine io_fwd_engine = {
543         .fwd_mode_name  = "io",
544         .port_fwd_begin = NULL,
545         .port_fwd_end   = NULL,
546         .packet_fwd     = pkt_burst_io_forward,
547 };
548
549 static inline void print_ether_addr(
550         const char *what,
551         struct ether_addr *eth_addr)
552 {
553         char buf[ETHER_ADDR_FMT_SIZE];
554         ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, eth_addr);
555         printf("%s%s", what, buf);
556 }
557
558 /*
559  * Received a burst of packets.
560  */
561         static void
562 pkt_burst_receive(struct fwd_stream *fs)
563 {
564         struct rte_mbuf  *pkts_burst[MAX_PKT_BURST];
565         struct rte_mbuf  *mb;
566         struct ether_hdr *eth_hdr;
567         uint16_t eth_type;
568         uint64_t ol_flags;
569         uint16_t nb_rx;
570         uint16_t i, packet_type;
571         uint16_t is_encapsulation;
572
573         #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
574         uint64_t start_tsc;
575         uint64_t end_tsc;
576         uint64_t core_cycles;
577         #endif
578
579         #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
580         start_tsc = rte_rdtsc();
581         #endif
582
583         /*
584          * Receive a burst of packets.
585          */
586         nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
587                         nb_pkt_per_burst);
588         if (unlikely(nb_rx == 0))
589                 return;
590
591         #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
592         fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
593         #endif
594
595         fs->rx_packets += nb_rx;
596
597         /*
598          * Dump each received packet if verbose_level > 0.
599          */
600         if (verbose_level > 0)
601                 printf("port %u/queue %u: received %u packets\n",
602                                 (unsigned int) fs->rx_port,
603                                 (unsigned int) fs->rx_queue,
604                                 (unsigned int) nb_rx);
605         for (i = 0; i < nb_rx; i++) {
606                 mb = pkts_burst[i];
607                 if (verbose_level == 0) {
608                         rte_pktmbuf_free(mb);
609                         continue;
610                 }
611                 eth_hdr = rte_pktmbuf_mtod(mb, struct ether_hdr *);
612                 eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
613                 ol_flags = mb->ol_flags;
614                 packet_type = mb->packet_type;
615                 is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
616
617                 print_ether_addr("  src=", &eth_hdr->s_addr);
618                 print_ether_addr(" - dst=", &eth_hdr->d_addr);
619                 printf(" - type=0x%04x - length=%u - nb_segs=%d",
620                                 eth_type, (unsigned int) mb->pkt_len,
621                                 (int)mb->nb_segs);
622                 if (ol_flags & PKT_RX_RSS_HASH) {
623                         printf(" - RSS hash=0x%x", (unsigned int)
624                                 mb->hash.rss);
625                         printf(" - RSS queue=0x%x", (unsigned int)
626                                 fs->rx_queue);
627                 } else if (ol_flags & PKT_RX_FDIR) {
628                         printf(" - FDIR matched ");
629                         if (ol_flags & PKT_RX_FDIR_ID)
630                                 printf("ID=0x%x",
631                                                 mb->hash.fdir.hi);
632                         else if (ol_flags & PKT_RX_FDIR_FLX)
633                                 printf("flex bytes=0x%08x %08x",
634                                         mb->hash.fdir.hi, mb->hash.fdir.lo);
635                         else
636                                 printf("hash=0x%x ID=0x%x ",
637                                         mb->hash.fdir.hash, mb->hash.fdir.id);
638                 }
639                 if (ol_flags & PKT_RX_VLAN_PKT)
640                         printf(" - VLAN tci=0x%x", mb->vlan_tci);
641                 if (ol_flags & PKT_RX_QINQ_PKT)
642                         printf(" - QinQ VLAN tci=0x%x, VLAN tci outer=0x%x",
643                                         mb->vlan_tci, mb->vlan_tci_outer);
644                 if (mb->packet_type) {
645                         uint32_t ptype;
646
647                         /* (outer) L2 packet type */
648                         ptype = mb->packet_type & RTE_PTYPE_L2_MASK;
649                         switch (ptype) {
650                         case RTE_PTYPE_L2_ETHER:
651                                 printf(" - (outer) L2 type: ETHER");
652                                 break;
653                         case RTE_PTYPE_L2_ETHER_TIMESYNC:
654                                 printf(" - (outer) L2 type: ETHER_Timesync");
655                                 break;
656                         case RTE_PTYPE_L2_ETHER_ARP:
657                                 printf(" - (outer) L2 type: ETHER_ARP");
658                                 break;
659                         case RTE_PTYPE_L2_ETHER_LLDP:
660                                 printf(" - (outer) L2 type: ETHER_LLDP");
661                                 break;
662                         default:
663                                 printf(" - (outer) L2 type: Unknown");
664                                 break;
665                         }
666
667                         /* (outer) L3 packet type */
668                         ptype = mb->packet_type & RTE_PTYPE_L3_MASK;
669                         switch (ptype) {
670                         case RTE_PTYPE_L3_IPV4:
671                                 printf(" - (outer) L3 type: IPV4");
672                                 break;
673                         case RTE_PTYPE_L3_IPV4_EXT:
674                                 printf(" - (outer) L3 type: IPV4_EXT");
675                                 break;
676                         case RTE_PTYPE_L3_IPV6:
677                                 printf(" - (outer) L3 type: IPV6");
678                                 break;
679                         case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
680                                 printf(" - (outer) L3 type: IPV4_EXT_UNKNOWN");
681                                 break;
682                         case RTE_PTYPE_L3_IPV6_EXT:
683                                 printf(" - (outer) L3 type: IPV6_EXT");
684                                 break;
685                         case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
686                                 printf(" - (outer) L3 type: IPV6_EXT_UNKNOWN");
687                                 break;
688                         default:
689                                 printf(" - (outer) L3 type: Unknown");
690                                 break;
691                         }
692
693                         /* (outer) L4 packet type */
694                         ptype = mb->packet_type & RTE_PTYPE_L4_MASK;
695                         switch (ptype) {
696                         case RTE_PTYPE_L4_TCP:
697                                 printf(" - (outer) L4 type: TCP");
698                                 break;
699                         case RTE_PTYPE_L4_UDP:
700                                 printf(" - (outer) L4 type: UDP");
701                                 break;
702                         case RTE_PTYPE_L4_FRAG:
703                                 printf(" - (outer) L4 type: L4_FRAG");
704                                 break;
705                         case RTE_PTYPE_L4_SCTP:
706                                 printf(" - (outer) L4 type: SCTP");
707                                 break;
708                         case RTE_PTYPE_L4_ICMP:
709                                 printf(" - (outer) L4 type: ICMP");
710                                 break;
711                         case RTE_PTYPE_L4_NONFRAG:
712                                 printf(" - (outer) L4 type: L4_NONFRAG");
713                                 break;
714                         default:
715                                 printf(" - (outer) L4 type: Unknown");
716                                 break;
717                         }
718
719                         /* packet tunnel type */
720                         ptype = mb->packet_type & RTE_PTYPE_TUNNEL_MASK;
721                         switch (ptype) {
722                         case RTE_PTYPE_TUNNEL_IP:
723                                 printf(" - Tunnel type: IP");
724                                 break;
725                         case RTE_PTYPE_TUNNEL_GRE:
726                                 printf(" - Tunnel type: GRE");
727                                 break;
728                         case RTE_PTYPE_TUNNEL_VXLAN:
729                                 printf(" - Tunnel type: VXLAN");
730                                 break;
731                         case RTE_PTYPE_TUNNEL_NVGRE:
732                                 printf(" - Tunnel type: NVGRE");
733                                 break;
734                         case RTE_PTYPE_TUNNEL_GENEVE:
735                                 printf(" - Tunnel type: GENEVE");
736                                 break;
737                         case RTE_PTYPE_TUNNEL_GRENAT:
738                                 printf(" - Tunnel type: GRENAT");
739                                 break;
740                         default:
741                                 printf(" - Tunnel type: Unknown");
742                                 break;
743                         }
744
745                         /* inner L2 packet type */
746                         ptype = mb->packet_type & RTE_PTYPE_INNER_L2_MASK;
747                         switch (ptype) {
748                         case RTE_PTYPE_INNER_L2_ETHER:
749                                 printf(" - Inner L2 type: ETHER");
750                                 break;
751                         case RTE_PTYPE_INNER_L2_ETHER_VLAN:
752                                 printf(" - Inner L2 type: ETHER_VLAN");
753                                 break;
754                         default:
755                                 printf(" - Inner L2 type: Unknown");
756                                 break;
757                         }
758                         /* inner L3 packet type */
759                         ptype = mb->packet_type & RTE_PTYPE_INNER_L3_MASK;
760                         switch (ptype) {
761                         case RTE_PTYPE_INNER_L3_IPV4:
762                                 printf(" - Inner L3 type: IPV4");
763                                 break;
764                         case RTE_PTYPE_INNER_L3_IPV4_EXT:
765                                 printf(" - Inner L3 type: IPV4_EXT");
766                                 break;
767                         case RTE_PTYPE_INNER_L3_IPV6:
768                                 printf(" - Inner L3 type: IPV6");
769                                 break;
770                         case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
771                                 printf(" - Inner L3 type: "
772                                         "IPV4_EXT_UNKNOWN");
773                                 break;
774                         case RTE_PTYPE_INNER_L3_IPV6_EXT:
775                                         printf(" - Inner L3 type: IPV6_EXT");
776                                 break;
777                         case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
778                                 printf(" - Inner L3 type: "
779                                         "IPV6_EXT_UNKNOWN");
780                                 break;
781                         default:
782                                 printf(" - Inner L3 type: Unknown");
783                                 break;
784                         }
785
786                         /* inner L4 packet type */
787                         ptype = mb->packet_type & RTE_PTYPE_INNER_L4_MASK;
788                         switch (ptype) {
789                         case RTE_PTYPE_INNER_L4_TCP:
790                                 printf(" - Inner L4 type: TCP");
791                                 break;
792                         case RTE_PTYPE_INNER_L4_UDP:
793                                 printf(" - Inner L4 type: UDP");
794                                 break;
795                         case RTE_PTYPE_INNER_L4_FRAG:
796                                 printf(" - Inner L4 type: L4_FRAG");
797                                 break;
798                         case RTE_PTYPE_INNER_L4_SCTP:
799                                 printf(" - Inner L4 type: SCTP");
800                                 break;
801                         case RTE_PTYPE_INNER_L4_ICMP:
802                                 printf(" - Inner L4 type: ICMP");
803                                 break;
804                         case RTE_PTYPE_INNER_L4_NONFRAG:
805                                 printf(" - Inner L4 type: L4_NONFRAG");
806                                 break;
807                         default:
808                                 printf(" - Inner L4 type: Unknown");
809                                 break;
810                         }
811                         printf("\n");
812                 } else
813                         printf("Unknown packet type\n");
814                 if (is_encapsulation) {
815                         struct ipv4_hdr *ipv4_hdr;
816                         struct ipv6_hdr *ipv6_hdr;
817                         struct udp_hdr *udp_hdr;
818                         uint8_t l2_len;
819                         uint8_t l3_len;
820                         uint8_t l4_len;
821                         uint8_t l4_proto;
822                         struct  vxlan_hdr *vxlan_hdr;
823
824                         l2_len  = sizeof(struct ether_hdr);
825
826                         /* Do not support ipv4 option field */
827                         if (RTE_ETH_IS_IPV4_HDR(packet_type)) {
828                                 l3_len = sizeof(struct ipv4_hdr);
829                                 ipv4_hdr = rte_pktmbuf_mtod_offset(mb,
830                                                 struct ipv4_hdr *,
831                                                 l2_len);
832                                 l4_proto = ipv4_hdr->next_proto_id;
833                         } else {
834                                 l3_len = sizeof(struct ipv6_hdr);
835                                 ipv6_hdr = rte_pktmbuf_mtod_offset(mb,
836                                                 struct ipv6_hdr *,
837                                                 l2_len);
838                                 l4_proto = ipv6_hdr->proto;
839                         }
840                         if (l4_proto == IPPROTO_UDP) {
841                                 udp_hdr = rte_pktmbuf_mtod_offset(mb,
842                                                 struct udp_hdr *,
843                                                 l2_len + l3_len);
844                                 l4_len = sizeof(struct udp_hdr);
845                                 vxlan_hdr = rte_pktmbuf_mtod_offset(mb,
846                                                 struct vxlan_hdr *,
847                                                 l2_len + l3_len + l4_len);
848
849                                 printf(" - VXLAN packet: packet type =%d, "
850                                         "Destination UDP port =%d, VNI = %d",
851                                         packet_type,
852                                         RTE_BE_TO_CPU_16(udp_hdr->dst_port),
853                                         rte_be_to_cpu_32(
854                                                 vxlan_hdr->vx_vni) >> 8);
855                         }
856                 }
857                 printf(" - Receive queue=0x%x", (unsigned int) fs->rx_queue);
858                 printf("\n");
859                 if (ol_flags != 0) {
860                         unsigned int rxf;
861                         const char *name;
862
863                         for (rxf = 0; rxf < sizeof(mb->ol_flags) * 8; rxf++) {
864                                 if ((ol_flags & (1ULL << rxf)) == 0)
865                                         continue;
866                                 name = rte_get_rx_ol_flag_name(1ULL << rxf);
867                                 if (name == NULL)
868                                         continue;
869                                 printf("  %s\n", name);
870                         }
871                 }
872                 rte_pktmbuf_free(mb);
873         }
874
875         #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
876         end_tsc = rte_rdtsc();
877         core_cycles = (end_tsc - start_tsc);
878         fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
879         #endif
880 }
881
882 struct fwd_engine rx_only_engine = {
883         .fwd_mode_name  = "rxonly",
884         .port_fwd_begin = NULL,
885         .port_fwd_end   = NULL,
886         .packet_fwd     = pkt_burst_receive,
887 };
888
889 /* *** SET FORWARDING MODE *** */
890 struct cmd_set_fwd_mode_result {
891         cmdline_fixed_string_t set;
892         cmdline_fixed_string_t fwd;
893         cmdline_fixed_string_t mode;
894 };
895
896 /*
897  * Forwarding engines.
898  */
899 struct fwd_engine *fwd_engines[] = {
900         &io_fwd_engine,
901         #if 0
902         &mac_fwd_engine,
903         &mac_retry_fwd_engine,
904         &mac_swap_engine,
905         &flow_gen_engine,
906         #endif
907         &rx_only_engine,
908         #if 0
909         &tx_only_engine,
910         &csum_fwd_engine,
911         &icmp_echo_engine,
912         #ifdef RTE_LIBRTE_IEEE1588
913         &ieee1588_fwd_engine,
914         #endif
915         #endif
916         NULL,
917 };
918
919 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
920
921 void set_pkt_forwarding_mode(const char *fwd_mode_name)
922 {
923         struct fwd_engine *fwd_eng;
924         unsigned int i;
925
926         i = 0;
927         while ((fwd_eng = fwd_engines[i]) != NULL) {
928                 if (!strcmp(fwd_eng->fwd_mode_name, fwd_mode_name)) {
929                         printf("Set %s packet forwarding mode\n",
930                                         fwd_mode_name);
931                         cur_fwd_eng = fwd_eng;
932                         return;
933                 }
934                 i++;
935         }
936         printf("Invalid %s packet forwarding mode\n", fwd_mode_name);
937 }
938
939 static void cmd_set_fwd_mode_parsed(void *parsed_result,
940                 __attribute__((unused)) struct cmdline *cl,
941                 __attribute__((unused)) void *data)
942 {
943         struct cmd_set_fwd_mode_result *res = parsed_result;
944
945         set_pkt_forwarding_mode(res->mode);
946 }
947
948 cmdline_parse_token_string_t cmd_setfwd_set =
949 TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, set, "set");
950 cmdline_parse_token_string_t cmd_setfwd_fwd =
951 TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, fwd, "fwd");
952 cmdline_parse_token_string_t cmd_setfwd_mode =
953 TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, mode,
954                 "rxonly" /* defined at init */);
955
956 cmdline_parse_inst_t cmd_set_fwd_mode = {
957         .f = cmd_set_fwd_mode_parsed,
958         .data = NULL,
959         .help_str = NULL, /* defined at init */
960         .tokens = {
961                 (void *)&cmd_setfwd_set,
962                 (void *)&cmd_setfwd_fwd,
963                 (void *)&cmd_setfwd_mode,
964                 NULL,
965         },
966 };
967
968 #if 1
969
970 static uint16_t
971 str2flowtype(char *string)
972 {
973         uint8_t i = 0;
974         static const struct {
975         char str[32];
976         uint16_t type;
977         } flowtype_str[] = {
978                 {"raw", RTE_ETH_FLOW_RAW},
979                 {"ipv4", RTE_ETH_FLOW_IPV4},
980                 {"ipv4-frag", RTE_ETH_FLOW_FRAG_IPV4},
981                 {"ipv4-tcp", RTE_ETH_FLOW_NONFRAG_IPV4_TCP},
982                 {"ipv4-udp", RTE_ETH_FLOW_NONFRAG_IPV4_UDP},
983                 {"ipv4-sctp", RTE_ETH_FLOW_NONFRAG_IPV4_SCTP},
984                 {"ipv4-other", RTE_ETH_FLOW_NONFRAG_IPV4_OTHER},
985                 {"ipv6", RTE_ETH_FLOW_IPV6},
986                 {"ipv6-frag", RTE_ETH_FLOW_FRAG_IPV6},
987                 {"ipv6-tcp", RTE_ETH_FLOW_NONFRAG_IPV6_TCP},
988                 {"ipv6-udp", RTE_ETH_FLOW_NONFRAG_IPV6_UDP},
989                 {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP},
990                 {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER},
991                 {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD},
992         };
993
994         for (i = 0; i < RTE_DIM(flowtype_str); i++) {
995                 if (!strcmp(flowtype_str[i].str, string))
996                         return flowtype_str[i].type;
997         }
998         return RTE_ETH_FLOW_UNKNOWN;
999 }
1000
1001 static inline int
1002 parse_flexbytes(const char *q_arg, uint8_t *flexbytes, uint16_t max_num)
1003 {
1004         char s[256];
1005         const char *p, *p0 = q_arg;
1006         char *end;
1007         unsigned long int_fld;
1008         char *str_fld[max_num];
1009         int i;
1010         unsigned int size;
1011         int ret = -1;
1012
1013         p = strchr(p0, '(');
1014         if (p == NULL)
1015                 return -1;
1016         ++p;
1017         p0 = strchr(p, ')');
1018         if (p0 == NULL)
1019                 return -1;
1020
1021         size = p0 - p;
1022         if (size >= sizeof(s))
1023                 return -1;
1024
1025         snprintf(s, sizeof(s), "%.*s", size, p);
1026         ret = rte_strsplit(s, sizeof(s), str_fld, max_num, ',');
1027         if (ret < 0 || ret > max_num)
1028                 return -1;
1029         for (i = 0; i < ret; i++) {
1030                 errno = 0;
1031                 int_fld = strtoul(str_fld[i], &end, 0);
1032                 if (errno != 0 || *end != '\0' || int_fld > UINT8_MAX)
1033                         return -1;
1034                 flexbytes[i] = (uint8_t)int_fld;
1035         }
1036         return ret;
1037 }
1038
1039 /* *** deal with flow director filter *** */
1040 struct cmd_flow_director_result {
1041         cmdline_fixed_string_t flow_director_filter;
1042         uint8_t port_id;
1043         cmdline_fixed_string_t mode;
1044         cmdline_fixed_string_t mode_value;
1045         cmdline_fixed_string_t ops;
1046         cmdline_fixed_string_t flow;
1047         cmdline_fixed_string_t flow_type;
1048         cmdline_fixed_string_t ether;
1049         uint16_t ether_type;
1050         cmdline_fixed_string_t src;
1051         cmdline_ipaddr_t ip_src;
1052         uint16_t port_src;
1053         cmdline_fixed_string_t dst;
1054         cmdline_ipaddr_t ip_dst;
1055         uint16_t port_dst;
1056         cmdline_fixed_string_t verify_tag;
1057         uint32_t verify_tag_value;
1058         cmdline_ipaddr_t tos;
1059         uint8_t tos_value;
1060         cmdline_ipaddr_t proto;
1061         uint8_t proto_value;
1062         cmdline_ipaddr_t ttl;
1063         uint8_t ttl_value;
1064         cmdline_fixed_string_t vlan;
1065         uint16_t vlan_value;
1066         cmdline_fixed_string_t flexbytes;
1067         cmdline_fixed_string_t flexbytes_value;
1068         cmdline_fixed_string_t pf_vf;
1069         cmdline_fixed_string_t drop;
1070         cmdline_fixed_string_t queue;
1071         uint16_t  queue_id;
1072         cmdline_fixed_string_t fd_id;
1073         uint32_t  fd_id_value;
1074         cmdline_fixed_string_t mac;
1075         struct ether_addr mac_addr;
1076         cmdline_fixed_string_t tunnel;
1077         cmdline_fixed_string_t tunnel_type;
1078         cmdline_fixed_string_t tunnel_id;
1079         uint32_t tunnel_id_value;
1080 };
1081
1082 static void
1083 cmd_flow_director_filter_parsed(void *parsed_result,
1084                 __attribute__((unused)) struct cmdline *cl,
1085                 __attribute__((unused)) void *data)
1086 {
1087         struct cmd_flow_director_result *res = parsed_result;
1088         struct rte_eth_fdir_filter entry;
1089         uint8_t flexbytes[RTE_ETH_FDIR_MAX_FLEXLEN];
1090         char *end;
1091         unsigned long vf_id;
1092         int ret = 0;
1093
1094         if (enable_hwlb) {
1095                 printf("Hash Filter is already Defined !\n");
1096                 printf("Please undefine HWLD flag and define "
1097                         "FDIR_FILTER flag\n");
1098         return;
1099         }
1100
1101         ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_FDIR);
1102         if (ret < 0) {
1103                 printf("flow director is not supported on port %u.\n",
1104                                 res->port_id);
1105                 return;
1106         }
1107         memset(flexbytes, 0, sizeof(flexbytes));
1108         memset(&entry, 0, sizeof(struct rte_eth_fdir_filter));
1109 #if 0
1110         if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
1111                 if (strcmp(res->mode_value, "MAC-VLAN")) {
1112                         printf("Please set mode to MAC-VLAN.\n");
1113                         return;
1114                 }
1115         } else if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_TUNNEL) {
1116                 if (strcmp(res->mode_value, "Tunnel")) {
1117                         printf("Please set mode to Tunnel.\n");
1118                         return;
1119                 }
1120         } else {
1121                 if (strcmp(res->mode_value, "IP")) {
1122                         printf("Please set mode to IP.\n");
1123                         return;
1124                 }
1125 #endif
1126         {
1127                 entry.input.flow_type = str2flowtype(res->flow_type);
1128         }
1129
1130         ret = parse_flexbytes(res->flexbytes_value,
1131                         flexbytes,
1132                         RTE_ETH_FDIR_MAX_FLEXLEN);
1133         if (ret < 0) {
1134                 printf("error: Cannot parse flexbytes input.\n");
1135                 return;
1136         }
1137
1138         switch (entry.input.flow_type) {
1139         case RTE_ETH_FLOW_FRAG_IPV4:
1140         case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
1141                 entry.input.flow.ip4_flow.proto = res->proto_value;
1142         case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
1143         case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
1144                 IPV4_ADDR_TO_UINT(res->ip_dst,
1145                                 entry.input.flow.ip4_flow.dst_ip);
1146                 IPV4_ADDR_TO_UINT(res->ip_src,
1147                         entry.input.flow.ip4_flow.src_ip);
1148                         entry.input.flow.ip4_flow.tos = res->tos_value;
1149                         entry.input.flow.ip4_flow.ttl = res->ttl_value;
1150                         /* need convert to big endian. */
1151                         entry.input.flow.udp4_flow.dst_port =
1152                                 rte_cpu_to_be_16(res->port_dst);
1153                         entry.input.flow.udp4_flow.src_port =
1154                                 rte_cpu_to_be_16(res->port_src);
1155         break;
1156
1157         case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
1158                 IPV4_ADDR_TO_UINT(res->ip_dst,
1159                                 entry.input.flow.sctp4_flow.ip.dst_ip);
1160                 IPV4_ADDR_TO_UINT(res->ip_src,
1161                                 entry.input.flow.sctp4_flow.ip.src_ip);
1162                 entry.input.flow.ip4_flow.tos = res->tos_value;
1163                 entry.input.flow.ip4_flow.ttl = res->ttl_value;
1164                 /* need convert to big endian. */
1165                 entry.input.flow.sctp4_flow.dst_port =
1166                         rte_cpu_to_be_16(res->port_dst);
1167                 entry.input.flow.sctp4_flow.src_port =
1168                         rte_cpu_to_be_16(res->port_src);
1169                 entry.input.flow.sctp4_flow.verify_tag =
1170                         rte_cpu_to_be_32(res->verify_tag_value);
1171         break;
1172
1173         case RTE_ETH_FLOW_FRAG_IPV6:
1174         case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
1175                 entry.input.flow.ipv6_flow.proto = res->proto_value;
1176         case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
1177         case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
1178                 IPV6_ADDR_TO_ARRAY(res->ip_dst,
1179                         entry.input.flow.ipv6_flow.dst_ip);
1180                 IPV6_ADDR_TO_ARRAY(res->ip_src,
1181                         entry.input.flow.ipv6_flow.src_ip);
1182                 entry.input.flow.ipv6_flow.tc = res->tos_value;
1183                 entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
1184                 /* need convert to big endian. */
1185                 entry.input.flow.udp6_flow.dst_port =
1186                         rte_cpu_to_be_16(res->port_dst);
1187                 entry.input.flow.udp6_flow.src_port =
1188                         rte_cpu_to_be_16(res->port_src);
1189         break;
1190
1191         case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
1192                 IPV6_ADDR_TO_ARRAY(res->ip_dst,
1193                         entry.input.flow.sctp6_flow.ip.dst_ip);
1194                 IPV6_ADDR_TO_ARRAY(res->ip_src,
1195                         entry.input.flow.sctp6_flow.ip.src_ip);
1196                 entry.input.flow.ipv6_flow.tc = res->tos_value;
1197                 entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
1198                 /* need convert to big endian. */
1199                 entry.input.flow.sctp6_flow.dst_port =
1200                         rte_cpu_to_be_16(res->port_dst);
1201                 entry.input.flow.sctp6_flow.src_port =
1202                         rte_cpu_to_be_16(res->port_src);
1203                 entry.input.flow.sctp6_flow.verify_tag =
1204                         rte_cpu_to_be_32(res->verify_tag_value);
1205         break;
1206         case RTE_ETH_FLOW_L2_PAYLOAD:
1207                 entry.input.flow.l2_flow.ether_type =
1208                         rte_cpu_to_be_16(res->ether_type);
1209         break;
1210         default:
1211                 break;
1212         }
1213 #if 0
1214         if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_MAC_VLAN)
1215                 (void)rte_memcpy(&entry.input.flow.mac_vlan_flow.mac_addr,
1216                                 &res->mac_addr,
1217                                 sizeof(struct ether_addr));
1218
1219         if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_TUNNEL) {
1220                 (void)rte_memcpy(&entry.input.flow.tunnel_flow.mac_addr,
1221                                 &res->mac_addr,
1222                                 sizeof(struct ether_addr));
1223                 entry.input.flow.tunnel_flow.tunnel_type =
1224                         str2fdir_tunneltype(res->tunnel_type);
1225                 entry.input.flow.tunnel_flow.tunnel_id =
1226                         rte_cpu_to_be_32(res->tunnel_id_value);
1227         }
1228 #endif
1229
1230         (void)rte_memcpy(entry.input.flow_ext.flexbytes,
1231                         flexbytes,
1232                         RTE_ETH_FDIR_MAX_FLEXLEN);
1233
1234         entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value);
1235
1236         entry.action.flex_off = 0;  /*use 0 by default */
1237         if (!strcmp(res->drop, "drop"))
1238                 entry.action.behavior = RTE_ETH_FDIR_REJECT;
1239         else
1240                 entry.action.behavior = RTE_ETH_FDIR_ACCEPT;
1241
1242         if (!strcmp(res->pf_vf, "pf"))
1243                 entry.input.flow_ext.is_vf = 0;
1244         else if (!strncmp(res->pf_vf, "vf", 2)) {
1245                 struct rte_eth_dev_info dev_info;
1246
1247                 memset(&dev_info, 0, sizeof(dev_info));
1248                 rte_eth_dev_info_get(res->port_id, &dev_info);
1249                 errno = 0;
1250                 vf_id = strtoul(res->pf_vf + 2, &end, 10);
1251                 if (errno != 0 || *end != '\0' || vf_id >= dev_info.max_vfs) {
1252                         printf("invalid parameter %s.\n", res->pf_vf);
1253                         return;
1254                 }
1255                 entry.input.flow_ext.is_vf = 1;
1256                 entry.input.flow_ext.dst_id = (uint16_t)vf_id;
1257         } else {
1258                 printf("invalid parameter %s.\n", res->pf_vf);
1259                 return;
1260         }
1261         /* set to report FD ID by default */
1262         entry.action.report_status = RTE_ETH_FDIR_REPORT_ID;
1263         entry.action.rx_queue = res->queue_id;
1264         entry.soft_id = res->fd_id_value;
1265         if (!strcmp(res->ops, "add"))
1266                 ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
1267                                 RTE_ETH_FILTER_ADD, &entry);
1268         else if (!strcmp(res->ops, "del"))
1269                 ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
1270                                 RTE_ETH_FILTER_DELETE, &entry);
1271         else
1272                 ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
1273                                 RTE_ETH_FILTER_UPDATE, &entry);
1274         if (ret < 0)
1275                 printf("flow director programming error: (%s)\n",
1276                                 strerror(-ret));
1277 //      fdir_filter_enabled = 1;
1278 }
1279
1280
1281
1282 cmdline_parse_token_string_t cmd_flow_director_filter =
1283 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1284                 flow_director_filter, "flow_director_filter");
1285
1286 cmdline_parse_token_num_t cmd_flow_director_port_id =
1287 TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
1288                 port_id, UINT8);
1289
1290
1291 cmdline_parse_token_string_t cmd_flow_director_mode =
1292 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1293                 mode, "mode");
1294
1295 cmdline_parse_token_string_t cmd_flow_director_mode_ip =
1296 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1297                 mode_value, "IP");
1298
1299 cmdline_parse_token_string_t cmd_flow_director_ops =
1300 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1301                 ops, "add#del#update");
1302
1303 cmdline_parse_token_string_t cmd_flow_director_flow =
1304 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1305                 flow, "flow");
1306
1307 cmdline_parse_token_string_t cmd_flow_director_flow_type =
1308 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1309                 flow_type, "ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
1310                 "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload");
1311
1312 cmdline_parse_token_string_t cmd_flow_director_src =
1313 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1314                 src, "src");
1315 cmdline_parse_token_ipaddr_t cmd_flow_director_ip_src =
1316 TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result,
1317                 ip_src);
1318 cmdline_parse_token_num_t cmd_flow_director_port_src =
1319 TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
1320                 port_src, UINT16);
1321 cmdline_parse_token_string_t cmd_flow_director_dst =
1322 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1323                 dst, "dst");
1324 cmdline_parse_token_ipaddr_t cmd_flow_director_ip_dst =
1325 TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result,
1326                 ip_dst);
1327 cmdline_parse_token_num_t cmd_flow_director_port_dst =
1328 TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
1329                 port_dst, UINT16);
1330
1331 cmdline_parse_token_string_t cmd_flow_director_tos =
1332 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1333                 tos, "tos");
1334 cmdline_parse_token_num_t cmd_flow_director_tos_value =
1335 TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
1336                 tos_value, UINT8);
1337
1338 cmdline_parse_token_string_t cmd_flow_director_ttl =
1339 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1340                 ttl, "ttl");
1341 cmdline_parse_token_num_t cmd_flow_director_ttl_value =
1342 TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
1343                 ttl_value, UINT8);
1344
1345 cmdline_parse_token_string_t cmd_flow_director_vlan =
1346 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1347                 vlan, "vlan");
1348 cmdline_parse_token_num_t cmd_flow_director_vlan_value =
1349 TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
1350                 vlan_value, UINT16);
1351 cmdline_parse_token_string_t cmd_flow_director_flexbytes =
1352 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1353                 flexbytes, "flexbytes");
1354 cmdline_parse_token_string_t cmd_flow_director_flexbytes_value =
1355 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1356                 flexbytes_value, NULL);
1357 cmdline_parse_token_string_t cmd_flow_director_drop =
1358 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1359                 drop, "drop#fwd");
1360 cmdline_parse_token_string_t cmd_flow_director_pf_vf =
1361 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1362                 pf_vf, NULL);
1363 cmdline_parse_token_string_t cmd_flow_director_queue =
1364 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1365                 queue, "queue");
1366 cmdline_parse_token_num_t cmd_flow_director_queue_id =
1367 TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
1368                 queue_id, UINT16);
1369 cmdline_parse_token_string_t cmd_flow_director_fd_id =
1370 TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1371                 fd_id, "fd_id");
1372 cmdline_parse_token_num_t cmd_flow_director_fd_id_value =
1373 TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
1374                 fd_id_value, UINT32);
1375
1376
1377 cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
1378         .f = cmd_flow_director_filter_parsed,
1379         .data = NULL,
1380         .help_str = "add or delete an udp/tcp flow director entry on NIC",
1381         .tokens = {
1382                 (void *)&cmd_flow_director_filter,
1383                 (void *)&cmd_flow_director_port_id,
1384                 (void *)&cmd_flow_director_mode,
1385                 (void *)&cmd_flow_director_mode_ip,
1386                 (void *)&cmd_flow_director_ops,
1387                 (void *)&cmd_flow_director_flow,
1388                 (void *)&cmd_flow_director_flow_type,
1389                 (void *)&cmd_flow_director_src,
1390                 (void *)&cmd_flow_director_ip_src,
1391                 (void *)&cmd_flow_director_port_src,
1392                 (void *)&cmd_flow_director_dst,
1393                 (void *)&cmd_flow_director_ip_dst,
1394                 (void *)&cmd_flow_director_port_dst,
1395                 (void *)&cmd_flow_director_tos,
1396                 (void *)&cmd_flow_director_tos_value,
1397                 (void *)&cmd_flow_director_ttl,
1398                 (void *)&cmd_flow_director_ttl_value,
1399                 (void *)&cmd_flow_director_vlan,
1400                 (void *)&cmd_flow_director_vlan_value,
1401                 (void *)&cmd_flow_director_flexbytes,
1402                 (void *)&cmd_flow_director_flexbytes_value,
1403                 (void *)&cmd_flow_director_drop,
1404                 (void *)&cmd_flow_director_pf_vf,
1405                 (void *)&cmd_flow_director_queue,
1406                 (void *)&cmd_flow_director_queue_id,
1407                 (void *)&cmd_flow_director_fd_id,
1408                 (void *)&cmd_flow_director_fd_id_value,
1409                 NULL,
1410         },
1411 };
1412 /* L2 payload*/
1413 cmdline_parse_token_string_t cmd_flow_director_ether =
1414         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
1415                 ether, "ether");
1416 cmdline_parse_token_num_t cmd_flow_director_ether_type =
1417         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
1418                 ether_type, UINT16);
1419
1420 cmdline_parse_inst_t cmd_add_del_l2_flow_director = {
1421         .f = cmd_flow_director_filter_parsed,
1422         .data = NULL,
1423         .help_str = "add or delete a L2 flow director entry on NIC",
1424         .tokens = {
1425         (void *)&cmd_flow_director_filter,
1426         (void *)&cmd_flow_director_port_id,
1427         (void *)&cmd_flow_director_mode,
1428         (void *)&cmd_flow_director_mode_ip,
1429         (void *)&cmd_flow_director_ops,
1430         (void *)&cmd_flow_director_flow,
1431         (void *)&cmd_flow_director_flow_type,
1432         (void *)&cmd_flow_director_ether,
1433         (void *)&cmd_flow_director_ether_type,
1434         (void *)&cmd_flow_director_flexbytes,
1435         (void *)&cmd_flow_director_flexbytes_value,
1436         (void *)&cmd_flow_director_drop,
1437         (void *)&cmd_flow_director_pf_vf,
1438         (void *)&cmd_flow_director_queue,
1439         (void *)&cmd_flow_director_queue_id,
1440         (void *)&cmd_flow_director_fd_id,
1441         (void *)&cmd_flow_director_fd_id_value,
1442         NULL,
1443         },
1444 };
1445
1446 #if 1
1447 /* Set hash input set */
1448 struct cmd_set_hash_input_set_result {
1449         cmdline_fixed_string_t set_hash_input_set;
1450         uint8_t port_id;
1451         cmdline_fixed_string_t flow_type;
1452         cmdline_fixed_string_t inset_field0;
1453         cmdline_fixed_string_t inset_field1;
1454         cmdline_fixed_string_t inset_field2;
1455         cmdline_fixed_string_t inset_field3;
1456         cmdline_fixed_string_t inset_field4;
1457         cmdline_fixed_string_t select;
1458 };
1459
1460 static enum rte_eth_input_set_field
1461 str2inset(char *string)
1462 {
1463         uint16_t i;
1464
1465         static const struct {
1466                 char str[32];
1467                 enum rte_eth_input_set_field inset;
1468         } inset_table[] = {
1469                 {"ethertype", RTE_ETH_INPUT_SET_L2_ETHERTYPE},
1470                 {"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
1471                 {"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
1472                 {"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
1473                 {"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
1474                 {"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
1475                 {"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
1476                 {"ipv4-ttl", RTE_ETH_INPUT_SET_L3_IP4_TTL},
1477                 {"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
1478                 {"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
1479                 {"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
1480                 {"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
1481                 {"ipv6-hop-limits", RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS},
1482                 {"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
1483                 {"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
1484                 {"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
1485                 {"tcp-dst-port", RTE_ETH_INPUT_SET_L4_TCP_DST_PORT},
1486                 {"sctp-src-port", RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT},
1487                 {"sctp-dst-port", RTE_ETH_INPUT_SET_L4_SCTP_DST_PORT},
1488                 {"sctp-veri-tag", RTE_ETH_INPUT_SET_L4_SCTP_VERIFICATION_TAG},
1489                 {"udp-key", RTE_ETH_INPUT_SET_TUNNEL_L4_UDP_KEY},
1490                 {"gre-key", RTE_ETH_INPUT_SET_TUNNEL_GRE_KEY},
1491                 {"fld-1st", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_1ST_WORD},
1492                 {"fld-2nd", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_2ND_WORD},
1493                 {"fld-3rd", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_3RD_WORD},
1494                 {"fld-4th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_4TH_WORD},
1495                 {"fld-5th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_5TH_WORD},
1496                 {"fld-6th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_6TH_WORD},
1497                 {"fld-7th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_7TH_WORD},
1498                 {"fld-8th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_8TH_WORD},
1499                 {"none", RTE_ETH_INPUT_SET_NONE},
1500         };
1501         for (i = 0; i < RTE_DIM(inset_table); i++) {
1502                 if (!strcmp(string, inset_table[i].str))
1503                         return inset_table[i].inset;
1504         }
1505
1506         return RTE_ETH_INPUT_SET_UNKNOWN;
1507 }
1508
1509 static void
1510 cmd_set_hash_input_set_1_parsed(void *parsed_result,
1511                 __rte_unused struct cmdline *cl,
1512                 __rte_unused void *data)
1513 {
1514         struct cmd_set_hash_input_set_result *res = parsed_result;
1515         struct rte_eth_hash_filter_info info;
1516
1517         if (enable_flow_dir) {
1518                 printf("FDIR Filter is Defined!\n");
1519                 printf("Please undefine FDIR_FILTER flag and define "
1520                         "HWLD flag\n");
1521                 return;
1522         }
1523
1524         memset(&info, 0, sizeof(info));
1525         info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
1526         info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
1527
1528         info.info.input_set_conf.field[0] = str2inset(res->inset_field0);
1529         info.info.input_set_conf.inset_size = 1;
1530
1531         if (!strcmp(res->select, "select"))
1532                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
1533         else if (!strcmp(res->select, "add"))
1534                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
1535
1536         rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
1537                 RTE_ETH_FILTER_SET, &info);
1538
1539         //hash_filter_enabled = 1;
1540 }
1541
1542 static void
1543 cmd_set_hash_input_set_2_parsed(void *parsed_result,
1544                         __rte_unused struct cmdline *cl,
1545                         __rte_unused void *data)
1546 {
1547         struct cmd_set_hash_input_set_result *res = parsed_result;
1548         struct rte_eth_hash_filter_info info;
1549
1550         if (enable_flow_dir) {
1551                 printf("FDIR Filter is Defined!\n");
1552                 printf("Please undefine FDIR_FILTER flag and define "
1553                         "HWLD flag\n");
1554                 return;
1555         }
1556
1557         memset(&info, 0, sizeof(info));
1558         info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
1559         info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
1560
1561         info.info.input_set_conf.field[0] = str2inset(res->inset_field0);
1562         info.info.input_set_conf.field[1] = str2inset(res->inset_field1);
1563
1564         info.info.input_set_conf.inset_size = 2;
1565
1566         if (!strcmp(res->select, "select"))
1567                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
1568         else if (!strcmp(res->select, "add"))
1569                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
1570
1571         rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
1572                 RTE_ETH_FILTER_SET, &info);
1573
1574         //hash_filter_enabled = 1;
1575 }
1576
1577 #if 0
1578 static void
1579 cmd_set_hash_input_set_3_parsed(void *parsed_result,
1580                 __rte_unused struct cmdline *cl,
1581                  __rte_unused void *data)
1582 {
1583         struct cmd_set_hash_input_set_result *res = parsed_result;
1584         struct rte_eth_hash_filter_info info;
1585
1586         memset(&info, 0, sizeof(info));
1587         info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
1588         info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
1589
1590         info.info.input_set_conf.field[0] = str2inset(res->inset_field0);
1591         info.info.input_set_conf.field[1] = str2inset(res->inset_field1);
1592         info.info.input_set_conf.field[2] = str2inset(res->inset_field2);
1593         info.info.input_set_conf.inset_size = 3;
1594
1595         if (!strcmp(res->select, "select"))
1596                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
1597         else if (!strcmp(res->select, "add"))
1598                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
1599
1600         rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
1601                 RTE_ETH_FILTER_SET, &info);
1602 }
1603 #endif
1604 static void
1605 cmd_set_hash_input_set_4_parsed(void *parsed_result,
1606                          __rte_unused struct cmdline *cl,
1607                          __rte_unused void *data)
1608 {
1609         struct cmd_set_hash_input_set_result *res = parsed_result;
1610         struct rte_eth_hash_filter_info info;
1611
1612         if (enable_flow_dir) {
1613                 printf("FDIR Filter is Defined!\n");
1614                 printf("Please undefine FDIR_FILTER flag and define "
1615                         "HWLD flag\n");
1616                 return;
1617         }
1618
1619         memset(&info, 0, sizeof(info));
1620         info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
1621         info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
1622
1623         info.info.input_set_conf.field[0] = str2inset(res->inset_field0);
1624         info.info.input_set_conf.field[1] = str2inset(res->inset_field1);
1625         info.info.input_set_conf.field[2] = str2inset(res->inset_field2);
1626         info.info.input_set_conf.field[3] = str2inset(res->inset_field3);
1627
1628         info.info.input_set_conf.inset_size = 4;
1629         if (!strcmp(res->select, "select"))
1630                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
1631         else if (!strcmp(res->select, "add"))
1632                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
1633
1634         rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
1635                 RTE_ETH_FILTER_SET, &info);
1636         //hash_filter_enabled = 1;
1637 }
1638
1639 #if 0
1640 static void
1641 cmd_set_hash_input_set_5_parsed(void *parsed_result,
1642         __rte_unused struct cmdline *cl,
1643         __rte_unused void *data)
1644 {
1645         struct cmd_set_hash_input_set_result *res = parsed_result;
1646         struct rte_eth_hash_filter_info info;
1647
1648         memset(&info, 0, sizeof(info));
1649         info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
1650         info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
1651
1652         info.info.input_set_conf.field[0] = str2inset(res->inset_field0);
1653         info.info.input_set_conf.field[1] = str2inset(res->inset_field1);
1654         info.info.input_set_conf.field[2] = str2inset(res->inset_field2);
1655         info.info.input_set_conf.field[3] = str2inset(res->inset_field3);
1656         info.info.input_set_conf.field[4] = str2inset(res->inset_field4);
1657
1658         info.info.input_set_conf.inset_size = 5;
1659         if (!strcmp(res->select, "select"))
1660                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
1661         else if (!strcmp(res->select, "add"))
1662                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
1663         rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
1664         RTE_ETH_FILTER_SET, &info);
1665 }
1666 #endif
1667
1668 cmdline_parse_token_string_t cmd_set_hash_input_set_cmd =
1669         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
1670         set_hash_input_set, "set_hash_input_set");
1671 cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
1672         TOKEN_NUM_INITIALIZER(struct cmd_set_hash_input_set_result,
1673         port_id, UINT8);
1674 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
1675         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
1676         flow_type,
1677         "ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
1678         "ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
1679
1680 cmdline_parse_token_string_t cmd_set_hash_input_set_field0 =
1681         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
1682         inset_field0,
1683         "src-ipv4#src-ipv6#dst-ipv4#dst-ipv6#"
1684         "udp-src-port#udp-dst-port#tcp-src-port#tcp-dst-port#none");
1685
1686 cmdline_parse_token_string_t cmd_set_hash_input_set_field1 =
1687         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
1688         inset_field1,
1689         "dst-ipv4#dst-ipv6#"
1690         "udp-src-port#tcp-src-port#udp-dst-port#tcp-dst-port#none");
1691
1692 cmdline_parse_token_string_t cmd_set_hash_input_set_field2 =
1693         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
1694         inset_field2,
1695         "udp-src-port#tcp-src-port#none");
1696
1697 cmdline_parse_token_string_t cmd_set_hash_input_set_field3 =
1698         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
1699         inset_field3,
1700         "udp-dst-port#tcp-dst-port#none");
1701 #if 0
1702 cmdline_parse_token_string_t cmd_set_hash_input_set_field4 =
1703         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
1704         inset_field4, "ipv4-proto#ipv6-next-header#none");
1705 #endif
1706
1707 cmdline_parse_token_string_t cmd_set_hash_input_set_select =
1708         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
1709         select, "select#add");
1710
1711 cmdline_parse_inst_t cmd_set_hash_input_set_1 = {
1712         .f = cmd_set_hash_input_set_1_parsed,
1713         .data = NULL,
1714         .help_str = "set_hash_input_set_1 <port_id> "
1715         "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
1716         "ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload    "
1717         "src-ipv4|src-ipv6|dst-ipv4|dst-ipv6|"
1718         "udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|none    "
1719         "select|add",
1720         .tokens = {
1721                 (void *)&cmd_set_hash_input_set_cmd,
1722                 (void *)&cmd_set_hash_input_set_port_id,
1723                 (void *)&cmd_set_hash_input_set_flow_type,
1724                 (void *)&cmd_set_hash_input_set_field0,
1725                 (void *)&cmd_set_hash_input_set_select,
1726                 NULL,
1727         },
1728 };
1729
1730 cmdline_parse_inst_t cmd_set_hash_input_set_2 = {
1731         .f = cmd_set_hash_input_set_2_parsed,
1732         .data = NULL,
1733         .help_str = "set_hash_input_set_2 <port_id> "
1734         "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other| "
1735         "ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
1736         "src-ipv4|src-ipv6|dst-ipv4|dst-ipv6| "
1737         "udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|none "
1738         "udp-src-port|tcp-src-port|udp-dst-port|tcp-dst-port|none "
1739         "select|add",
1740         .tokens = {
1741                 (void *)&cmd_set_hash_input_set_cmd,
1742                 (void *)&cmd_set_hash_input_set_port_id,
1743                 (void *)&cmd_set_hash_input_set_flow_type,
1744                 (void *)&cmd_set_hash_input_set_field0,
1745                 (void *)&cmd_set_hash_input_set_field1,
1746                 (void *)&cmd_set_hash_input_set_select,
1747                 NULL,
1748         },
1749 };
1750
1751 #if 0
1752 cmdline_parse_inst_t cmd_set_hash_input_set_3 = {
1753         .f = cmd_set_hash_input_set_3_parsed,
1754         .data = NULL,
1755         .help_str = "set_hash_input_set_3 <port_id> "
1756         "ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
1757         "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload        "
1758         "ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
1759         "ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
1760         "tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
1761         "gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
1762         "fld-7th|fld-8th|none       "
1763         "udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|none       "
1764         "select|add",
1765         .tokens = {
1766                 (void *)&cmd_set_hash_input_set_cmd,
1767                 (void *)&cmd_set_hash_input_set_port_id,
1768                 (void *)&cmd_set_hash_input_set_flow_type,
1769                 (void *)&cmd_set_hash_input_set_field0,
1770                 (void *)&cmd_set_hash_input_set_field1,
1771                 (void *)&cmd_set_hash_input_set_field2,
1772                 (void *)&cmd_set_hash_input_set_select,
1773                 NULL,
1774         },
1775 };
1776 #endif
1777
1778 cmdline_parse_inst_t cmd_set_hash_input_set_4 = {
1779         .f = cmd_set_hash_input_set_4_parsed,
1780         .data = NULL,
1781         .help_str = "set_hash_input_set_4 <port_id> "
1782         "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
1783         "ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
1784         "src-ipv4|src-ipv6|dst-ipv4|dst-ipv6|"
1785         "udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|none "
1786         "udp-src-port|tcp-src-port|udp-dst-port|tcp-dst-port|none "
1787         "udp-src-port|tcp-src-port|dst-ipv4|none    "
1788         "udp-dst-port|tcp-dst-port|none    "
1789         "select|add",
1790         .tokens = {
1791                 (void *)&cmd_set_hash_input_set_cmd,
1792                 (void *)&cmd_set_hash_input_set_port_id,
1793                 (void *)&cmd_set_hash_input_set_flow_type,
1794                 (void *)&cmd_set_hash_input_set_field0,
1795                 (void *)&cmd_set_hash_input_set_field1,
1796                 (void *)&cmd_set_hash_input_set_field2,
1797                 (void *)&cmd_set_hash_input_set_field3,
1798                 (void *)&cmd_set_hash_input_set_select,
1799                 NULL,
1800         },
1801 };
1802 #if 0
1803 cmdline_parse_inst_t cmd_set_hash_input_set_5 = {
1804         .f = cmd_set_hash_input_set_5_parsed,
1805         .data = NULL,
1806         .help_str = "set_hash_input_set_5 <port_id> "
1807         "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
1808         "ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload    "
1809         "src-ipv4|src-ipv6|none    "
1810         "dst-ipv4|dst-ipv6|none    "
1811         "udp-src-port|tcp-src-port|none    "
1812         "udp-dst-port|tcp-dst-port|none    "
1813         "ipv4-proto|ipv6-next-header|none    "
1814         "select|add",
1815
1816         .tokens = {
1817                 (void *)&cmd_set_hash_input_set_cmd,
1818                 (void *)&cmd_set_hash_input_set_port_id,
1819                 (void *)&cmd_set_hash_input_set_flow_type,
1820                 (void *)&cmd_set_hash_input_set_field0,
1821                 (void *)&cmd_set_hash_input_set_field1,
1822                 (void *)&cmd_set_hash_input_set_field2,
1823                 (void *)&cmd_set_hash_input_set_field3,
1824                 (void *)&cmd_set_hash_input_set_field4,
1825                 (void *)&cmd_set_hash_input_set_select,
1826                 NULL,
1827         },
1828 };
1829 #endif
1830 #endif
1831 /* set hash global config */
1832 struct cmd_set_hash_global_config_result {
1833         cmdline_fixed_string_t set_hash_global_config;
1834         uint8_t port_id;
1835         cmdline_fixed_string_t hash_func;
1836         cmdline_fixed_string_t flow_type;
1837         cmdline_fixed_string_t enable;
1838 };
1839
1840 static void
1841 cmd_set_hash_global_config_parsed(void *parsed_result,
1842                 __rte_unused struct cmdline *cl,
1843                 __rte_unused void *data)
1844 {
1845         struct cmd_set_hash_global_config_result *res = parsed_result;
1846         struct rte_eth_hash_filter_info info;
1847         uint32_t ftype, idx, offset;
1848         int ret;
1849
1850         if (rte_eth_dev_filter_supported(res->port_id,
1851                                 RTE_ETH_FILTER_HASH) < 0) {
1852                 printf("RTE_ETH_FILTER_HASH not supported on port %d\n",
1853                                 res->port_id);
1854                 return;
1855         }
1856         memset(&info, 0, sizeof(info));
1857         info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
1858         if (!strcmp(res->hash_func, "toeplitz"))
1859                 info.info.global_conf.hash_func =
1860                         RTE_ETH_HASH_FUNCTION_TOEPLITZ;
1861         else if (!strcmp(res->hash_func, "simple_xor"))
1862                 info.info.global_conf.hash_func =
1863                         RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
1864         else if (!strcmp(res->hash_func, "default"))
1865                 info.info.global_conf.hash_func =
1866                         RTE_ETH_HASH_FUNCTION_DEFAULT;
1867
1868         ftype = str2flowtype(res->flow_type);
1869         idx = ftype / (CHAR_BIT * sizeof(uint32_t));
1870         offset = ftype % (CHAR_BIT * sizeof(uint32_t));
1871         info.info.global_conf.valid_bit_mask[idx] |= (1UL << offset);
1872         if (!strcmp(res->enable, "enable"))
1873                 if(idx < RTE_SYM_HASH_MASK_ARRAY_SIZE)
1874                 info.info.global_conf.sym_hash_enable_mask[idx] |=
1875                         (1UL << offset);
1876         ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
1877                         RTE_ETH_FILTER_SET, &info);
1878         if (ret < 0)
1879                 printf("Cannot set global hash configurations by port %d\n",
1880                                 res->port_id);
1881         else
1882                 printf("Global hash configurations have been set "
1883                                 "succcessfully by port %d\n", res->port_id);
1884 }
1885 cmdline_parse_token_string_t cmd_set_hash_global_config_all =
1886 TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
1887                 set_hash_global_config, "set_hash_global_config");
1888 cmdline_parse_token_num_t cmd_set_hash_global_config_port_id =
1889 TOKEN_NUM_INITIALIZER(struct cmd_set_hash_global_config_result,
1890                 port_id, UINT8);
1891 cmdline_parse_token_string_t cmd_set_hash_global_config_hash_func =
1892 TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
1893                 hash_func, "toeplitz#simple_xor#default");
1894 cmdline_parse_token_string_t cmd_set_hash_global_config_flow_type =
1895 TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
1896                 flow_type,
1897                 "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
1898                 "ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
1899 cmdline_parse_token_string_t cmd_set_hash_global_config_enable =
1900 TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
1901                 enable, "enable#disable");
1902
1903 cmdline_parse_inst_t cmd_set_hash_global_config = {
1904         .f = cmd_set_hash_global_config_parsed,
1905         .data = NULL,
1906         .help_str = "set_hash_global_config port_id "
1907                 "toeplitz|simple_xor|default "
1908                 "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
1909                 "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
1910                 "enable|disable",
1911         .tokens = {
1912                 (void *)&cmd_set_hash_global_config_all,
1913                 (void *)&cmd_set_hash_global_config_port_id,
1914                 (void *)&cmd_set_hash_global_config_hash_func,
1915                 (void *)&cmd_set_hash_global_config_flow_type,
1916                 (void *)&cmd_set_hash_global_config_enable,
1917                 NULL,
1918         },
1919 };
1920
1921 /* *** Set symmetric hash enable per port *** */
1922 struct cmd_set_sym_hash_ena_per_port_result {
1923         cmdline_fixed_string_t set_sym_hash_ena_per_port;
1924         cmdline_fixed_string_t enable;
1925         uint8_t port_id;
1926 };
1927
1928 static void
1929 cmd_set_sym_hash_per_port_parsed(void *parsed_result,
1930                  __rte_unused struct cmdline *cl,
1931                  __rte_unused void *data)
1932 {
1933         struct cmd_set_sym_hash_ena_per_port_result *res = parsed_result;
1934         struct rte_eth_hash_filter_info info;
1935         int ret;
1936
1937         if (rte_eth_dev_filter_supported(res->port_id,
1938                  RTE_ETH_FILTER_HASH) < 0) {
1939                 printf("RTE_ETH_FILTER_HASH not supported on port: %d\n",
1940                         res->port_id);
1941                 return;
1942         }
1943
1944         memset(&info, 0, sizeof(info));
1945         info.info_type = RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT;
1946
1947         if (!strcmp(res->enable, "enable"))
1948                 info.info.enable = 1;
1949
1950         ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
1951                                  RTE_ETH_FILTER_SET, &info);
1952         if (ret < 0) {
1953                 printf("Cannot set symmetric hash enable per port on "
1954                         "port %u\n", res->port_id);
1955                 return;
1956         }
1957         printf("Symmetric hash has been set to %s on port %u\n",
1958                                  res->enable, res->port_id);
1959 }
1960
1961 cmdline_parse_token_string_t cmd_set_sym_hash_ena_per_port_all =
1962         TOKEN_STRING_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
1963         set_sym_hash_ena_per_port, "set_sym_hash_ena_per_port");
1964 cmdline_parse_token_num_t cmd_set_sym_hash_ena_per_port_port_id =
1965         TOKEN_NUM_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
1966         port_id, UINT8);
1967 cmdline_parse_token_string_t cmd_set_sym_hash_ena_per_port_enable =
1968         TOKEN_STRING_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
1969         enable, "enable#disable");
1970
1971 cmdline_parse_inst_t cmd_set_sym_hash_ena_per_port = {
1972         .f = cmd_set_sym_hash_per_port_parsed,
1973         .data = NULL,
1974         .help_str = "set_sym_hash_ena_per_port port_id enable|disable",
1975         .tokens = {
1976                 (void *)&cmd_set_sym_hash_ena_per_port_all,
1977                 (void *)&cmd_set_sym_hash_ena_per_port_port_id,
1978                 (void *)&cmd_set_sym_hash_ena_per_port_enable,
1979                 NULL,
1980         },
1981 };
1982 #endif
1983
1984 static int
1985 app_pipeline_arpicmp_entry_dbg(struct app_params *app,
1986                                         uint32_t pipeline_id, uint8_t *msg)
1987 {
1988         struct pipeline_arpicmp_entry_dbg_msg_req *req;
1989         struct pipeline_arpicmp_entry_dbg_msg_rsp *rsp;
1990
1991         /* Check input arguments */
1992         if (app == NULL)
1993                 return -1;
1994
1995         /* Allocate and write request */
1996         req = app_msg_alloc(app);
1997         if (req == NULL)
1998                 return -1;
1999
2000         req->type = PIPELINE_MSG_REQ_CUSTOM;
2001         req->subtype = PIPELINE_ARPICMP_MSG_REQ_ENTRY_DBG;
2002         req->data[0] = msg[0];
2003         req->data[1] = msg[1];
2004
2005         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
2006         if (rsp == NULL)
2007                 return -1;
2008
2009         /* Read response */
2010         if (rsp->status) {
2011                 app_msg_free(app, rsp);
2012                 printf("Error rsp->status %d\n", rsp->status);
2013                 return -1;
2014         }
2015
2016         /* Free response */
2017         app_msg_free(app, rsp);
2018
2019         return 0;
2020 }
2021
2022 /*
2023  * entry dbg
2024  */
2025
2026
2027 struct cmd_entry_dbg_result {
2028         cmdline_fixed_string_t p_string;
2029         uint32_t p;
2030         cmdline_fixed_string_t entry_string;
2031         cmdline_fixed_string_t dbg_string;
2032         uint8_t cmd;
2033         uint8_t d1;
2034 };
2035
2036 static void
2037 cmd_entry_dbg_parsed(void *parsed_result,
2038                                  __rte_unused struct cmdline *cl, void *data)
2039 {
2040         struct cmd_entry_dbg_result *params = parsed_result;
2041         struct app_params *app = data;
2042         uint8_t msg[2];
2043         int status;
2044
2045         msg[0] = params->cmd;
2046         msg[1] = params->d1;
2047         status = app_pipeline_arpicmp_entry_dbg(app, params->p, msg);
2048
2049         if (status != 0) {
2050                 printf("Dbg Command failed\n");
2051                 return;
2052         }
2053 }
2054
2055 static cmdline_parse_token_string_t lb_cmd_entry_dbg_p_string =
2056 TOKEN_STRING_INITIALIZER(struct cmd_entry_dbg_result, p_string, "p");
2057
2058 static cmdline_parse_token_num_t lb_cmd_entry_dbg_p =
2059 TOKEN_NUM_INITIALIZER(struct cmd_entry_dbg_result, p, UINT32);
2060
2061 static cmdline_parse_token_string_t lb_cmd_entry_dbg_entry_string =
2062 TOKEN_STRING_INITIALIZER(struct cmd_entry_dbg_result,
2063                          entry_string, "txrx");
2064
2065 static cmdline_parse_token_string_t lb_cmd_entry_dbg_dbg_string =
2066 TOKEN_STRING_INITIALIZER(struct cmd_entry_dbg_result, dbg_string,
2067                          "dbg");
2068
2069 static cmdline_parse_token_num_t lb_cmd_entry_dbg_cmd =
2070 TOKEN_NUM_INITIALIZER(struct cmd_entry_dbg_result, cmd, UINT8);
2071
2072 static cmdline_parse_token_num_t lb_cmd_entry_dbg_d1 =
2073 TOKEN_NUM_INITIALIZER(struct cmd_entry_dbg_result, d1, UINT8);
2074
2075 static cmdline_parse_inst_t lb_cmd_entry_dbg = {
2076         .f = cmd_entry_dbg_parsed,
2077         .data = NULL,
2078         .help_str = "ARPICMP dbg cmd",
2079         .tokens = {
2080                          (void *)&lb_cmd_entry_dbg_p_string,
2081                          (void *)&lb_cmd_entry_dbg_p,
2082                          (void *)&lb_cmd_entry_dbg_entry_string,
2083                          (void *)&lb_cmd_entry_dbg_dbg_string,
2084                          (void *)&lb_cmd_entry_dbg_cmd,
2085                          (void *)&lb_cmd_entry_dbg_d1,
2086                          NULL,
2087         },
2088 };
2089
2090 static cmdline_parse_ctx_t pipeline_cmds[] = {
2091         (cmdline_parse_inst_t *) &lb_cmd_entry_dbg,
2092         (cmdline_parse_inst_t *) &cmd_arp_add,
2093         (cmdline_parse_inst_t *) &cmd_arp_del,
2094         (cmdline_parse_inst_t *) &cmd_arp_req,
2095         (cmdline_parse_inst_t *) &cmd_icmp_echo_req,
2096         (cmdline_parse_inst_t *) &cmd_arp_ls,
2097         (cmdline_parse_inst_t *) &cmd_show_ports_info,
2098         /*HWLB cmds*/
2099         (cmdline_parse_inst_t *) &cmd_set_fwd_mode,
2100         (cmdline_parse_inst_t *) &cmd_add_del_udp_flow_director,
2101         (cmdline_parse_inst_t *) &cmd_add_del_l2_flow_director,
2102         (cmdline_parse_inst_t *) &cmd_set_hash_input_set_1,
2103         (cmdline_parse_inst_t *) &cmd_set_hash_input_set_2,
2104 /*      (cmdline_parse_inst_t *) & cmd_set_hash_input_set_3,*/
2105         (cmdline_parse_inst_t *) &cmd_set_hash_input_set_4,
2106 /*      (cmdline_parse_inst_t *) & cmd_set_hash_input_set_5,*/
2107         (cmdline_parse_inst_t *) &cmd_set_hash_global_config,
2108         (cmdline_parse_inst_t *) &cmd_set_sym_hash_ena_per_port,
2109         #ifndef VNF_ACL
2110         (cmdline_parse_inst_t *) &cmd_arp_dbg,
2111         (cmdline_parse_inst_t *) &cmd_arp_timer,
2112         #endif
2113         NULL,
2114 };
2115
2116 static struct pipeline_fe_ops pipeline_arpicmp_fe_ops = {
2117         .f_init = NULL,
2118         .f_free = NULL,
2119         .cmds = pipeline_cmds,
2120 };
2121
2122 struct pipeline_type pipeline_arpicmp = {
2123         .name = "ARPICMP",
2124         .be_ops = &pipeline_arpicmp_be_ops,
2125         .fe_ops = &pipeline_arpicmp_fe_ops,
2126 };