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