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