remove unused ring includes
[dpdk.git] / examples / ip_pipeline / pipeline / pipeline_common_fe.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2016 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_malloc.h>
40 #include <cmdline_rdline.h>
41 #include <cmdline_parse.h>
42 #include <cmdline_parse_num.h>
43 #include <cmdline_parse_string.h>
44 #include <cmdline.h>
45
46 #include "pipeline_common_fe.h"
47 #include "parser.h"
48
49 struct app_link_params *
50 app_pipeline_track_pktq_out_to_link(struct app_params *app,
51         uint32_t pipeline_id,
52         uint32_t pktq_out_id)
53 {
54         struct app_pipeline_params *p;
55
56         /* Check input arguments */
57         if (app == NULL)
58                 return NULL;
59
60         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
61         if (p == NULL)
62                 return NULL;
63
64         for ( ; ; ) {
65                 struct app_pktq_out_params *pktq_out =
66                         &p->pktq_out[pktq_out_id];
67
68                 switch (pktq_out->type) {
69                 case APP_PKTQ_OUT_HWQ:
70                 {
71                         struct app_pktq_hwq_out_params *hwq_out;
72
73                         hwq_out = &app->hwq_out_params[pktq_out->id];
74
75                         return app_get_link_for_txq(app, hwq_out);
76                 }
77
78                 case APP_PKTQ_OUT_SWQ:
79                 {
80                         struct pipeline_params pp;
81                         struct pipeline_type *ptype;
82                         struct app_pktq_swq_params *swq;
83                         uint32_t pktq_in_id;
84                         int status;
85
86                         swq = &app->swq_params[pktq_out->id];
87                         p = app_swq_get_reader(app, swq, &pktq_in_id);
88                         if (p == NULL)
89                                 return NULL;
90
91                         ptype = app_pipeline_type_find(app, p->type);
92                         if ((ptype == NULL) || (ptype->fe_ops->f_track == NULL))
93                                 return NULL;
94
95                         app_pipeline_params_get(app, p, &pp);
96                         status = ptype->fe_ops->f_track(&pp,
97                                 pktq_in_id,
98                                 &pktq_out_id);
99                         if (status)
100                                 return NULL;
101
102                         break;
103                 }
104
105                 case APP_PKTQ_OUT_TM:
106                 {
107                         struct pipeline_params pp;
108                         struct pipeline_type *ptype;
109                         struct app_pktq_tm_params *tm;
110                         uint32_t pktq_in_id;
111                         int status;
112
113                         tm = &app->tm_params[pktq_out->id];
114                         p = app_tm_get_reader(app, tm, &pktq_in_id);
115                         if (p == NULL)
116                                 return NULL;
117
118                         ptype = app_pipeline_type_find(app, p->type);
119                         if ((ptype == NULL) || (ptype->fe_ops->f_track == NULL))
120                                 return NULL;
121
122                         app_pipeline_params_get(app, p, &pp);
123                         status = ptype->fe_ops->f_track(&pp,
124                                 pktq_in_id,
125                                 &pktq_out_id);
126                         if (status)
127                                 return NULL;
128
129                         break;
130                 }
131
132                 case APP_PKTQ_OUT_KNI:
133                 {
134                         struct pipeline_params pp;
135                         struct pipeline_type *ptype;
136                         struct app_pktq_kni_params *kni;
137                         uint32_t pktq_in_id;
138                         int status;
139
140                         kni = &app->kni_params[pktq_out->id];
141                         p = app_kni_get_reader(app, kni, &pktq_in_id);
142                         if (p == NULL)
143                                 return NULL;
144
145                         ptype = app_pipeline_type_find(app, p->type);
146                         if ((ptype == NULL) || (ptype->fe_ops->f_track == NULL))
147                                 return NULL;
148
149                         app_pipeline_params_get(app, p, &pp);
150                         status = ptype->fe_ops->f_track(&pp,
151                                 pktq_in_id,
152                                 &pktq_out_id);
153                         if (status)
154                                 return NULL;
155
156                         break;
157                 }
158
159                 case APP_PKTQ_OUT_SINK:
160                 default:
161                         return NULL;
162                 }
163         }
164 }
165
166 int
167 app_pipeline_track_default(struct pipeline_params *p,
168         uint32_t port_in,
169         uint32_t *port_out)
170 {
171         /* Check input arguments */
172         if ((p == NULL) ||
173                 (port_in >= p->n_ports_in) ||
174                 (port_out == NULL))
175                 return -1;
176
177         if (p->n_ports_out == 1) {
178                 *port_out = 0;
179                 return 0;
180         }
181
182         return -1;
183 }
184
185 int
186 app_pipeline_ping(struct app_params *app,
187         uint32_t pipeline_id)
188 {
189         struct app_pipeline_params *p;
190         struct pipeline_msg_req *req;
191         struct pipeline_msg_rsp *rsp;
192         int status = 0;
193
194         /* Check input arguments */
195         if (app == NULL)
196                 return -1;
197
198         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
199         if (p == NULL)
200                 return -1;
201
202         /* Message buffer allocation */
203         req = app_msg_alloc(app);
204         if (req == NULL)
205                 return -1;
206
207         /* Fill in request */
208         req->type = PIPELINE_MSG_REQ_PING;
209
210         /* Send request and wait for response */
211         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
212         if (rsp == NULL)
213                 return -1;
214
215         /* Check response */
216         status = rsp->status;
217
218         /* Message buffer free */
219         app_msg_free(app, rsp);
220
221         return status;
222 }
223
224 int
225 app_pipeline_stats_port_in(struct app_params *app,
226         uint32_t pipeline_id,
227         uint32_t port_id,
228         struct rte_pipeline_port_in_stats *stats)
229 {
230         struct app_pipeline_params *p;
231         struct pipeline_stats_msg_req *req;
232         struct pipeline_stats_port_in_msg_rsp *rsp;
233         int status = 0;
234
235         /* Check input arguments */
236         if ((app == NULL) ||
237                 (stats == NULL))
238                 return -1;
239
240         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
241         if ((p == NULL) ||
242                 (port_id >= p->n_pktq_in))
243                 return -1;
244
245         /* Message buffer allocation */
246         req = app_msg_alloc(app);
247         if (req == NULL)
248                 return -1;
249
250         /* Fill in request */
251         req->type = PIPELINE_MSG_REQ_STATS_PORT_IN;
252         req->id = port_id;
253
254         /* Send request and wait for response */
255         rsp = (struct pipeline_stats_port_in_msg_rsp *)
256                 app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
257         if (rsp == NULL)
258                 return -1;
259
260         /* Check response */
261         status = rsp->status;
262         if (status == 0)
263                 memcpy(stats, &rsp->stats, sizeof(rsp->stats));
264
265         /* Message buffer free */
266         app_msg_free(app, rsp);
267
268         return status;
269 }
270
271 int
272 app_pipeline_stats_port_out(struct app_params *app,
273         uint32_t pipeline_id,
274         uint32_t port_id,
275         struct rte_pipeline_port_out_stats *stats)
276 {
277         struct app_pipeline_params *p;
278         struct pipeline_stats_msg_req *req;
279         struct pipeline_stats_port_out_msg_rsp *rsp;
280         int status = 0;
281
282         /* Check input arguments */
283         if ((app == NULL) ||
284                 (pipeline_id >= app->n_pipelines) ||
285                 (stats == NULL))
286                 return -1;
287
288         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
289         if ((p == NULL) ||
290                 (port_id >= p->n_pktq_out))
291                 return -1;
292
293         /* Message buffer allocation */
294         req = app_msg_alloc(app);
295         if (req == NULL)
296                 return -1;
297
298         /* Fill in request */
299         req->type = PIPELINE_MSG_REQ_STATS_PORT_OUT;
300         req->id = port_id;
301
302         /* Send request and wait for response */
303         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
304         if (rsp == NULL)
305                 return -1;
306
307         /* Check response */
308         status = rsp->status;
309         if (status == 0)
310                 memcpy(stats, &rsp->stats, sizeof(rsp->stats));
311
312         /* Message buffer free */
313         app_msg_free(app, rsp);
314
315         return status;
316 }
317
318 int
319 app_pipeline_stats_table(struct app_params *app,
320         uint32_t pipeline_id,
321         uint32_t table_id,
322         struct rte_pipeline_table_stats *stats)
323 {
324         struct app_pipeline_params *p;
325         struct pipeline_stats_msg_req *req;
326         struct pipeline_stats_table_msg_rsp *rsp;
327         int status = 0;
328
329         /* Check input arguments */
330         if ((app == NULL) ||
331                 (stats == NULL))
332                 return -1;
333
334         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
335         if (p == NULL)
336                 return -1;
337
338         /* Message buffer allocation */
339         req = app_msg_alloc(app);
340         if (req == NULL)
341                 return -1;
342
343         /* Fill in request */
344         req->type = PIPELINE_MSG_REQ_STATS_TABLE;
345         req->id = table_id;
346
347         /* Send request and wait for response */
348         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
349         if (rsp == NULL)
350                 return -1;
351
352         /* Check response */
353         status = rsp->status;
354         if (status == 0)
355                 memcpy(stats, &rsp->stats, sizeof(rsp->stats));
356
357         /* Message buffer free */
358         app_msg_free(app, rsp);
359
360         return status;
361 }
362
363 int
364 app_pipeline_port_in_enable(struct app_params *app,
365         uint32_t pipeline_id,
366         uint32_t port_id)
367 {
368         struct app_pipeline_params *p;
369         struct pipeline_port_in_msg_req *req;
370         struct pipeline_msg_rsp *rsp;
371         int status = 0;
372
373         /* Check input arguments */
374         if (app == NULL)
375                 return -1;
376
377         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
378         if ((p == NULL) ||
379                 (port_id >= p->n_pktq_in))
380                 return -1;
381
382         /* Message buffer allocation */
383         req = app_msg_alloc(app);
384         if (req == NULL)
385                 return -1;
386
387         /* Fill in request */
388         req->type = PIPELINE_MSG_REQ_PORT_IN_ENABLE;
389         req->port_id = port_id;
390
391         /* Send request and wait for response */
392         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
393         if (rsp == NULL)
394                 return -1;
395
396         /* Check response */
397         status = rsp->status;
398
399         /* Message buffer free */
400         app_msg_free(app, rsp);
401
402         return status;
403 }
404
405 int
406 app_pipeline_port_in_disable(struct app_params *app,
407         uint32_t pipeline_id,
408         uint32_t port_id)
409 {
410         struct app_pipeline_params *p;
411         struct pipeline_port_in_msg_req *req;
412         struct pipeline_msg_rsp *rsp;
413         int status = 0;
414
415         /* Check input arguments */
416         if (app == NULL)
417                 return -1;
418
419         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
420         if ((p == NULL) ||
421                 (port_id >= p->n_pktq_in))
422                 return -1;
423
424         /* Message buffer allocation */
425         req = app_msg_alloc(app);
426         if (req == NULL)
427                 return -1;
428
429         /* Fill in request */
430         req->type = PIPELINE_MSG_REQ_PORT_IN_DISABLE;
431         req->port_id = port_id;
432
433         /* Send request and wait for response */
434         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
435         if (rsp == NULL)
436                 return -1;
437
438         /* Check response */
439         status = rsp->status;
440
441         /* Message buffer free */
442         app_msg_free(app, rsp);
443
444         return status;
445 }
446
447 int
448 app_link_set_op(struct app_params *app,
449         uint32_t link_id,
450         uint32_t pipeline_id,
451         app_link_op op,
452         void *arg)
453 {
454         struct app_pipeline_params *pp;
455         struct app_link_params *lp;
456         struct app_link_data *ld;
457         uint32_t ppos, lpos;
458
459         /* Check input arguments */
460         if ((app == NULL) ||
461                 (op == NULL))
462                 return -1;
463
464         APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, lp);
465         if (lp == NULL)
466                 return -1;
467         lpos = lp - app->link_params;
468         ld = &app->link_data[lpos];
469
470         APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, pp);
471         if (pp == NULL)
472                 return -1;
473         ppos = pp - app->pipeline_params;
474
475         ld->f_link[ppos] = op;
476         ld->arg[ppos] = arg;
477
478         return 0;
479 }
480
481 int
482 app_link_config(struct app_params *app,
483         uint32_t link_id,
484         uint32_t ip,
485         uint32_t depth)
486 {
487         struct app_link_params *p;
488         uint32_t i, netmask, host, bcast;
489
490         /* Check input arguments */
491         if (app == NULL)
492                 return -1;
493
494         APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
495         if (p == NULL) {
496                 APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link",
497                         link_id);
498                 return -1;
499         }
500
501         if (p->state) {
502                 APP_LOG(app, HIGH, "%s is UP, please bring it DOWN first",
503                         p->name);
504                 return -1;
505         }
506
507         netmask = (~0U) << (32 - depth);
508         host = ip & netmask;
509         bcast = host | (~netmask);
510
511         if ((ip == 0) ||
512                 (ip == UINT32_MAX) ||
513                 (ip == host) ||
514                 (ip == bcast)) {
515                 APP_LOG(app, HIGH, "Illegal IP address");
516                 return -1;
517         }
518
519         for (i = 0; i < app->n_links; i++) {
520                 struct app_link_params *link = &app->link_params[i];
521
522                 if (strcmp(p->name, link->name) == 0)
523                         continue;
524
525                 if (link->ip == ip) {
526                         APP_LOG(app, HIGH,
527                                 "%s is already assigned this IP address",
528                                 link->name);
529                         return -1;
530                 }
531         }
532
533         if ((depth == 0) || (depth > 32)) {
534                 APP_LOG(app, HIGH, "Illegal value for depth parameter "
535                         "(%" PRIu32 ")",
536                         depth);
537                 return -1;
538         }
539
540         /* Save link parameters */
541         p->ip = ip;
542         p->depth = depth;
543
544         return 0;
545 }
546
547 int
548 app_link_up(struct app_params *app,
549         uint32_t link_id)
550 {
551         struct app_link_params *p;
552         struct app_link_data *d;
553         int i;
554
555         /* Check input arguments */
556         if (app == NULL)
557                 return -1;
558
559         APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
560         if (p == NULL) {
561                 APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link",
562                         link_id);
563                 return -1;
564         }
565
566         d = &app->link_data[p - app->link_params];
567
568         /* Check link state */
569         if (p->state) {
570                 APP_LOG(app, HIGH, "%s is already UP", p->name);
571                 return 0;
572         }
573
574         /* Check that IP address is valid */
575         if (p->ip == 0) {
576                 APP_LOG(app, HIGH, "%s IP address is not set", p->name);
577                 return 0;
578         }
579
580         app_link_up_internal(app, p);
581
582         /* Callbacks */
583         for (i = 0; i < APP_MAX_PIPELINES; i++)
584                 if (d->f_link[i])
585                         d->f_link[i](app, link_id, 1, d->arg[i]);
586
587         return 0;
588 }
589
590 int
591 app_link_down(struct app_params *app,
592         uint32_t link_id)
593 {
594         struct app_link_params *p;
595         struct app_link_data *d;
596         uint32_t i;
597
598         /* Check input arguments */
599         if (app == NULL)
600                 return -1;
601
602         APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
603         if (p == NULL) {
604                 APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link",
605                         link_id);
606                 return -1;
607         }
608
609         d = &app->link_data[p - app->link_params];
610
611         /* Check link state */
612         if (p->state == 0) {
613                 APP_LOG(app, HIGH, "%s is already DOWN", p->name);
614                 return 0;
615         }
616
617         app_link_down_internal(app, p);
618
619         /* Callbacks */
620         for (i = 0; i < APP_MAX_PIPELINES; i++)
621                 if (d->f_link[i])
622                         d->f_link[i](app, link_id, 0, d->arg[i]);
623
624         return 0;
625 }
626
627 /*
628  * ping
629  */
630
631 struct cmd_ping_result {
632         cmdline_fixed_string_t p_string;
633         uint32_t pipeline_id;
634         cmdline_fixed_string_t ping_string;
635 };
636
637 static void
638 cmd_ping_parsed(
639         void *parsed_result,
640         __rte_unused struct cmdline *cl,
641         void *data)
642 {
643         struct cmd_ping_result *params = parsed_result;
644         struct app_params *app = data;
645         int status;
646
647         status = app_pipeline_ping(app, params->pipeline_id);
648         if (status != 0)
649                 printf("Command failed\n");
650 }
651
652 static cmdline_parse_token_string_t cmd_ping_p_string =
653         TOKEN_STRING_INITIALIZER(struct cmd_ping_result, p_string, "p");
654
655 static cmdline_parse_token_num_t cmd_ping_pipeline_id =
656         TOKEN_NUM_INITIALIZER(struct cmd_ping_result, pipeline_id, UINT32);
657
658 static cmdline_parse_token_string_t cmd_ping_ping_string =
659         TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping_string, "ping");
660
661 static cmdline_parse_inst_t cmd_ping = {
662         .f = cmd_ping_parsed,
663         .data = NULL,
664         .help_str = "Pipeline ping",
665         .tokens = {
666                 (void *) &cmd_ping_p_string,
667                 (void *) &cmd_ping_pipeline_id,
668                 (void *) &cmd_ping_ping_string,
669                 NULL,
670         },
671 };
672
673 /*
674  * stats port in
675  */
676
677 struct cmd_stats_port_in_result {
678         cmdline_fixed_string_t p_string;
679         uint32_t pipeline_id;
680         cmdline_fixed_string_t stats_string;
681         cmdline_fixed_string_t port_string;
682         cmdline_fixed_string_t in_string;
683         uint32_t port_in_id;
684
685 };
686
687 static void
688 cmd_stats_port_in_parsed(
689         void *parsed_result,
690         __rte_unused struct cmdline *cl,
691         void *data)
692 {
693         struct cmd_stats_port_in_result *params = parsed_result;
694         struct app_params *app = data;
695         struct rte_pipeline_port_in_stats stats;
696         int status;
697
698         status = app_pipeline_stats_port_in(app,
699                         params->pipeline_id,
700                         params->port_in_id,
701                         &stats);
702
703         if (status != 0) {
704                 printf("Command failed\n");
705                 return;
706         }
707
708         /* Display stats */
709         printf("Pipeline %" PRIu32 " - stats for input port %" PRIu32 ":\n"
710                 "\tPkts in: %" PRIu64 "\n"
711                 "\tPkts dropped by AH: %" PRIu64 "\n"
712                 "\tPkts dropped by other: %" PRIu64 "\n",
713                 params->pipeline_id,
714                 params->port_in_id,
715                 stats.stats.n_pkts_in,
716                 stats.n_pkts_dropped_by_ah,
717                 stats.stats.n_pkts_drop);
718 }
719
720 static cmdline_parse_token_string_t cmd_stats_port_in_p_string =
721         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, p_string,
722                 "p");
723
724 static cmdline_parse_token_num_t cmd_stats_port_in_pipeline_id =
725         TOKEN_NUM_INITIALIZER(struct cmd_stats_port_in_result, pipeline_id,
726                 UINT32);
727
728 static cmdline_parse_token_string_t cmd_stats_port_in_stats_string =
729         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, stats_string,
730                 "stats");
731
732 static cmdline_parse_token_string_t cmd_stats_port_in_port_string =
733         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, port_string,
734                 "port");
735
736 static cmdline_parse_token_string_t cmd_stats_port_in_in_string =
737         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, in_string,
738                 "in");
739
740         cmdline_parse_token_num_t cmd_stats_port_in_port_in_id =
741         TOKEN_NUM_INITIALIZER(struct cmd_stats_port_in_result, port_in_id,
742                 UINT32);
743
744 static cmdline_parse_inst_t cmd_stats_port_in = {
745         .f = cmd_stats_port_in_parsed,
746         .data = NULL,
747         .help_str = "Pipeline input port stats",
748         .tokens = {
749                 (void *) &cmd_stats_port_in_p_string,
750                 (void *) &cmd_stats_port_in_pipeline_id,
751                 (void *) &cmd_stats_port_in_stats_string,
752                 (void *) &cmd_stats_port_in_port_string,
753                 (void *) &cmd_stats_port_in_in_string,
754                 (void *) &cmd_stats_port_in_port_in_id,
755                 NULL,
756         },
757 };
758
759 /*
760  * stats port out
761  */
762
763 struct cmd_stats_port_out_result {
764         cmdline_fixed_string_t p_string;
765         uint32_t pipeline_id;
766         cmdline_fixed_string_t stats_string;
767         cmdline_fixed_string_t port_string;
768         cmdline_fixed_string_t out_string;
769         uint32_t port_out_id;
770 };
771
772 static void
773 cmd_stats_port_out_parsed(
774         void *parsed_result,
775         __rte_unused struct cmdline *cl,
776         void *data)
777 {
778
779         struct cmd_stats_port_out_result *params = parsed_result;
780         struct app_params *app = data;
781         struct rte_pipeline_port_out_stats stats;
782         int status;
783
784         status = app_pipeline_stats_port_out(app,
785                         params->pipeline_id,
786                         params->port_out_id,
787                         &stats);
788
789         if (status != 0) {
790                 printf("Command failed\n");
791                 return;
792         }
793
794         /* Display stats */
795         printf("Pipeline %" PRIu32 " - stats for output port %" PRIu32 ":\n"
796                 "\tPkts in: %" PRIu64 "\n"
797                 "\tPkts dropped by AH: %" PRIu64 "\n"
798                 "\tPkts dropped by other: %" PRIu64 "\n",
799                 params->pipeline_id,
800                 params->port_out_id,
801                 stats.stats.n_pkts_in,
802                 stats.n_pkts_dropped_by_ah,
803                 stats.stats.n_pkts_drop);
804 }
805
806 static cmdline_parse_token_string_t cmd_stats_port_out_p_string =
807         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, p_string,
808         "p");
809
810 static cmdline_parse_token_num_t cmd_stats_port_out_pipeline_id =
811         TOKEN_NUM_INITIALIZER(struct cmd_stats_port_out_result, pipeline_id,
812                 UINT32);
813
814 static cmdline_parse_token_string_t cmd_stats_port_out_stats_string =
815         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, stats_string,
816                 "stats");
817
818 static cmdline_parse_token_string_t cmd_stats_port_out_port_string =
819         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, port_string,
820                 "port");
821
822 static cmdline_parse_token_string_t cmd_stats_port_out_out_string =
823         TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, out_string,
824                 "out");
825
826 static cmdline_parse_token_num_t cmd_stats_port_out_port_out_id =
827         TOKEN_NUM_INITIALIZER(struct cmd_stats_port_out_result, port_out_id,
828                 UINT32);
829
830 static cmdline_parse_inst_t cmd_stats_port_out = {
831         .f = cmd_stats_port_out_parsed,
832         .data = NULL,
833         .help_str = "Pipeline output port stats",
834         .tokens = {
835                 (void *) &cmd_stats_port_out_p_string,
836                 (void *) &cmd_stats_port_out_pipeline_id,
837                 (void *) &cmd_stats_port_out_stats_string,
838                 (void *) &cmd_stats_port_out_port_string,
839                 (void *) &cmd_stats_port_out_out_string,
840                 (void *) &cmd_stats_port_out_port_out_id,
841                 NULL,
842         },
843 };
844
845 /*
846  * stats table
847  */
848
849 struct cmd_stats_table_result {
850         cmdline_fixed_string_t p_string;
851         uint32_t pipeline_id;
852         cmdline_fixed_string_t stats_string;
853         cmdline_fixed_string_t table_string;
854         uint32_t table_id;
855 };
856
857 static void
858 cmd_stats_table_parsed(
859         void *parsed_result,
860         __rte_unused struct cmdline *cl,
861         void *data)
862 {
863         struct cmd_stats_table_result *params = parsed_result;
864         struct app_params *app = data;
865         struct rte_pipeline_table_stats stats;
866         int status;
867
868         status = app_pipeline_stats_table(app,
869                         params->pipeline_id,
870                         params->table_id,
871                         &stats);
872
873         if (status != 0) {
874                 printf("Command failed\n");
875                 return;
876         }
877
878         /* Display stats */
879         printf("Pipeline %" PRIu32 " - stats for table %" PRIu32 ":\n"
880                 "\tPkts in: %" PRIu64 "\n"
881                 "\tPkts in with lookup miss: %" PRIu64 "\n"
882                 "\tPkts in with lookup hit dropped by AH: %" PRIu64 "\n"
883                 "\tPkts in with lookup hit dropped by others: %" PRIu64 "\n"
884                 "\tPkts in with lookup miss dropped by AH: %" PRIu64 "\n"
885                 "\tPkts in with lookup miss dropped by others: %" PRIu64 "\n",
886                 params->pipeline_id,
887                 params->table_id,
888                 stats.stats.n_pkts_in,
889                 stats.stats.n_pkts_lookup_miss,
890                 stats.n_pkts_dropped_by_lkp_hit_ah,
891                 stats.n_pkts_dropped_lkp_hit,
892                 stats.n_pkts_dropped_by_lkp_miss_ah,
893                 stats.n_pkts_dropped_lkp_miss);
894 }
895
896 static cmdline_parse_token_string_t cmd_stats_table_p_string =
897         TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, p_string,
898                 "p");
899
900 static cmdline_parse_token_num_t cmd_stats_table_pipeline_id =
901         TOKEN_NUM_INITIALIZER(struct cmd_stats_table_result, pipeline_id,
902                 UINT32);
903
904 static cmdline_parse_token_string_t cmd_stats_table_stats_string =
905         TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, stats_string,
906                 "stats");
907
908 static cmdline_parse_token_string_t cmd_stats_table_table_string =
909         TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, table_string,
910                 "table");
911
912 static cmdline_parse_token_num_t cmd_stats_table_table_id =
913         TOKEN_NUM_INITIALIZER(struct cmd_stats_table_result, table_id, UINT32);
914
915 static cmdline_parse_inst_t cmd_stats_table = {
916         .f = cmd_stats_table_parsed,
917         .data = NULL,
918         .help_str = "Pipeline table stats",
919         .tokens = {
920                 (void *) &cmd_stats_table_p_string,
921                 (void *) &cmd_stats_table_pipeline_id,
922                 (void *) &cmd_stats_table_stats_string,
923                 (void *) &cmd_stats_table_table_string,
924                 (void *) &cmd_stats_table_table_id,
925                 NULL,
926         },
927 };
928
929 /*
930  * port in enable
931  */
932
933 struct cmd_port_in_enable_result {
934         cmdline_fixed_string_t p_string;
935         uint32_t pipeline_id;
936         cmdline_fixed_string_t port_string;
937         cmdline_fixed_string_t in_string;
938         uint32_t port_in_id;
939         cmdline_fixed_string_t enable_string;
940 };
941
942 static void
943 cmd_port_in_enable_parsed(
944         void *parsed_result,
945         __rte_unused struct cmdline *cl,
946         void *data)
947 {
948         struct cmd_port_in_enable_result *params = parsed_result;
949         struct app_params *app = data;
950         int status;
951
952         status = app_pipeline_port_in_enable(app,
953                         params->pipeline_id,
954                         params->port_in_id);
955
956         if (status != 0)
957                 printf("Command failed\n");
958 }
959
960 static cmdline_parse_token_string_t cmd_port_in_enable_p_string =
961         TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, p_string,
962                 "p");
963
964 static cmdline_parse_token_num_t cmd_port_in_enable_pipeline_id =
965         TOKEN_NUM_INITIALIZER(struct cmd_port_in_enable_result, pipeline_id,
966                 UINT32);
967
968 static cmdline_parse_token_string_t cmd_port_in_enable_port_string =
969         TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, port_string,
970         "port");
971
972 static cmdline_parse_token_string_t cmd_port_in_enable_in_string =
973         TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, in_string,
974                 "in");
975
976 static cmdline_parse_token_num_t cmd_port_in_enable_port_in_id =
977         TOKEN_NUM_INITIALIZER(struct cmd_port_in_enable_result, port_in_id,
978                 UINT32);
979
980 static cmdline_parse_token_string_t cmd_port_in_enable_enable_string =
981         TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result,
982                 enable_string, "enable");
983
984 static cmdline_parse_inst_t cmd_port_in_enable = {
985         .f = cmd_port_in_enable_parsed,
986         .data = NULL,
987         .help_str = "Pipeline input port enable",
988         .tokens = {
989                 (void *) &cmd_port_in_enable_p_string,
990                 (void *) &cmd_port_in_enable_pipeline_id,
991                 (void *) &cmd_port_in_enable_port_string,
992                 (void *) &cmd_port_in_enable_in_string,
993                 (void *) &cmd_port_in_enable_port_in_id,
994                 (void *) &cmd_port_in_enable_enable_string,
995                 NULL,
996         },
997 };
998
999 /*
1000  * port in disable
1001  */
1002
1003 struct cmd_port_in_disable_result {
1004         cmdline_fixed_string_t p_string;
1005         uint32_t pipeline_id;
1006         cmdline_fixed_string_t port_string;
1007         cmdline_fixed_string_t in_string;
1008         uint32_t port_in_id;
1009         cmdline_fixed_string_t disable_string;
1010 };
1011
1012 static void
1013 cmd_port_in_disable_parsed(
1014         void *parsed_result,
1015         __rte_unused struct cmdline *cl,
1016         void *data)
1017 {
1018         struct cmd_port_in_disable_result *params = parsed_result;
1019         struct app_params *app = data;
1020         int status;
1021
1022         status = app_pipeline_port_in_disable(app,
1023                         params->pipeline_id,
1024                         params->port_in_id);
1025
1026         if (status != 0)
1027                 printf("Command failed\n");
1028 }
1029
1030 static cmdline_parse_token_string_t cmd_port_in_disable_p_string =
1031         TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, p_string,
1032                 "p");
1033
1034 static cmdline_parse_token_num_t cmd_port_in_disable_pipeline_id =
1035         TOKEN_NUM_INITIALIZER(struct cmd_port_in_disable_result, pipeline_id,
1036                 UINT32);
1037
1038 static cmdline_parse_token_string_t cmd_port_in_disable_port_string =
1039         TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, port_string,
1040                 "port");
1041
1042 static cmdline_parse_token_string_t cmd_port_in_disable_in_string =
1043         TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, in_string,
1044                 "in");
1045
1046 static cmdline_parse_token_num_t cmd_port_in_disable_port_in_id =
1047         TOKEN_NUM_INITIALIZER(struct cmd_port_in_disable_result, port_in_id,
1048                 UINT32);
1049
1050 static cmdline_parse_token_string_t cmd_port_in_disable_disable_string =
1051         TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result,
1052                 disable_string, "disable");
1053
1054 static cmdline_parse_inst_t cmd_port_in_disable = {
1055         .f = cmd_port_in_disable_parsed,
1056         .data = NULL,
1057         .help_str = "Pipeline input port disable",
1058         .tokens = {
1059                 (void *) &cmd_port_in_disable_p_string,
1060                 (void *) &cmd_port_in_disable_pipeline_id,
1061                 (void *) &cmd_port_in_disable_port_string,
1062                 (void *) &cmd_port_in_disable_in_string,
1063                 (void *) &cmd_port_in_disable_port_in_id,
1064                 (void *) &cmd_port_in_disable_disable_string,
1065                 NULL,
1066         },
1067 };
1068
1069 /*
1070  * link config
1071  */
1072
1073 static void
1074 print_link_info(struct app_link_params *p)
1075 {
1076         struct rte_eth_stats stats;
1077         struct ether_addr *mac_addr;
1078         uint32_t netmask = (~0U) << (32 - p->depth);
1079         uint32_t host = p->ip & netmask;
1080         uint32_t bcast = host | (~netmask);
1081
1082         memset(&stats, 0, sizeof(stats));
1083         rte_eth_stats_get(p->pmd_id, &stats);
1084
1085         mac_addr = (struct ether_addr *) &p->mac_addr;
1086
1087         if (strlen(p->pci_bdf))
1088                 printf("%s(%s): flags=<%s>\n",
1089                         p->name,
1090                         p->pci_bdf,
1091                         (p->state) ? "UP" : "DOWN");
1092         else
1093                 printf("%s: flags=<%s>\n",
1094                         p->name,
1095                         (p->state) ? "UP" : "DOWN");
1096
1097         if (p->ip)
1098                 printf("\tinet %" PRIu32 ".%" PRIu32
1099                         ".%" PRIu32 ".%" PRIu32
1100                         " netmask %" PRIu32 ".%" PRIu32
1101                         ".%" PRIu32 ".%" PRIu32 " "
1102                         "broadcast %" PRIu32 ".%" PRIu32
1103                         ".%" PRIu32 ".%" PRIu32 "\n",
1104                         (p->ip >> 24) & 0xFF,
1105                         (p->ip >> 16) & 0xFF,
1106                         (p->ip >> 8) & 0xFF,
1107                         p->ip & 0xFF,
1108                         (netmask >> 24) & 0xFF,
1109                         (netmask >> 16) & 0xFF,
1110                         (netmask >> 8) & 0xFF,
1111                         netmask & 0xFF,
1112                         (bcast >> 24) & 0xFF,
1113                         (bcast >> 16) & 0xFF,
1114                         (bcast >> 8) & 0xFF,
1115                         bcast & 0xFF);
1116
1117         printf("\tether %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32
1118                 ":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\n",
1119                 mac_addr->addr_bytes[0],
1120                 mac_addr->addr_bytes[1],
1121                 mac_addr->addr_bytes[2],
1122                 mac_addr->addr_bytes[3],
1123                 mac_addr->addr_bytes[4],
1124                 mac_addr->addr_bytes[5]);
1125
1126         printf("\tRX packets %" PRIu64
1127                 "  bytes %" PRIu64
1128                 "\n",
1129                 stats.ipackets,
1130                 stats.ibytes);
1131
1132         printf("\tRX errors %" PRIu64
1133                 "  missed %" PRIu64
1134                 "  no-mbuf %" PRIu64
1135                 "\n",
1136                 stats.ierrors,
1137                 stats.imissed,
1138                 stats.rx_nombuf);
1139
1140         printf("\tTX packets %" PRIu64
1141                 "  bytes %" PRIu64 "\n",
1142                 stats.opackets,
1143                 stats.obytes);
1144
1145         printf("\tTX errors %" PRIu64
1146                 "\n",
1147                 stats.oerrors);
1148
1149         printf("\n");
1150 }
1151
1152 /*
1153  * link
1154  *
1155  * link config:
1156  *    link <linkid> config <ipaddr> <depth>
1157  *
1158  * link up:
1159  *    link <linkid> up
1160  *
1161  * link down:
1162  *    link <linkid> down
1163  *
1164  * link ls:
1165  *    link ls
1166  */
1167
1168 struct cmd_link_result {
1169         cmdline_fixed_string_t link_string;
1170         cmdline_multi_string_t multi_string;
1171 };
1172
1173 static void
1174 cmd_link_parsed(
1175         void *parsed_result,
1176         __attribute__((unused)) struct cmdline *cl,
1177          void *data)
1178 {
1179         struct cmd_link_result *params = parsed_result;
1180         struct app_params *app = data;
1181
1182         char *tokens[16];
1183         uint32_t n_tokens = RTE_DIM(tokens);
1184         int status;
1185
1186         uint32_t link_id;
1187
1188         status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
1189         if (status != 0) {
1190                 printf(CMD_MSG_TOO_MANY_ARGS, "link");
1191                 return;
1192         }
1193
1194         /* link ls */
1195         if ((n_tokens == 1) && (strcmp(tokens[0], "ls") == 0)) {
1196                 for (link_id = 0; link_id < app->n_links; link_id++) {
1197                         struct app_link_params *p;
1198
1199                         APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
1200                         print_link_info(p);
1201                 }
1202                 return;
1203         } /* link ls */
1204
1205         if (n_tokens < 2) {
1206                 printf(CMD_MSG_MISMATCH_ARGS, "link");
1207                 return;
1208         }
1209
1210         if (parser_read_uint32(&link_id, tokens[0])) {
1211                 printf(CMD_MSG_INVALID_ARG, "linkid");
1212                 return;
1213         }
1214
1215         /* link config */
1216         if (strcmp(tokens[1], "config") == 0) {
1217                 struct in_addr ipaddr_ipv4;
1218                 uint32_t depth;
1219
1220                 if (n_tokens != 4) {
1221                         printf(CMD_MSG_MISMATCH_ARGS, "link config");
1222                         return;
1223                 }
1224
1225                 if (parse_ipv4_addr(tokens[2], &ipaddr_ipv4)) {
1226                         printf(CMD_MSG_INVALID_ARG, "ipaddr");
1227                         return;
1228                 }
1229
1230                 if (parser_read_uint32(&depth, tokens[3])) {
1231                         printf(CMD_MSG_INVALID_ARG, "depth");
1232                         return;
1233                 }
1234
1235                 status = app_link_config(app,
1236                         link_id,
1237                         rte_be_to_cpu_32(ipaddr_ipv4.s_addr),
1238                         depth);
1239                 if (status)
1240                         printf(CMD_MSG_FAIL, "link config");
1241
1242                 return;
1243         } /* link config */
1244
1245         /* link up */
1246         if (strcmp(tokens[1], "up") == 0) {
1247                 if (n_tokens != 2) {
1248                         printf(CMD_MSG_MISMATCH_ARGS, "link up");
1249                         return;
1250                 }
1251
1252                 status = app_link_up(app, link_id);
1253                 if (status)
1254                         printf(CMD_MSG_FAIL, "link up");
1255
1256                 return;
1257         } /* link up */
1258
1259         /* link down */
1260         if (strcmp(tokens[1], "down") == 0) {
1261                 if (n_tokens != 2) {
1262                         printf(CMD_MSG_MISMATCH_ARGS, "link down");
1263                         return;
1264                 }
1265
1266                 status = app_link_down(app, link_id);
1267                 if (status)
1268                         printf(CMD_MSG_FAIL, "link down");
1269
1270                 return;
1271         } /* link down */
1272
1273         printf(CMD_MSG_MISMATCH_ARGS, "link");
1274 }
1275
1276 static cmdline_parse_token_string_t cmd_link_link_string =
1277         TOKEN_STRING_INITIALIZER(struct cmd_link_result, link_string, "link");
1278
1279 static cmdline_parse_token_string_t cmd_link_multi_string =
1280         TOKEN_STRING_INITIALIZER(struct cmd_link_result, multi_string,
1281         TOKEN_STRING_MULTI);
1282
1283 static cmdline_parse_inst_t cmd_link = {
1284         .f = cmd_link_parsed,
1285         .data = NULL,
1286         .help_str = "link config / up / down / ls",
1287         .tokens = {
1288                 (void *) &cmd_link_link_string,
1289                 (void *) &cmd_link_multi_string,
1290                 NULL,
1291         },
1292 };
1293
1294 /*
1295  * quit
1296  */
1297
1298 struct cmd_quit_result {
1299         cmdline_fixed_string_t quit;
1300 };
1301
1302 static void
1303 cmd_quit_parsed(
1304         __rte_unused void *parsed_result,
1305         struct cmdline *cl,
1306         __rte_unused void *data)
1307 {
1308         cmdline_quit(cl);
1309 }
1310
1311 static cmdline_parse_token_string_t cmd_quit_quit =
1312         TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
1313
1314 static cmdline_parse_inst_t cmd_quit = {
1315         .f = cmd_quit_parsed,
1316         .data = NULL,
1317         .help_str = "Quit",
1318         .tokens = {
1319                 (void *) &cmd_quit_quit,
1320                 NULL,
1321         },
1322 };
1323
1324 /*
1325  * run
1326  *
1327  *    run <file>
1328  *    run <file> [<count> [<interval>]]
1329          <count> default is 1
1330  *       <interval> is measured in milliseconds, default is 1 second
1331  */
1332
1333 static void
1334 app_run_file(
1335         cmdline_parse_ctx_t *ctx,
1336         const char *file_name)
1337 {
1338         struct cmdline *file_cl;
1339         int fd;
1340
1341         fd = open(file_name, O_RDONLY);
1342         if (fd < 0) {
1343                 printf("Cannot open file \"%s\"\n", file_name);
1344                 return;
1345         }
1346
1347         file_cl = cmdline_new(ctx, "", fd, 1);
1348         cmdline_interact(file_cl);
1349         close(fd);
1350 }
1351
1352 struct cmd_run_result {
1353         cmdline_fixed_string_t run_string;
1354         cmdline_multi_string_t multi_string;
1355 };
1356
1357 static void
1358 cmd_run_parsed(
1359         void *parsed_result,
1360         struct cmdline *cl,
1361         __attribute__((unused)) void *data)
1362 {
1363         struct cmd_run_result *params = parsed_result;
1364
1365         char *tokens[16];
1366         uint32_t n_tokens = RTE_DIM(tokens);
1367         int status;
1368
1369         char *file_name;
1370         uint32_t count, interval, i;
1371
1372         status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
1373         if (status) {
1374                 printf(CMD_MSG_TOO_MANY_ARGS, "run");
1375                 return;
1376         }
1377
1378         switch (n_tokens) {
1379         case 0:
1380                 printf(CMD_MSG_NOT_ENOUGH_ARGS, "run");
1381                 return;
1382
1383         case 1:
1384                 file_name = tokens[0];
1385                 count = 1;
1386                 interval = 1000;
1387                 break;
1388
1389         case 2:
1390                 file_name = tokens[0];
1391
1392                 if (parser_read_uint32(&count, tokens[1]) ||
1393                         (count == 0)) {
1394                         printf(CMD_MSG_INVALID_ARG, "count");
1395                         return;
1396                 }
1397
1398                 interval = 1000;
1399                 break;
1400
1401         case 3:
1402                 file_name = tokens[0];
1403
1404                 if (parser_read_uint32(&count, tokens[1]) ||
1405                         (count == 0)) {
1406                         printf(CMD_MSG_INVALID_ARG, "count");
1407                         return;
1408                 }
1409
1410                 if (parser_read_uint32(&interval, tokens[2]) ||
1411                         (interval == 0)) {
1412                         printf(CMD_MSG_INVALID_ARG, "interval");
1413                         return;
1414                 }
1415                 break;
1416
1417         default:
1418                 printf(CMD_MSG_MISMATCH_ARGS, "run");
1419                 return;
1420         }
1421
1422         for (i = 0; i < count; i++) {
1423                 app_run_file(cl->ctx, file_name);
1424                 if (interval)
1425                         usleep(interval * 1000);
1426         }
1427 }
1428
1429 static cmdline_parse_token_string_t cmd_run_run_string =
1430         TOKEN_STRING_INITIALIZER(struct cmd_run_result, run_string, "run");
1431
1432 static cmdline_parse_token_string_t cmd_run_multi_string =
1433         TOKEN_STRING_INITIALIZER(struct cmd_run_result, multi_string,
1434         TOKEN_STRING_MULTI);
1435
1436
1437 static cmdline_parse_inst_t cmd_run = {
1438         .f = cmd_run_parsed,
1439         .data = NULL,
1440         .help_str = "Run CLI script file",
1441         .tokens = {
1442                 (void *) &cmd_run_run_string,
1443                 (void *) &cmd_run_multi_string,
1444                 NULL,
1445         },
1446 };
1447
1448 static cmdline_parse_ctx_t pipeline_common_cmds[] = {
1449         (cmdline_parse_inst_t *) &cmd_quit,
1450         (cmdline_parse_inst_t *) &cmd_run,
1451         (cmdline_parse_inst_t *) &cmd_link,
1452         (cmdline_parse_inst_t *) &cmd_ping,
1453         (cmdline_parse_inst_t *) &cmd_stats_port_in,
1454         (cmdline_parse_inst_t *) &cmd_stats_port_out,
1455         (cmdline_parse_inst_t *) &cmd_stats_table,
1456         (cmdline_parse_inst_t *) &cmd_port_in_enable,
1457         (cmdline_parse_inst_t *) &cmd_port_in_disable,
1458         NULL,
1459 };
1460
1461 int
1462 app_pipeline_common_cmd_push(struct app_params *app)
1463 {
1464         uint32_t n_cmds, i;
1465
1466         /* Check for available slots in the application commands array */
1467         n_cmds = RTE_DIM(pipeline_common_cmds) - 1;
1468         if (n_cmds > APP_MAX_CMDS - app->n_cmds)
1469                 return -ENOMEM;
1470
1471         /* Push pipeline commands into the application */
1472         memcpy(&app->cmds[app->n_cmds],
1473                 pipeline_common_cmds,
1474                 n_cmds * sizeof(cmdline_parse_ctx_t));
1475
1476         for (i = 0; i < n_cmds; i++)
1477                 app->cmds[app->n_cmds + i]->data = app;
1478
1479         app->n_cmds += n_cmds;
1480         app->cmds[app->n_cmds] = NULL;
1481
1482         return 0;
1483 }