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