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