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