Imported Upstream version 16.04
[deb_dpdk.git] / examples / ip_pipeline / pipeline / pipeline_common_fe.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdio.h>
35 #include <fcntl.h>
36 #include <unistd.h>
37
38 #include <rte_common.h>
39 #include <rte_ring.h>
40 #include <rte_malloc.h>
41 #include <cmdline_rdline.h>
42 #include <cmdline_parse.h>
43 #include <cmdline_parse_num.h>
44 #include <cmdline_parse_string.h>
45 #include <cmdline_parse_ipaddr.h>
46 #include <cmdline_parse_etheraddr.h>
47 #include <cmdline_socket.h>
48 #include <cmdline.h>
49
50 #include "pipeline_common_fe.h"
51
52 int
53 app_pipeline_ping(struct app_params *app,
54         uint32_t pipeline_id)
55 {
56         struct app_pipeline_params *p;
57         struct pipeline_msg_req *req;
58         struct pipeline_msg_rsp *rsp;
59         int status = 0;
60
61         /* Check input arguments */
62         if (app == NULL)
63                 return -1;
64
65         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
66         if (p == NULL)
67                 return -1;
68
69         /* Message buffer allocation */
70         req = app_msg_alloc(app);
71         if (req == NULL)
72                 return -1;
73
74         /* Fill in request */
75         req->type = PIPELINE_MSG_REQ_PING;
76
77         /* Send request and wait for response */
78         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
79         if (rsp == NULL)
80                 return -1;
81
82         /* Check response */
83         status = rsp->status;
84
85         /* Message buffer free */
86         app_msg_free(app, rsp);
87
88         return status;
89 }
90
91 int
92 app_pipeline_stats_port_in(struct app_params *app,
93         uint32_t pipeline_id,
94         uint32_t port_id,
95         struct rte_pipeline_port_in_stats *stats)
96 {
97         struct app_pipeline_params *p;
98         struct pipeline_stats_msg_req *req;
99         struct pipeline_stats_port_in_msg_rsp *rsp;
100         int status = 0;
101
102         /* Check input arguments */
103         if ((app == NULL) ||
104                 (stats == NULL))
105                 return -1;
106
107         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
108         if ((p == NULL) ||
109                 (port_id >= p->n_pktq_in))
110                 return -1;
111
112         /* Message buffer allocation */
113         req = app_msg_alloc(app);
114         if (req == NULL)
115                 return -1;
116
117         /* Fill in request */
118         req->type = PIPELINE_MSG_REQ_STATS_PORT_IN;
119         req->id = port_id;
120
121         /* Send request and wait for response */
122         rsp = (struct pipeline_stats_port_in_msg_rsp *)
123                 app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
124         if (rsp == NULL)
125                 return -1;
126
127         /* Check response */
128         status = rsp->status;
129         if (status == 0)
130                 memcpy(stats, &rsp->stats, sizeof(rsp->stats));
131
132         /* Message buffer free */
133         app_msg_free(app, rsp);
134
135         return status;
136 }
137
138 int
139 app_pipeline_stats_port_out(struct app_params *app,
140         uint32_t pipeline_id,
141         uint32_t port_id,
142         struct rte_pipeline_port_out_stats *stats)
143 {
144         struct app_pipeline_params *p;
145         struct pipeline_stats_msg_req *req;
146         struct pipeline_stats_port_out_msg_rsp *rsp;
147         int status = 0;
148
149         /* Check input arguments */
150         if ((app == NULL) ||
151                 (pipeline_id >= app->n_pipelines) ||
152                 (stats == NULL))
153                 return -1;
154
155         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
156         if ((p == NULL) ||
157                 (port_id >= p->n_pktq_out))
158                 return -1;
159
160         /* Message buffer allocation */
161         req = app_msg_alloc(app);
162         if (req == NULL)
163                 return -1;
164
165         /* Fill in request */
166         req->type = PIPELINE_MSG_REQ_STATS_PORT_OUT;
167         req->id = port_id;
168
169         /* Send request and wait for response */
170         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
171         if (rsp == NULL)
172                 return -1;
173
174         /* Check response */
175         status = rsp->status;
176         if (status == 0)
177                 memcpy(stats, &rsp->stats, sizeof(rsp->stats));
178
179         /* Message buffer free */
180         app_msg_free(app, rsp);
181
182         return status;
183 }
184
185 int
186 app_pipeline_stats_table(struct app_params *app,
187         uint32_t pipeline_id,
188         uint32_t table_id,
189         struct rte_pipeline_table_stats *stats)
190 {
191         struct app_pipeline_params *p;
192         struct pipeline_stats_msg_req *req;
193         struct pipeline_stats_table_msg_rsp *rsp;
194         int status = 0;
195
196         /* Check input arguments */
197         if ((app == NULL) ||
198                 (stats == NULL))
199                 return -1;
200
201         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
202         if (p == NULL)
203                 return -1;
204
205         /* Message buffer allocation */
206         req = app_msg_alloc(app);
207         if (req == NULL)
208                 return -1;
209
210         /* Fill in request */
211         req->type = PIPELINE_MSG_REQ_STATS_TABLE;
212         req->id = table_id;
213
214         /* Send request and wait for response */
215         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
216         if (rsp == NULL)
217                 return -1;
218
219         /* Check response */
220         status = rsp->status;
221         if (status == 0)
222                 memcpy(stats, &rsp->stats, sizeof(rsp->stats));
223
224         /* Message buffer free */
225         app_msg_free(app, rsp);
226
227         return status;
228 }
229
230 int
231 app_pipeline_port_in_enable(struct app_params *app,
232         uint32_t pipeline_id,
233         uint32_t port_id)
234 {
235         struct app_pipeline_params *p;
236         struct pipeline_port_in_msg_req *req;
237         struct pipeline_msg_rsp *rsp;
238         int status = 0;
239
240         /* Check input arguments */
241         if (app == NULL)
242                 return -1;
243
244         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
245         if ((p == NULL) ||
246                 (port_id >= p->n_pktq_in))
247                 return -1;
248
249         /* Message buffer allocation */
250         req = app_msg_alloc(app);
251         if (req == NULL)
252                 return -1;
253
254         /* Fill in request */
255         req->type = PIPELINE_MSG_REQ_PORT_IN_ENABLE;
256         req->port_id = port_id;
257
258         /* Send request and wait for response */
259         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
260         if (rsp == NULL)
261                 return -1;
262
263         /* Check response */
264         status = rsp->status;
265
266         /* Message buffer free */
267         app_msg_free(app, rsp);
268
269         return status;
270 }
271
272 int
273 app_pipeline_port_in_disable(struct app_params *app,
274         uint32_t pipeline_id,
275         uint32_t port_id)
276 {
277         struct app_pipeline_params *p;
278         struct pipeline_port_in_msg_req *req;
279         struct pipeline_msg_rsp *rsp;
280         int status = 0;
281
282         /* Check input arguments */
283         if (app == NULL)
284                 return -1;
285
286         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
287         if ((p == NULL) ||
288                 (port_id >= p->n_pktq_in))
289                 return -1;
290
291         /* Message buffer allocation */
292         req = app_msg_alloc(app);
293         if (req == NULL)
294                 return -1;
295
296         /* Fill in request */
297         req->type = PIPELINE_MSG_REQ_PORT_IN_DISABLE;
298         req->port_id = port_id;
299
300         /* Send request and wait for response */
301         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
302         if (rsp == NULL)
303                 return -1;
304
305         /* Check response */
306         status = rsp->status;
307
308         /* Message buffer free */
309         app_msg_free(app, rsp);
310
311         return status;
312 }
313
314 int
315 app_link_config(struct app_params *app,
316         uint32_t link_id,
317         uint32_t ip,
318         uint32_t depth)
319 {
320         struct app_link_params *p;
321         uint32_t i, netmask, host, bcast;
322
323         /* Check input arguments */
324         if (app == NULL)
325                 return -1;
326
327         APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
328         if (p == NULL) {
329                 APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link",
330                         link_id);
331                 return -1;
332         }
333
334         if (p->state) {
335                 APP_LOG(app, HIGH, "%s is UP, please bring it DOWN first",
336                         p->name);
337                 return -1;
338         }
339
340         netmask = (~0U) << (32 - depth);
341         host = ip & netmask;
342         bcast = host | (~netmask);
343
344         if ((ip == 0) ||
345                 (ip == UINT32_MAX) ||
346                 (ip == host) ||
347                 (ip == bcast)) {
348                 APP_LOG(app, HIGH, "Illegal IP address");
349                 return -1;
350         }
351
352         for (i = 0; i < app->n_links; i++) {
353                 struct app_link_params *link = &app->link_params[i];
354
355                 if (strcmp(p->name, link->name) == 0)
356                         continue;
357
358                 if (link->ip == ip) {
359                         APP_LOG(app, HIGH,
360                                 "%s is already assigned this IP address",
361                                 link->name);
362                         return -1;
363                 }
364         }
365
366         if ((depth == 0) || (depth > 32)) {
367                 APP_LOG(app, HIGH, "Illegal value for depth parameter "
368                         "(%" PRIu32 ")",
369                         depth);
370                 return -1;
371         }
372
373         /* Save link parameters */
374         p->ip = ip;
375         p->depth = depth;
376
377         return 0;
378 }
379
380 int
381 app_link_up(struct app_params *app,
382         uint32_t link_id)
383 {
384         struct app_link_params *p;
385
386         /* Check input arguments */
387         if (app == NULL)
388                 return -1;
389
390         APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
391         if (p == NULL) {
392                 APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link",
393                         link_id);
394                 return -1;
395         }
396
397         /* Check link state */
398         if (p->state) {
399                 APP_LOG(app, HIGH, "%s is already UP", p->name);
400                 return 0;
401         }
402
403         /* Check that IP address is valid */
404         if (p->ip == 0) {
405                 APP_LOG(app, HIGH, "%s IP address is not set", p->name);
406                 return 0;
407         }
408
409         app_link_up_internal(app, p);
410
411         return 0;
412 }
413
414 int
415 app_link_down(struct app_params *app,
416         uint32_t link_id)
417 {
418         struct app_link_params *p;
419
420         /* Check input arguments */
421         if (app == NULL)
422                 return -1;
423
424         APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
425         if (p == NULL) {
426                 APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link",
427                         link_id);
428                 return -1;
429         }
430
431         /* Check link state */
432         if (p->state == 0) {
433                 APP_LOG(app, HIGH, "%s is already DOWN", p->name);
434                 return 0;
435         }
436
437         app_link_down_internal(app, p);
438
439         return 0;
440 }
441
442 /*
443  * ping
444  */
445
446 struct cmd_ping_result {
447         cmdline_fixed_string_t p_string;
448         uint32_t pipeline_id;
449         cmdline_fixed_string_t ping_string;
450 };
451
452 static void
453 cmd_ping_parsed(
454         void *parsed_result,
455         __rte_unused struct cmdline *cl,
456         void *data)
457 {
458         struct cmd_ping_result *params = parsed_result;
459         struct app_params *app = data;
460         int status;
461
462         status = app_pipeline_ping(app, params->pipeline_id);
463         if (status != 0)
464                 printf("Command failed\n");
465 }
466
467 cmdline_parse_token_string_t cmd_ping_p_string =
468         TOKEN_STRING_INITIALIZER(struct cmd_ping_result, p_string, "p");
469
470 cmdline_parse_token_num_t cmd_ping_pipeline_id =
471         TOKEN_NUM_INITIALIZER(struct cmd_ping_result, pipeline_id, UINT32);
472
473 cmdline_parse_token_string_t cmd_ping_ping_string =
474         TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping_string, "ping");
475
476 cmdline_parse_inst_t cmd_ping = {
477         .f = cmd_ping_parsed,
478         .data = NULL,
479         .help_str = "Pipeline ping",
480         .tokens = {
481                 (void *) &cmd_ping_p_string,
482                 (void *) &cmd_ping_pipeline_id,
483                 (void *) &cmd_ping_ping_string,
484                 NULL,
485         },
486 };
487
488 /*
489  * stats port in
490  */
491
492 struct cmd_stats_port_in_result {
493         cmdline_fixed_string_t p_string;
494         uint32_t pipeline_id;
495         cmdline_fixed_string_t stats_string;
496         cmdline_fixed_string_t port_string;
497         cmdline_fixed_string_t in_string;
498         uint32_t port_in_id;
499
500 };
501 static void
502 cmd_stats_port_in_parsed(
503         void *parsed_result,
504         __rte_unused struct cmdline *cl,
505         void *data)
506 {
507         struct cmd_stats_port_in_result *params = parsed_result;
508         struct app_params *app = data;
509         struct rte_pipeline_port_in_stats stats;
510         int status;
511
512         status = app_pipeline_stats_port_in(app,
513                         params->pipeline_id,
514                         params->port_in_id,
515                         &stats);
516
517         if (status != 0) {
518                 printf("Command failed\n");
519                 return;
520         }
521
522         /* Display stats */
523         printf("Pipeline %" PRIu32 " - stats for input port %" PRIu32 ":\n"
524                 "\tPkts in: %" PRIu64 "\n"
525                 "\tPkts dropped by AH: %" PRIu64 "\n"
526                 "\tPkts dropped by other: %" PRIu64 "\n",
527                 params->pipeline_id,
528                 params->port_in_id,
529                 stats.stats.n_pkts_in,
530                 stats.n_pkts_dropped_by_ah,
531                 stats.stats.n_pkts_drop);
532 }
533
534 cmdline_parse_token_string_t cmd_stats_port_in_p_string =
535         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, p_string,
536                 "p");
537
538 cmdline_parse_token_num_t cmd_stats_port_in_pipeline_id =
539         TOKEN_NUM_INITIALIZER(struct cmd_stats_port_in_result, pipeline_id,
540                 UINT32);
541
542 cmdline_parse_token_string_t cmd_stats_port_in_stats_string =
543         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, stats_string,
544                 "stats");
545
546 cmdline_parse_token_string_t cmd_stats_port_in_port_string =
547         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, port_string,
548                 "port");
549
550 cmdline_parse_token_string_t cmd_stats_port_in_in_string =
551         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, in_string,
552                 "in");
553
554         cmdline_parse_token_num_t cmd_stats_port_in_port_in_id =
555         TOKEN_NUM_INITIALIZER(struct cmd_stats_port_in_result, port_in_id,
556                 UINT32);
557
558 cmdline_parse_inst_t cmd_stats_port_in = {
559         .f = cmd_stats_port_in_parsed,
560         .data = NULL,
561         .help_str = "Pipeline input port stats",
562         .tokens = {
563                 (void *) &cmd_stats_port_in_p_string,
564                 (void *) &cmd_stats_port_in_pipeline_id,
565                 (void *) &cmd_stats_port_in_stats_string,
566                 (void *) &cmd_stats_port_in_port_string,
567                 (void *) &cmd_stats_port_in_in_string,
568                 (void *) &cmd_stats_port_in_port_in_id,
569                 NULL,
570         },
571 };
572
573 /*
574  * stats port out
575  */
576
577 struct cmd_stats_port_out_result {
578         cmdline_fixed_string_t p_string;
579         uint32_t pipeline_id;
580         cmdline_fixed_string_t stats_string;
581         cmdline_fixed_string_t port_string;
582         cmdline_fixed_string_t out_string;
583         uint32_t port_out_id;
584 };
585
586 static void
587 cmd_stats_port_out_parsed(
588         void *parsed_result,
589         __rte_unused struct cmdline *cl,
590         void *data)
591 {
592
593         struct cmd_stats_port_out_result *params = parsed_result;
594         struct app_params *app = data;
595         struct rte_pipeline_port_out_stats stats;
596         int status;
597
598         status = app_pipeline_stats_port_out(app,
599                         params->pipeline_id,
600                         params->port_out_id,
601                         &stats);
602
603         if (status != 0) {
604                 printf("Command failed\n");
605                 return;
606         }
607
608         /* Display stats */
609         printf("Pipeline %" PRIu32 " - stats for output port %" PRIu32 ":\n"
610                 "\tPkts in: %" PRIu64 "\n"
611                 "\tPkts dropped by AH: %" PRIu64 "\n"
612                 "\tPkts dropped by other: %" PRIu64 "\n",
613                 params->pipeline_id,
614                 params->port_out_id,
615                 stats.stats.n_pkts_in,
616                 stats.n_pkts_dropped_by_ah,
617                 stats.stats.n_pkts_drop);
618 }
619
620 cmdline_parse_token_string_t cmd_stats_port_out_p_string =
621         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, p_string,
622         "p");
623
624 cmdline_parse_token_num_t cmd_stats_port_out_pipeline_id =
625         TOKEN_NUM_INITIALIZER(struct cmd_stats_port_out_result, pipeline_id,
626                 UINT32);
627
628 cmdline_parse_token_string_t cmd_stats_port_out_stats_string =
629         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, stats_string,
630                 "stats");
631
632 cmdline_parse_token_string_t cmd_stats_port_out_port_string =
633         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, port_string,
634                 "port");
635
636 cmdline_parse_token_string_t cmd_stats_port_out_out_string =
637         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, out_string,
638                 "out");
639
640 cmdline_parse_token_num_t cmd_stats_port_out_port_out_id =
641         TOKEN_NUM_INITIALIZER(struct cmd_stats_port_out_result, port_out_id,
642                 UINT32);
643
644 cmdline_parse_inst_t cmd_stats_port_out = {
645         .f = cmd_stats_port_out_parsed,
646         .data = NULL,
647         .help_str = "Pipeline output port stats",
648         .tokens = {
649                 (void *) &cmd_stats_port_out_p_string,
650                 (void *) &cmd_stats_port_out_pipeline_id,
651                 (void *) &cmd_stats_port_out_stats_string,
652                 (void *) &cmd_stats_port_out_port_string,
653                 (void *) &cmd_stats_port_out_out_string,
654                 (void *) &cmd_stats_port_out_port_out_id,
655                 NULL,
656         },
657 };
658
659 /*
660  * stats table
661  */
662
663 struct cmd_stats_table_result {
664         cmdline_fixed_string_t p_string;
665         uint32_t pipeline_id;
666         cmdline_fixed_string_t stats_string;
667         cmdline_fixed_string_t table_string;
668         uint32_t table_id;
669 };
670
671 static void
672 cmd_stats_table_parsed(
673         void *parsed_result,
674         __rte_unused struct cmdline *cl,
675         void *data)
676 {
677         struct cmd_stats_table_result *params = parsed_result;
678         struct app_params *app = data;
679         struct rte_pipeline_table_stats stats;
680         int status;
681
682         status = app_pipeline_stats_table(app,
683                         params->pipeline_id,
684                         params->table_id,
685                         &stats);
686
687         if (status != 0) {
688                 printf("Command failed\n");
689                 return;
690         }
691
692         /* Display stats */
693         printf("Pipeline %" PRIu32 " - stats for table %" PRIu32 ":\n"
694                 "\tPkts in: %" PRIu64 "\n"
695                 "\tPkts in with lookup miss: %" PRIu64 "\n"
696                 "\tPkts in with lookup hit dropped by AH: %" PRIu64 "\n"
697                 "\tPkts in with lookup hit dropped by others: %" PRIu64 "\n"
698                 "\tPkts in with lookup miss dropped by AH: %" PRIu64 "\n"
699                 "\tPkts in with lookup miss dropped by others: %" PRIu64 "\n",
700                 params->pipeline_id,
701                 params->table_id,
702                 stats.stats.n_pkts_in,
703                 stats.stats.n_pkts_lookup_miss,
704                 stats.n_pkts_dropped_by_lkp_hit_ah,
705                 stats.n_pkts_dropped_lkp_hit,
706                 stats.n_pkts_dropped_by_lkp_miss_ah,
707                 stats.n_pkts_dropped_lkp_miss);
708 }
709
710 cmdline_parse_token_string_t cmd_stats_table_p_string =
711         TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, p_string,
712                 "p");
713
714 cmdline_parse_token_num_t cmd_stats_table_pipeline_id =
715         TOKEN_NUM_INITIALIZER(struct cmd_stats_table_result, pipeline_id,
716                 UINT32);
717
718 cmdline_parse_token_string_t cmd_stats_table_stats_string =
719         TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, stats_string,
720                 "stats");
721
722 cmdline_parse_token_string_t cmd_stats_table_table_string =
723         TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, table_string,
724                 "table");
725
726 cmdline_parse_token_num_t cmd_stats_table_table_id =
727         TOKEN_NUM_INITIALIZER(struct cmd_stats_table_result, table_id, UINT32);
728
729 cmdline_parse_inst_t cmd_stats_table = {
730         .f = cmd_stats_table_parsed,
731         .data = NULL,
732         .help_str = "Pipeline table stats",
733         .tokens = {
734                 (void *) &cmd_stats_table_p_string,
735                 (void *) &cmd_stats_table_pipeline_id,
736                 (void *) &cmd_stats_table_stats_string,
737                 (void *) &cmd_stats_table_table_string,
738                 (void *) &cmd_stats_table_table_id,
739                 NULL,
740         },
741 };
742
743 /*
744  * port in enable
745  */
746
747 struct cmd_port_in_enable_result {
748         cmdline_fixed_string_t p_string;
749         uint32_t pipeline_id;
750         cmdline_fixed_string_t port_string;
751         cmdline_fixed_string_t in_string;
752         uint32_t port_in_id;
753         cmdline_fixed_string_t enable_string;
754 };
755
756 static void
757 cmd_port_in_enable_parsed(
758         void *parsed_result,
759         __rte_unused struct cmdline *cl,
760         void *data)
761 {
762         struct cmd_port_in_enable_result *params = parsed_result;
763         struct app_params *app = data;
764         int status;
765
766         status = app_pipeline_port_in_enable(app,
767                         params->pipeline_id,
768                         params->port_in_id);
769
770         if (status != 0)
771                 printf("Command failed\n");
772 }
773
774 cmdline_parse_token_string_t cmd_port_in_enable_p_string =
775         TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, p_string,
776                 "p");
777
778 cmdline_parse_token_num_t cmd_port_in_enable_pipeline_id =
779         TOKEN_NUM_INITIALIZER(struct cmd_port_in_enable_result, pipeline_id,
780                 UINT32);
781
782 cmdline_parse_token_string_t cmd_port_in_enable_port_string =
783         TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, port_string,
784         "port");
785
786 cmdline_parse_token_string_t cmd_port_in_enable_in_string =
787         TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, in_string,
788                 "in");
789
790 cmdline_parse_token_num_t cmd_port_in_enable_port_in_id =
791         TOKEN_NUM_INITIALIZER(struct cmd_port_in_enable_result, port_in_id,
792                 UINT32);
793
794 cmdline_parse_token_string_t cmd_port_in_enable_enable_string =
795         TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result,
796                 enable_string, "enable");
797
798 cmdline_parse_inst_t cmd_port_in_enable = {
799         .f = cmd_port_in_enable_parsed,
800         .data = NULL,
801         .help_str = "Pipeline input port enable",
802         .tokens = {
803                 (void *) &cmd_port_in_enable_p_string,
804                 (void *) &cmd_port_in_enable_pipeline_id,
805                 (void *) &cmd_port_in_enable_port_string,
806                 (void *) &cmd_port_in_enable_in_string,
807                 (void *) &cmd_port_in_enable_port_in_id,
808                 (void *) &cmd_port_in_enable_enable_string,
809                 NULL,
810         },
811 };
812
813 /*
814  * port in disable
815  */
816
817 struct cmd_port_in_disable_result {
818         cmdline_fixed_string_t p_string;
819         uint32_t pipeline_id;
820         cmdline_fixed_string_t port_string;
821         cmdline_fixed_string_t in_string;
822         uint32_t port_in_id;
823         cmdline_fixed_string_t disable_string;
824 };
825
826 static void
827 cmd_port_in_disable_parsed(
828         void *parsed_result,
829         __rte_unused struct cmdline *cl,
830         void *data)
831 {
832         struct cmd_port_in_disable_result *params = parsed_result;
833         struct app_params *app = data;
834         int status;
835
836         status = app_pipeline_port_in_disable(app,
837                         params->pipeline_id,
838                         params->port_in_id);
839
840         if (status != 0)
841                 printf("Command failed\n");
842 }
843
844 cmdline_parse_token_string_t cmd_port_in_disable_p_string =
845         TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, p_string,
846                 "p");
847
848 cmdline_parse_token_num_t cmd_port_in_disable_pipeline_id =
849         TOKEN_NUM_INITIALIZER(struct cmd_port_in_disable_result, pipeline_id,
850                 UINT32);
851
852 cmdline_parse_token_string_t cmd_port_in_disable_port_string =
853         TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, port_string,
854                 "port");
855
856 cmdline_parse_token_string_t cmd_port_in_disable_in_string =
857         TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, in_string,
858                 "in");
859
860 cmdline_parse_token_num_t cmd_port_in_disable_port_in_id =
861         TOKEN_NUM_INITIALIZER(struct cmd_port_in_disable_result, port_in_id,
862                 UINT32);
863
864 cmdline_parse_token_string_t cmd_port_in_disable_disable_string =
865         TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result,
866                 disable_string, "disable");
867
868 cmdline_parse_inst_t cmd_port_in_disable = {
869         .f = cmd_port_in_disable_parsed,
870         .data = NULL,
871         .help_str = "Pipeline input port disable",
872         .tokens = {
873                 (void *) &cmd_port_in_disable_p_string,
874                 (void *) &cmd_port_in_disable_pipeline_id,
875                 (void *) &cmd_port_in_disable_port_string,
876                 (void *) &cmd_port_in_disable_in_string,
877                 (void *) &cmd_port_in_disable_port_in_id,
878                 (void *) &cmd_port_in_disable_disable_string,
879                 NULL,
880         },
881 };
882
883 /*
884  * link config
885  */
886
887 static void
888 print_link_info(struct app_link_params *p)
889 {
890         struct rte_eth_stats stats;
891         struct ether_addr *mac_addr;
892         uint32_t netmask = (~0U) << (32 - p->depth);
893         uint32_t host = p->ip & netmask;
894         uint32_t bcast = host | (~netmask);
895
896         memset(&stats, 0, sizeof(stats));
897         rte_eth_stats_get(p->pmd_id, &stats);
898
899         mac_addr = (struct ether_addr *) &p->mac_addr;
900
901         if (strlen(p->pci_bdf))
902                 printf("%s(%s): flags=<%s>\n",
903                         p->name,
904                         p->pci_bdf,
905                         (p->state) ? "UP" : "DOWN");
906         else
907                 printf("%s: flags=<%s>\n",
908                         p->name,
909                         (p->state) ? "UP" : "DOWN");
910
911         if (p->ip)
912                 printf("\tinet %" PRIu32 ".%" PRIu32
913                         ".%" PRIu32 ".%" PRIu32
914                         " netmask %" PRIu32 ".%" PRIu32
915                         ".%" PRIu32 ".%" PRIu32 " "
916                         "broadcast %" PRIu32 ".%" PRIu32
917                         ".%" PRIu32 ".%" PRIu32 "\n",
918                         (p->ip >> 24) & 0xFF,
919                         (p->ip >> 16) & 0xFF,
920                         (p->ip >> 8) & 0xFF,
921                         p->ip & 0xFF,
922                         (netmask >> 24) & 0xFF,
923                         (netmask >> 16) & 0xFF,
924                         (netmask >> 8) & 0xFF,
925                         netmask & 0xFF,
926                         (bcast >> 24) & 0xFF,
927                         (bcast >> 16) & 0xFF,
928                         (bcast >> 8) & 0xFF,
929                         bcast & 0xFF);
930
931         printf("\tether %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32
932                 ":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\n",
933                 mac_addr->addr_bytes[0],
934                 mac_addr->addr_bytes[1],
935                 mac_addr->addr_bytes[2],
936                 mac_addr->addr_bytes[3],
937                 mac_addr->addr_bytes[4],
938                 mac_addr->addr_bytes[5]);
939
940         printf("\tRX packets %" PRIu64
941                 "  bytes %" PRIu64
942                 "\n",
943                 stats.ipackets,
944                 stats.ibytes);
945
946         printf("\tRX errors %" PRIu64
947                 "  missed %" PRIu64
948                 "  no-mbuf %" PRIu64
949                 "\n",
950                 stats.ierrors,
951                 stats.imissed,
952                 stats.rx_nombuf);
953
954         printf("\tTX packets %" PRIu64
955                 "  bytes %" PRIu64 "\n",
956                 stats.opackets,
957                 stats.obytes);
958
959         printf("\tTX errors %" PRIu64
960                 "\n",
961                 stats.oerrors);
962
963         printf("\n");
964 }
965
966 struct cmd_link_config_result {
967         cmdline_fixed_string_t link_string;
968         uint32_t link_id;
969         cmdline_fixed_string_t config_string;
970         cmdline_ipaddr_t ip;
971         uint32_t depth;
972 };
973
974 static void
975 cmd_link_config_parsed(
976         void *parsed_result,
977         __attribute__((unused)) struct cmdline *cl,
978          void *data)
979 {
980         struct cmd_link_config_result *params = parsed_result;
981         struct app_params *app = data;
982         int status;
983
984         uint32_t link_id = params->link_id;
985         uint32_t ip  = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
986         uint32_t depth = params->depth;
987
988         status = app_link_config(app, link_id, ip, depth);
989         if (status)
990                 printf("Command failed\n");
991         else {
992                 struct app_link_params *p;
993
994                 APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
995                 print_link_info(p);
996         }
997 }
998
999 cmdline_parse_token_string_t cmd_link_config_link_string =
1000         TOKEN_STRING_INITIALIZER(struct cmd_link_config_result, link_string,
1001                 "link");
1002
1003 cmdline_parse_token_num_t cmd_link_config_link_id =
1004         TOKEN_NUM_INITIALIZER(struct cmd_link_config_result, link_id, UINT32);
1005
1006 cmdline_parse_token_string_t cmd_link_config_config_string =
1007         TOKEN_STRING_INITIALIZER(struct cmd_link_config_result, config_string,
1008                 "config");
1009
1010 cmdline_parse_token_ipaddr_t cmd_link_config_ip =
1011         TOKEN_IPV4_INITIALIZER(struct cmd_link_config_result, ip);
1012
1013 cmdline_parse_token_num_t cmd_link_config_depth =
1014         TOKEN_NUM_INITIALIZER(struct cmd_link_config_result, depth, UINT32);
1015
1016 cmdline_parse_inst_t cmd_link_config = {
1017         .f = cmd_link_config_parsed,
1018         .data = NULL,
1019         .help_str = "Link configuration",
1020         .tokens = {
1021                 (void *)&cmd_link_config_link_string,
1022                 (void *)&cmd_link_config_link_id,
1023                 (void *)&cmd_link_config_config_string,
1024                 (void *)&cmd_link_config_ip,
1025                 (void *)&cmd_link_config_depth,
1026                 NULL,
1027         },
1028 };
1029
1030 /*
1031  * link up
1032  */
1033
1034 struct cmd_link_up_result {
1035         cmdline_fixed_string_t link_string;
1036         uint32_t link_id;
1037         cmdline_fixed_string_t up_string;
1038 };
1039
1040 static void
1041 cmd_link_up_parsed(
1042         void *parsed_result,
1043         __attribute__((unused)) struct cmdline *cl,
1044         void *data)
1045 {
1046         struct cmd_link_up_result *params = parsed_result;
1047         struct app_params *app = data;
1048         int status;
1049
1050         status = app_link_up(app, params->link_id);
1051         if (status != 0)
1052                 printf("Command failed\n");
1053         else {
1054                 struct app_link_params *p;
1055
1056                 APP_PARAM_FIND_BY_ID(app->link_params, "LINK", params->link_id,
1057                         p);
1058                 print_link_info(p);
1059         }
1060 }
1061
1062 cmdline_parse_token_string_t cmd_link_up_link_string =
1063         TOKEN_STRING_INITIALIZER(struct cmd_link_up_result, link_string,
1064                 "link");
1065
1066 cmdline_parse_token_num_t cmd_link_up_link_id =
1067         TOKEN_NUM_INITIALIZER(struct cmd_link_up_result, link_id, UINT32);
1068
1069 cmdline_parse_token_string_t cmd_link_up_up_string =
1070         TOKEN_STRING_INITIALIZER(struct cmd_link_up_result, up_string, "up");
1071
1072 cmdline_parse_inst_t cmd_link_up = {
1073         .f = cmd_link_up_parsed,
1074         .data = NULL,
1075         .help_str = "Link UP",
1076         .tokens = {
1077                 (void *)&cmd_link_up_link_string,
1078                 (void *)&cmd_link_up_link_id,
1079                 (void *)&cmd_link_up_up_string,
1080                 NULL,
1081         },
1082 };
1083
1084 /*
1085  * link down
1086  */
1087
1088 struct cmd_link_down_result {
1089         cmdline_fixed_string_t link_string;
1090         uint32_t link_id;
1091         cmdline_fixed_string_t down_string;
1092 };
1093
1094 static void
1095 cmd_link_down_parsed(
1096         void *parsed_result,
1097         __attribute__((unused)) struct cmdline *cl,
1098         void *data)
1099 {
1100         struct cmd_link_down_result *params = parsed_result;
1101         struct app_params *app = data;
1102         int status;
1103
1104         status = app_link_down(app, params->link_id);
1105         if (status != 0)
1106                 printf("Command failed\n");
1107         else {
1108                 struct app_link_params *p;
1109
1110                 APP_PARAM_FIND_BY_ID(app->link_params, "LINK", params->link_id,
1111                         p);
1112                 print_link_info(p);
1113         }
1114 }
1115
1116 cmdline_parse_token_string_t cmd_link_down_link_string =
1117         TOKEN_STRING_INITIALIZER(struct cmd_link_down_result, link_string,
1118                 "link");
1119
1120 cmdline_parse_token_num_t cmd_link_down_link_id =
1121         TOKEN_NUM_INITIALIZER(struct cmd_link_down_result, link_id, UINT32);
1122
1123 cmdline_parse_token_string_t cmd_link_down_down_string =
1124         TOKEN_STRING_INITIALIZER(struct cmd_link_down_result, down_string,
1125                 "down");
1126
1127 cmdline_parse_inst_t cmd_link_down = {
1128         .f = cmd_link_down_parsed,
1129         .data = NULL,
1130         .help_str = "Link DOWN",
1131         .tokens = {
1132                 (void *) &cmd_link_down_link_string,
1133                 (void *) &cmd_link_down_link_id,
1134                 (void *) &cmd_link_down_down_string,
1135                 NULL,
1136         },
1137 };
1138
1139 /*
1140  * link ls
1141  */
1142
1143 struct cmd_link_ls_result {
1144         cmdline_fixed_string_t link_string;
1145         cmdline_fixed_string_t ls_string;
1146 };
1147
1148 static void
1149 cmd_link_ls_parsed(
1150         __attribute__((unused)) void *parsed_result,
1151         __attribute__((unused)) struct cmdline *cl,
1152          void *data)
1153 {
1154         struct app_params *app = data;
1155         uint32_t link_id;
1156
1157         for (link_id = 0; link_id < app->n_links; link_id++) {
1158                 struct app_link_params *p;
1159
1160                 APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
1161                 print_link_info(p);
1162         }
1163 }
1164
1165 cmdline_parse_token_string_t cmd_link_ls_link_string =
1166         TOKEN_STRING_INITIALIZER(struct cmd_link_ls_result, link_string,
1167                 "link");
1168
1169 cmdline_parse_token_string_t cmd_link_ls_ls_string =
1170         TOKEN_STRING_INITIALIZER(struct cmd_link_ls_result, ls_string, "ls");
1171
1172 cmdline_parse_inst_t cmd_link_ls = {
1173         .f = cmd_link_ls_parsed,
1174         .data = NULL,
1175         .help_str = "Link list",
1176         .tokens = {
1177                 (void *)&cmd_link_ls_link_string,
1178                 (void *)&cmd_link_ls_ls_string,
1179                 NULL,
1180         },
1181 };
1182
1183 /*
1184  * quit
1185  */
1186
1187 struct cmd_quit_result {
1188         cmdline_fixed_string_t quit;
1189 };
1190
1191 static void
1192 cmd_quit_parsed(
1193         __rte_unused void *parsed_result,
1194         struct cmdline *cl,
1195         __rte_unused void *data)
1196 {
1197         cmdline_quit(cl);
1198 }
1199
1200 static cmdline_parse_token_string_t cmd_quit_quit =
1201         TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
1202
1203 static cmdline_parse_inst_t cmd_quit = {
1204         .f = cmd_quit_parsed,
1205         .data = NULL,
1206         .help_str = "Quit",
1207         .tokens = {
1208                 (void *) &cmd_quit_quit,
1209                 NULL,
1210         },
1211 };
1212
1213 /*
1214  * run
1215  */
1216
1217 static void
1218 app_run_file(
1219         cmdline_parse_ctx_t *ctx,
1220         const char *file_name)
1221 {
1222         struct cmdline *file_cl;
1223         int fd;
1224
1225         fd = open(file_name, O_RDONLY);
1226         if (fd < 0) {
1227                 printf("Cannot open file \"%s\"\n", file_name);
1228                 return;
1229         }
1230
1231         file_cl = cmdline_new(ctx, "", fd, 1);
1232         cmdline_interact(file_cl);
1233         close(fd);
1234 }
1235
1236 struct cmd_run_file_result {
1237         cmdline_fixed_string_t run_string;
1238         char file_name[APP_FILE_NAME_SIZE];
1239 };
1240
1241 static void
1242 cmd_run_parsed(
1243         void *parsed_result,
1244         struct cmdline *cl,
1245         __attribute__((unused)) void *data)
1246 {
1247         struct cmd_run_file_result *params = parsed_result;
1248
1249         app_run_file(cl->ctx, params->file_name);
1250 }
1251
1252 cmdline_parse_token_string_t cmd_run_run_string =
1253         TOKEN_STRING_INITIALIZER(struct cmd_run_file_result, run_string,
1254                 "run");
1255
1256 cmdline_parse_token_string_t cmd_run_file_name =
1257         TOKEN_STRING_INITIALIZER(struct cmd_run_file_result, file_name, NULL);
1258
1259 cmdline_parse_inst_t cmd_run = {
1260         .f = cmd_run_parsed,
1261         .data = NULL,
1262         .help_str = "Run CLI script file",
1263         .tokens = {
1264                 (void *) &cmd_run_run_string,
1265                 (void *) &cmd_run_file_name,
1266                 NULL,
1267         },
1268 };
1269
1270 static cmdline_parse_ctx_t pipeline_common_cmds[] = {
1271         (cmdline_parse_inst_t *) &cmd_quit,
1272         (cmdline_parse_inst_t *) &cmd_run,
1273
1274         (cmdline_parse_inst_t *) &cmd_link_config,
1275         (cmdline_parse_inst_t *) &cmd_link_up,
1276         (cmdline_parse_inst_t *) &cmd_link_down,
1277         (cmdline_parse_inst_t *) &cmd_link_ls,
1278
1279         (cmdline_parse_inst_t *) &cmd_ping,
1280         (cmdline_parse_inst_t *) &cmd_stats_port_in,
1281         (cmdline_parse_inst_t *) &cmd_stats_port_out,
1282         (cmdline_parse_inst_t *) &cmd_stats_table,
1283         (cmdline_parse_inst_t *) &cmd_port_in_enable,
1284         (cmdline_parse_inst_t *) &cmd_port_in_disable,
1285         NULL,
1286 };
1287
1288 int
1289 app_pipeline_common_cmd_push(struct app_params *app)
1290 {
1291         uint32_t n_cmds, i;
1292
1293         /* Check for available slots in the application commands array */
1294         n_cmds = RTE_DIM(pipeline_common_cmds) - 1;
1295         if (n_cmds > APP_MAX_CMDS - app->n_cmds)
1296                 return -ENOMEM;
1297
1298         /* Push pipeline commands into the application */
1299         memcpy(&app->cmds[app->n_cmds],
1300                 pipeline_common_cmds,
1301                 n_cmds * sizeof(cmdline_parse_ctx_t));
1302
1303         for (i = 0; i < n_cmds; i++)
1304                 app->cmds[app->n_cmds + i]->data = app;
1305
1306         app->n_cmds += n_cmds;
1307         app->cmds[app->n_cmds] = NULL;
1308
1309         return 0;
1310 }