Imported Upstream version 16.04
[deb_dpdk.git] / examples / ip_pipeline / pipeline / pipeline_routing.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <cmdline_parse.h>
35 #include <cmdline_parse_num.h>
36 #include <cmdline_parse_string.h>
37 #include <cmdline_parse_ipaddr.h>
38 #include <cmdline_parse_etheraddr.h>
39
40 #include "app.h"
41 #include "pipeline_common_fe.h"
42 #include "pipeline_routing.h"
43
44 struct app_pipeline_routing_route {
45         struct pipeline_routing_route_key key;
46         struct pipeline_routing_route_data data;
47         void *entry_ptr;
48
49         TAILQ_ENTRY(app_pipeline_routing_route) node;
50 };
51
52 struct app_pipeline_routing_arp_entry {
53         struct pipeline_routing_arp_key key;
54         struct ether_addr macaddr;
55         void *entry_ptr;
56
57         TAILQ_ENTRY(app_pipeline_routing_arp_entry) node;
58 };
59
60 struct pipeline_routing {
61         /* Parameters */
62         uint32_t n_ports_in;
63         uint32_t n_ports_out;
64
65         /* Routes */
66         TAILQ_HEAD(, app_pipeline_routing_route) routes;
67         uint32_t n_routes;
68
69         uint32_t default_route_present;
70         uint32_t default_route_port_id;
71         void *default_route_entry_ptr;
72
73         /* ARP entries */
74         TAILQ_HEAD(, app_pipeline_routing_arp_entry) arp_entries;
75         uint32_t n_arp_entries;
76
77         uint32_t default_arp_entry_present;
78         uint32_t default_arp_entry_port_id;
79         void *default_arp_entry_ptr;
80 };
81
82 static void *
83 pipeline_routing_init(struct pipeline_params *params,
84         __rte_unused void *arg)
85 {
86         struct pipeline_routing *p;
87         uint32_t size;
88
89         /* Check input arguments */
90         if ((params == NULL) ||
91                 (params->n_ports_in == 0) ||
92                 (params->n_ports_out == 0))
93                 return NULL;
94
95         /* Memory allocation */
96         size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_routing));
97         p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
98         if (p == NULL)
99                 return NULL;
100
101         /* Initialization */
102         p->n_ports_in = params->n_ports_in;
103         p->n_ports_out = params->n_ports_out;
104
105         TAILQ_INIT(&p->routes);
106         p->n_routes = 0;
107
108         TAILQ_INIT(&p->arp_entries);
109         p->n_arp_entries = 0;
110
111         return p;
112 }
113
114 static int
115 app_pipeline_routing_free(void *pipeline)
116 {
117         struct pipeline_routing *p = pipeline;
118
119         /* Check input arguments */
120         if (p == NULL)
121                 return -1;
122
123         /* Free resources */
124         while (!TAILQ_EMPTY(&p->routes)) {
125                 struct app_pipeline_routing_route *route;
126
127                 route = TAILQ_FIRST(&p->routes);
128                 TAILQ_REMOVE(&p->routes, route, node);
129                 rte_free(route);
130         }
131
132         while (!TAILQ_EMPTY(&p->arp_entries)) {
133                 struct app_pipeline_routing_arp_entry *arp_entry;
134
135                 arp_entry = TAILQ_FIRST(&p->arp_entries);
136                 TAILQ_REMOVE(&p->arp_entries, arp_entry, node);
137                 rte_free(arp_entry);
138         }
139
140         rte_free(p);
141         return 0;
142 }
143
144 static struct app_pipeline_routing_route *
145 app_pipeline_routing_find_route(struct pipeline_routing *p,
146                 const struct pipeline_routing_route_key *key)
147 {
148         struct app_pipeline_routing_route *it, *found;
149
150         found = NULL;
151         TAILQ_FOREACH(it, &p->routes, node) {
152                 if ((key->type == it->key.type) &&
153                         (key->key.ipv4.ip == it->key.key.ipv4.ip) &&
154                         (key->key.ipv4.depth == it->key.key.ipv4.depth)) {
155                         found = it;
156                         break;
157                 }
158         }
159
160         return found;
161 }
162
163 static struct app_pipeline_routing_arp_entry *
164 app_pipeline_routing_find_arp_entry(struct pipeline_routing *p,
165                 const struct pipeline_routing_arp_key *key)
166 {
167         struct app_pipeline_routing_arp_entry *it, *found;
168
169         found = NULL;
170         TAILQ_FOREACH(it, &p->arp_entries, node) {
171                 if ((key->type == it->key.type) &&
172                         (key->key.ipv4.port_id == it->key.key.ipv4.port_id) &&
173                         (key->key.ipv4.ip == it->key.key.ipv4.ip)) {
174                         found = it;
175                         break;
176                 }
177         }
178
179         return found;
180 }
181
182 static void
183 print_route(const struct app_pipeline_routing_route *route)
184 {
185         if (route->key.type == PIPELINE_ROUTING_ROUTE_IPV4) {
186                 const struct pipeline_routing_route_key_ipv4 *key =
187                                 &route->key.key.ipv4;
188
189                 printf("IP Prefix = %" PRIu32 ".%" PRIu32
190                         ".%" PRIu32 ".%" PRIu32 "/%" PRIu32
191                         " => (Port = %" PRIu32,
192
193                         (key->ip >> 24) & 0xFF,
194                         (key->ip >> 16) & 0xFF,
195                         (key->ip >> 8) & 0xFF,
196                         key->ip & 0xFF,
197
198                         key->depth,
199                         route->data.port_id);
200
201                 if (route->data.flags & PIPELINE_ROUTING_ROUTE_ARP)
202                         printf(
203                                 ", Next Hop IP = %" PRIu32 ".%" PRIu32
204                                 ".%" PRIu32 ".%" PRIu32,
205
206                                 (route->data.ethernet.ip >> 24) & 0xFF,
207                                 (route->data.ethernet.ip >> 16) & 0xFF,
208                                 (route->data.ethernet.ip >> 8) & 0xFF,
209                                 route->data.ethernet.ip & 0xFF);
210                 else
211                         printf(
212                                 ", Next Hop HWaddress = %02" PRIx32
213                                 ":%02" PRIx32 ":%02" PRIx32
214                                 ":%02" PRIx32 ":%02" PRIx32
215                                 ":%02" PRIx32,
216
217                                 route->data.ethernet.macaddr.addr_bytes[0],
218                                 route->data.ethernet.macaddr.addr_bytes[1],
219                                 route->data.ethernet.macaddr.addr_bytes[2],
220                                 route->data.ethernet.macaddr.addr_bytes[3],
221                                 route->data.ethernet.macaddr.addr_bytes[4],
222                                 route->data.ethernet.macaddr.addr_bytes[5]);
223
224                 if (route->data.flags & PIPELINE_ROUTING_ROUTE_QINQ)
225                         printf(", QinQ SVLAN = %" PRIu32 " CVLAN = %" PRIu32,
226                                 route->data.l2.qinq.svlan,
227                                 route->data.l2.qinq.cvlan);
228
229                 if (route->data.flags & PIPELINE_ROUTING_ROUTE_MPLS) {
230                         uint32_t i;
231
232                         printf(", MPLS labels");
233                         for (i = 0; i < route->data.l2.mpls.n_labels; i++)
234                                 printf(" %" PRIu32,
235                                         route->data.l2.mpls.labels[i]);
236                 }
237
238                 printf(")\n");
239         }
240 }
241
242 static void
243 print_arp_entry(const struct app_pipeline_routing_arp_entry *entry)
244 {
245         printf("(Port = %" PRIu32 ", IP = %" PRIu32 ".%" PRIu32
246                 ".%" PRIu32 ".%" PRIu32
247                 ") => HWaddress = %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32
248                 ":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\n",
249
250                 entry->key.key.ipv4.port_id,
251                 (entry->key.key.ipv4.ip >> 24) & 0xFF,
252                 (entry->key.key.ipv4.ip >> 16) & 0xFF,
253                 (entry->key.key.ipv4.ip >> 8) & 0xFF,
254                 entry->key.key.ipv4.ip & 0xFF,
255
256                 entry->macaddr.addr_bytes[0],
257                 entry->macaddr.addr_bytes[1],
258                 entry->macaddr.addr_bytes[2],
259                 entry->macaddr.addr_bytes[3],
260                 entry->macaddr.addr_bytes[4],
261                 entry->macaddr.addr_bytes[5]);
262 }
263
264 static int
265 app_pipeline_routing_route_ls(struct app_params *app, uint32_t pipeline_id)
266 {
267         struct pipeline_routing *p;
268         struct app_pipeline_routing_route *it;
269
270         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
271         if (p == NULL)
272                 return -EINVAL;
273
274         TAILQ_FOREACH(it, &p->routes, node)
275                 print_route(it);
276
277         if (p->default_route_present)
278                 printf("Default route: port %" PRIu32 " (entry ptr = %p)\n",
279                                 p->default_route_port_id,
280                                 p->default_route_entry_ptr);
281         else
282                 printf("Default: DROP\n");
283
284         return 0;
285 }
286
287 int
288 app_pipeline_routing_add_route(struct app_params *app,
289         uint32_t pipeline_id,
290         struct pipeline_routing_route_key *key,
291         struct pipeline_routing_route_data *data)
292 {
293         struct pipeline_routing *p;
294
295         struct pipeline_routing_route_add_msg_req *req;
296         struct pipeline_routing_route_add_msg_rsp *rsp;
297
298         struct app_pipeline_routing_route *entry;
299
300         int new_entry;
301
302         /* Check input arguments */
303         if ((app == NULL) ||
304                 (key == NULL) ||
305                 (data == NULL))
306                 return -1;
307
308         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
309         if (p == NULL)
310                 return -1;
311
312         switch (key->type) {
313         case PIPELINE_ROUTING_ROUTE_IPV4:
314         {
315                 uint32_t depth = key->key.ipv4.depth;
316                 uint32_t netmask;
317
318                 /* key */
319                 if ((depth == 0) || (depth > 32))
320                         return -1;
321
322                 netmask = (~0U) << (32 - depth);
323                 key->key.ipv4.ip &= netmask;
324
325                 /* data */
326                 if (data->port_id >= p->n_ports_out)
327                         return -1;
328         }
329         break;
330
331         default:
332                 return -1;
333         }
334
335         /* Find existing rule or allocate new rule */
336         entry = app_pipeline_routing_find_route(p, key);
337         new_entry = (entry == NULL);
338         if (entry == NULL) {
339                 entry = rte_malloc(NULL, sizeof(*entry), RTE_CACHE_LINE_SIZE);
340
341                 if (entry == NULL)
342                         return -1;
343         }
344
345         /* Allocate and write request */
346         req = app_msg_alloc(app);
347         if (req == NULL) {
348                 if (new_entry)
349                         rte_free(entry);
350                 return -1;
351         }
352
353         req->type = PIPELINE_MSG_REQ_CUSTOM;
354         req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD;
355         memcpy(&req->key, key, sizeof(*key));
356         memcpy(&req->data, data, sizeof(*data));
357
358         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
359         if (rsp == NULL) {
360                 if (new_entry)
361                         rte_free(entry);
362                 return -1;
363         }
364
365         /* Read response and write entry */
366         if (rsp->status ||
367                 (rsp->entry_ptr == NULL) ||
368                 ((new_entry == 0) && (rsp->key_found == 0)) ||
369                 ((new_entry == 1) && (rsp->key_found == 1))) {
370                 app_msg_free(app, rsp);
371                 if (new_entry)
372                         rte_free(entry);
373                 return -1;
374         }
375
376         memcpy(&entry->key, key, sizeof(*key));
377         memcpy(&entry->data, data, sizeof(*data));
378         entry->entry_ptr = rsp->entry_ptr;
379
380         /* Commit entry */
381         if (new_entry) {
382                 TAILQ_INSERT_TAIL(&p->routes, entry, node);
383                 p->n_routes++;
384         }
385
386         print_route(entry);
387
388         /* Message buffer free */
389         app_msg_free(app, rsp);
390         return 0;
391 }
392
393 int
394 app_pipeline_routing_delete_route(struct app_params *app,
395         uint32_t pipeline_id,
396         struct pipeline_routing_route_key *key)
397 {
398         struct pipeline_routing *p;
399
400         struct pipeline_routing_route_delete_msg_req *req;
401         struct pipeline_routing_route_delete_msg_rsp *rsp;
402
403         struct app_pipeline_routing_route *entry;
404
405         /* Check input arguments */
406         if ((app == NULL) ||
407                 (key == NULL))
408                 return -1;
409
410         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
411         if (p == NULL)
412                 return -1;
413
414         switch (key->type) {
415         case PIPELINE_ROUTING_ROUTE_IPV4:
416         {
417                 uint32_t depth = key->key.ipv4.depth;
418                 uint32_t netmask;
419
420                 /* key */
421                 if ((depth == 0) || (depth > 32))
422                         return -1;
423
424                 netmask = (~0U) << (32 - depth);
425                 key->key.ipv4.ip &= netmask;
426         }
427         break;
428
429         default:
430                 return -1;
431         }
432
433         /* Find rule */
434         entry = app_pipeline_routing_find_route(p, key);
435         if (entry == NULL)
436                 return 0;
437
438         /* Allocate and write request */
439         req = app_msg_alloc(app);
440         if (req == NULL)
441                 return -1;
442
443         req->type = PIPELINE_MSG_REQ_CUSTOM;
444         req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL;
445         memcpy(&req->key, key, sizeof(*key));
446
447         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
448         if (rsp == NULL)
449                 return -1;
450
451         /* Read response */
452         if (rsp->status || !rsp->key_found) {
453                 app_msg_free(app, rsp);
454                 return -1;
455         }
456
457         /* Remove route */
458         TAILQ_REMOVE(&p->routes, entry, node);
459         p->n_routes--;
460         rte_free(entry);
461
462         /* Free response */
463         app_msg_free(app, rsp);
464
465         return 0;
466 }
467
468 int
469 app_pipeline_routing_add_default_route(struct app_params *app,
470         uint32_t pipeline_id,
471         uint32_t port_id)
472 {
473         struct pipeline_routing *p;
474
475         struct pipeline_routing_route_add_default_msg_req *req;
476         struct pipeline_routing_route_add_default_msg_rsp *rsp;
477
478         /* Check input arguments */
479         if (app == NULL)
480                 return -1;
481
482         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
483         if (p == NULL)
484                 return -1;
485
486         if (port_id >= p->n_ports_out)
487                 return -1;
488
489         /* Allocate and write request */
490         req = app_msg_alloc(app);
491         if (req == NULL)
492                 return -1;
493
494         req->type = PIPELINE_MSG_REQ_CUSTOM;
495         req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD_DEFAULT;
496         req->port_id = port_id;
497
498         /* Send request and wait for response */
499         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
500         if (rsp == NULL)
501                 return -1;
502
503         /* Read response and write route */
504         if (rsp->status || (rsp->entry_ptr == NULL)) {
505                 app_msg_free(app, rsp);
506                 return -1;
507         }
508
509         p->default_route_port_id = port_id;
510         p->default_route_entry_ptr = rsp->entry_ptr;
511
512         /* Commit route */
513         p->default_route_present = 1;
514
515         /* Free response */
516         app_msg_free(app, rsp);
517
518         return 0;
519 }
520
521 int
522 app_pipeline_routing_delete_default_route(struct app_params *app,
523         uint32_t pipeline_id)
524 {
525         struct pipeline_routing *p;
526
527         struct pipeline_routing_arp_delete_default_msg_req *req;
528         struct pipeline_routing_arp_delete_default_msg_rsp *rsp;
529
530         /* Check input arguments */
531         if (app == NULL)
532                 return -1;
533
534         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
535         if (p == NULL)
536                 return -1;
537
538         /* Allocate and write request */
539         req = app_msg_alloc(app);
540         if (req == NULL)
541                 return -1;
542
543         req->type = PIPELINE_MSG_REQ_CUSTOM;
544         req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL_DEFAULT;
545
546         /* Send request and wait for response */
547         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
548         if (rsp == NULL)
549                 return -1;
550
551         /* Read response and write route */
552         if (rsp->status) {
553                 app_msg_free(app, rsp);
554                 return -1;
555         }
556
557         /* Commit route */
558         p->default_route_present = 0;
559
560         /* Free response */
561         app_msg_free(app, rsp);
562
563         return 0;
564 }
565
566 static int
567 app_pipeline_routing_arp_ls(struct app_params *app, uint32_t pipeline_id)
568 {
569         struct pipeline_routing *p;
570         struct app_pipeline_routing_arp_entry *it;
571
572         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
573         if (p == NULL)
574                 return -EINVAL;
575
576         TAILQ_FOREACH(it, &p->arp_entries, node)
577                 print_arp_entry(it);
578
579         if (p->default_arp_entry_present)
580                 printf("Default entry: port %" PRIu32 " (entry ptr = %p)\n",
581                                 p->default_arp_entry_port_id,
582                                 p->default_arp_entry_ptr);
583         else
584                 printf("Default: DROP\n");
585
586         return 0;
587 }
588
589 int
590 app_pipeline_routing_add_arp_entry(struct app_params *app, uint32_t pipeline_id,
591                 struct pipeline_routing_arp_key *key,
592                 struct ether_addr *macaddr)
593 {
594         struct pipeline_routing *p;
595
596         struct pipeline_routing_arp_add_msg_req *req;
597         struct pipeline_routing_arp_add_msg_rsp *rsp;
598
599         struct app_pipeline_routing_arp_entry *entry;
600
601         int new_entry;
602
603         /* Check input arguments */
604         if ((app == NULL) ||
605                 (key == NULL) ||
606                 (macaddr == NULL))
607                 return -1;
608
609         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
610         if (p == NULL)
611                 return -1;
612
613         switch (key->type) {
614         case PIPELINE_ROUTING_ARP_IPV4:
615         {
616                 uint32_t port_id = key->key.ipv4.port_id;
617
618                 /* key */
619                 if (port_id >= p->n_ports_out)
620                         return -1;
621         }
622         break;
623
624         default:
625                 return -1;
626         }
627
628         /* Find existing entry or allocate new */
629         entry = app_pipeline_routing_find_arp_entry(p, key);
630         new_entry = (entry == NULL);
631         if (entry == NULL) {
632                 entry = rte_malloc(NULL, sizeof(*entry), RTE_CACHE_LINE_SIZE);
633
634                 if (entry == NULL)
635                         return -1;
636         }
637
638         /* Message buffer allocation */
639         req = app_msg_alloc(app);
640         if (req == NULL) {
641                 if (new_entry)
642                         rte_free(entry);
643                 return -1;
644         }
645
646         req->type = PIPELINE_MSG_REQ_CUSTOM;
647         req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_ADD;
648         memcpy(&req->key, key, sizeof(*key));
649         ether_addr_copy(macaddr, &req->macaddr);
650
651         /* Send request and wait for response */
652         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
653         if (rsp == NULL) {
654                 if (new_entry)
655                         rte_free(entry);
656                 return -1;
657         }
658
659         /* Read response and write entry */
660         if (rsp->status ||
661                 (rsp->entry_ptr == NULL) ||
662                 ((new_entry == 0) && (rsp->key_found == 0)) ||
663                 ((new_entry == 1) && (rsp->key_found == 1))) {
664                 app_msg_free(app, rsp);
665                 if (new_entry)
666                         rte_free(entry);
667                 return -1;
668         }
669
670         memcpy(&entry->key, key, sizeof(*key));
671         ether_addr_copy(macaddr, &entry->macaddr);
672         entry->entry_ptr = rsp->entry_ptr;
673
674         /* Commit entry */
675         if (new_entry) {
676                 TAILQ_INSERT_TAIL(&p->arp_entries, entry, node);
677                 p->n_arp_entries++;
678         }
679
680         print_arp_entry(entry);
681
682         /* Message buffer free */
683         app_msg_free(app, rsp);
684         return 0;
685 }
686
687 int
688 app_pipeline_routing_delete_arp_entry(struct app_params *app,
689         uint32_t pipeline_id,
690         struct pipeline_routing_arp_key *key)
691 {
692         struct pipeline_routing *p;
693
694         struct pipeline_routing_arp_delete_msg_req *req;
695         struct pipeline_routing_arp_delete_msg_rsp *rsp;
696
697         struct app_pipeline_routing_arp_entry *entry;
698
699         /* Check input arguments */
700         if ((app == NULL) ||
701                 (key == NULL))
702                 return -1;
703
704         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
705         if (p == NULL)
706                 return -EINVAL;
707
708         switch (key->type) {
709         case PIPELINE_ROUTING_ARP_IPV4:
710         {
711                 uint32_t port_id = key->key.ipv4.port_id;
712
713                 /* key */
714                 if (port_id >= p->n_ports_out)
715                         return -1;
716         }
717         break;
718
719         default:
720                 return -1;
721         }
722
723         /* Find rule */
724         entry = app_pipeline_routing_find_arp_entry(p, key);
725         if (entry == NULL)
726                 return 0;
727
728         /* Allocate and write request */
729         req = app_msg_alloc(app);
730         if (req == NULL)
731                 return -1;
732
733         req->type = PIPELINE_MSG_REQ_CUSTOM;
734         req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_DEL;
735         memcpy(&req->key, key, sizeof(*key));
736
737         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
738         if (rsp == NULL)
739                 return -1;
740
741         /* Read response */
742         if (rsp->status || !rsp->key_found) {
743                 app_msg_free(app, rsp);
744                 return -1;
745         }
746
747         /* Remove entry */
748         TAILQ_REMOVE(&p->arp_entries, entry, node);
749         p->n_arp_entries--;
750         rte_free(entry);
751
752         /* Free response */
753         app_msg_free(app, rsp);
754
755         return 0;
756 }
757
758 int
759 app_pipeline_routing_add_default_arp_entry(struct app_params *app,
760                 uint32_t pipeline_id,
761                 uint32_t port_id)
762 {
763         struct pipeline_routing *p;
764
765         struct pipeline_routing_arp_add_default_msg_req *req;
766         struct pipeline_routing_arp_add_default_msg_rsp *rsp;
767
768         /* Check input arguments */
769         if (app == NULL)
770                 return -1;
771
772         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
773         if (p == NULL)
774                 return -1;
775
776         if (port_id >= p->n_ports_out)
777                 return -1;
778
779         /* Allocate and write request */
780         req = app_msg_alloc(app);
781         if (req == NULL)
782                 return -1;
783
784         req->type = PIPELINE_MSG_REQ_CUSTOM;
785         req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT;
786         req->port_id = port_id;
787
788         /* Send request and wait for response */
789         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
790         if (rsp == NULL)
791                 return -1;
792
793         /* Read response and write entry */
794         if (rsp->status || rsp->entry_ptr == NULL) {
795                 app_msg_free(app, rsp);
796                 return -1;
797         }
798
799         p->default_arp_entry_port_id = port_id;
800         p->default_arp_entry_ptr = rsp->entry_ptr;
801
802         /* Commit entry */
803         p->default_arp_entry_present = 1;
804
805         /* Free response */
806         app_msg_free(app, rsp);
807
808         return 0;
809 }
810
811 int
812 app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
813         uint32_t pipeline_id)
814 {
815         struct pipeline_routing *p;
816
817         struct pipeline_routing_arp_delete_default_msg_req *req;
818         struct pipeline_routing_arp_delete_default_msg_rsp *rsp;
819
820         /* Check input arguments */
821         if (app == NULL)
822                 return -1;
823
824         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
825         if (p == NULL)
826                 return -EINVAL;
827
828         /* Allocate and write request */
829         req = app_msg_alloc(app);
830         if (req == NULL)
831                 return -ENOMEM;
832
833         req->type = PIPELINE_MSG_REQ_CUSTOM;
834         req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT;
835
836         /* Send request and wait for response */
837         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
838         if (rsp == NULL)
839                 return -ETIMEDOUT;
840
841         /* Read response and write entry */
842         if (rsp->status) {
843                 app_msg_free(app, rsp);
844                 return rsp->status;
845         }
846
847         /* Commit entry */
848         p->default_arp_entry_present = 0;
849
850         /* Free response */
851         app_msg_free(app, rsp);
852
853         return 0;
854 }
855
856 static int
857 parse_labels(char *string, uint32_t *labels, uint32_t *n_labels)
858 {
859         uint32_t n_max_labels = *n_labels, count = 0;
860
861         /* Check for void list of labels */
862         if (strcmp(string, "<void>") == 0) {
863                 *n_labels = 0;
864                 return 0;
865         }
866
867         /* At least one label should be present */
868         for ( ; (*string != '\0'); ) {
869                 char *next;
870                 int value;
871
872                 if (count >= n_max_labels)
873                         return -1;
874
875                 if (count > 0) {
876                         if (string[0] != ':')
877                                 return -1;
878
879                         string++;
880                 }
881
882                 value = strtol(string, &next, 10);
883                 if (next == string)
884                         return -1;
885                 string = next;
886
887                 labels[count++] = (uint32_t) value;
888         }
889
890         *n_labels = count;
891         return 0;
892 }
893
894 /*
895  * route add (mpls = no, qinq = no, arp = no)
896  */
897
898 struct cmd_route_add1_result {
899         cmdline_fixed_string_t p_string;
900         uint32_t p;
901         cmdline_fixed_string_t route_string;
902         cmdline_fixed_string_t add_string;
903         cmdline_ipaddr_t ip;
904         uint32_t depth;
905         cmdline_fixed_string_t port_string;
906         uint32_t port;
907         cmdline_fixed_string_t ether_string;
908         struct ether_addr macaddr;
909 };
910
911 static void
912 cmd_route_add1_parsed(
913         void *parsed_result,
914         __rte_unused struct cmdline *cl,
915         void *data)
916 {
917         struct cmd_route_add1_result *params = parsed_result;
918         struct app_params *app = data;
919         struct pipeline_routing_route_key key;
920         struct pipeline_routing_route_data route_data;
921         int status;
922
923         /* Create route */
924         key.type = PIPELINE_ROUTING_ROUTE_IPV4;
925         key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
926         key.key.ipv4.depth = params->depth;
927
928         route_data.flags = 0;
929         route_data.port_id = params->port;
930         route_data.ethernet.macaddr = params->macaddr;
931
932         status = app_pipeline_routing_add_route(app,
933                 params->p,
934                 &key,
935                 &route_data);
936
937         if (status != 0) {
938                 printf("Command failed\n");
939                 return;
940         }
941 }
942
943 static cmdline_parse_token_string_t cmd_route_add1_p_string =
944         TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, p_string,
945         "p");
946
947 static cmdline_parse_token_num_t cmd_route_add1_p =
948         TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, p, UINT32);
949
950 static cmdline_parse_token_string_t cmd_route_add1_route_string =
951         TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, route_string,
952         "route");
953
954 static cmdline_parse_token_string_t cmd_route_add1_add_string =
955         TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, add_string,
956         "add");
957
958 static cmdline_parse_token_ipaddr_t cmd_route_add1_ip =
959         TOKEN_IPV4_INITIALIZER(struct cmd_route_add1_result, ip);
960
961 static cmdline_parse_token_num_t cmd_route_add1_depth =
962         TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, depth, UINT32);
963
964 static cmdline_parse_token_string_t cmd_route_add1_port_string =
965         TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, port_string,
966         "port");
967
968 static cmdline_parse_token_num_t cmd_route_add1_port =
969         TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, port, UINT32);
970
971 static cmdline_parse_token_string_t cmd_route_add1_ether_string =
972         TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, ether_string,
973         "ether");
974
975 static cmdline_parse_token_etheraddr_t cmd_route_add1_macaddr =
976         TOKEN_ETHERADDR_INITIALIZER(struct cmd_route_add1_result, macaddr);
977
978 static cmdline_parse_inst_t cmd_route_add1 = {
979         .f = cmd_route_add1_parsed,
980         .data = NULL,
981         .help_str = "Route add (mpls = no, qinq = no, arp = no)",
982         .tokens = {
983                 (void *)&cmd_route_add1_p_string,
984                 (void *)&cmd_route_add1_p,
985                 (void *)&cmd_route_add1_route_string,
986                 (void *)&cmd_route_add1_add_string,
987                 (void *)&cmd_route_add1_ip,
988                 (void *)&cmd_route_add1_depth,
989                 (void *)&cmd_route_add1_port_string,
990                 (void *)&cmd_route_add1_port,
991                 (void *)&cmd_route_add1_ether_string,
992                 (void *)&cmd_route_add1_macaddr,
993                 NULL,
994         },
995 };
996
997 /*
998  * route add (mpls = no, qinq = no, arp = yes)
999  */
1000
1001 struct cmd_route_add2_result {
1002         cmdline_fixed_string_t p_string;
1003         uint32_t p;
1004         cmdline_fixed_string_t route_string;
1005         cmdline_fixed_string_t add_string;
1006         cmdline_ipaddr_t ip;
1007         uint32_t depth;
1008         cmdline_fixed_string_t port_string;
1009         uint32_t port;
1010         cmdline_fixed_string_t ether_string;
1011         cmdline_ipaddr_t nh_ip;
1012 };
1013
1014 static void
1015 cmd_route_add2_parsed(
1016         void *parsed_result,
1017         __rte_unused struct cmdline *cl,
1018         void *data)
1019 {
1020         struct cmd_route_add2_result *params = parsed_result;
1021         struct app_params *app = data;
1022         struct pipeline_routing_route_key key;
1023         struct pipeline_routing_route_data route_data;
1024         int status;
1025
1026         /* Create route */
1027         key.type = PIPELINE_ROUTING_ROUTE_IPV4;
1028         key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
1029         key.key.ipv4.depth = params->depth;
1030
1031         route_data.flags = PIPELINE_ROUTING_ROUTE_ARP;
1032         route_data.port_id = params->port;
1033         route_data.ethernet.ip =
1034                 rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
1035
1036         status = app_pipeline_routing_add_route(app,
1037                 params->p,
1038                 &key,
1039                 &route_data);
1040
1041         if (status != 0) {
1042                 printf("Command failed\n");
1043                 return;
1044         }
1045 }
1046
1047 static cmdline_parse_token_string_t cmd_route_add2_p_string =
1048         TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, p_string,
1049         "p");
1050
1051 static cmdline_parse_token_num_t cmd_route_add2_p =
1052         TOKEN_NUM_INITIALIZER(struct cmd_route_add2_result, p, UINT32);
1053
1054 static cmdline_parse_token_string_t cmd_route_add2_route_string =
1055         TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, route_string,
1056         "route");
1057
1058 static cmdline_parse_token_string_t cmd_route_add2_add_string =
1059         TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, add_string,
1060         "add");
1061
1062 static cmdline_parse_token_ipaddr_t cmd_route_add2_ip =
1063         TOKEN_IPV4_INITIALIZER(struct cmd_route_add2_result, ip);
1064
1065 static cmdline_parse_token_num_t cmd_route_add2_depth =
1066         TOKEN_NUM_INITIALIZER(struct cmd_route_add2_result, depth, UINT32);
1067
1068 static cmdline_parse_token_string_t cmd_route_add2_port_string =
1069         TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, port_string,
1070         "port");
1071
1072 static cmdline_parse_token_num_t cmd_route_add2_port =
1073         TOKEN_NUM_INITIALIZER(struct cmd_route_add2_result, port, UINT32);
1074
1075 static cmdline_parse_token_string_t cmd_route_add2_ether_string =
1076         TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, ether_string,
1077         "ether");
1078
1079 static cmdline_parse_token_ipaddr_t cmd_route_add2_nh_ip =
1080         TOKEN_IPV4_INITIALIZER(struct cmd_route_add2_result, nh_ip);
1081
1082 static cmdline_parse_inst_t cmd_route_add2 = {
1083         .f = cmd_route_add2_parsed,
1084         .data = NULL,
1085         .help_str = "Route add (mpls = no, qinq = no, arp = yes)",
1086         .tokens = {
1087                 (void *)&cmd_route_add2_p_string,
1088                 (void *)&cmd_route_add2_p,
1089                 (void *)&cmd_route_add2_route_string,
1090                 (void *)&cmd_route_add2_add_string,
1091                 (void *)&cmd_route_add2_ip,
1092                 (void *)&cmd_route_add2_depth,
1093                 (void *)&cmd_route_add2_port_string,
1094                 (void *)&cmd_route_add2_port,
1095                 (void *)&cmd_route_add2_ether_string,
1096                 (void *)&cmd_route_add2_nh_ip,
1097                 NULL,
1098         },
1099 };
1100
1101 /*
1102  * route add (mpls = no, qinq = yes, arp = no)
1103  */
1104
1105 struct cmd_route_add3_result {
1106         cmdline_fixed_string_t p_string;
1107         uint32_t p;
1108         cmdline_fixed_string_t route_string;
1109         cmdline_fixed_string_t add_string;
1110         cmdline_ipaddr_t ip;
1111         uint32_t depth;
1112         cmdline_fixed_string_t port_string;
1113         uint32_t port;
1114         cmdline_fixed_string_t ether_string;
1115         struct ether_addr macaddr;
1116         cmdline_fixed_string_t qinq_string;
1117         uint32_t svlan;
1118         uint32_t cvlan;
1119 };
1120
1121 static void
1122 cmd_route_add3_parsed(
1123         void *parsed_result,
1124         __rte_unused struct cmdline *cl,
1125         void *data)
1126 {
1127         struct cmd_route_add3_result *params = parsed_result;
1128         struct app_params *app = data;
1129         struct pipeline_routing_route_key key;
1130         struct pipeline_routing_route_data route_data;
1131         int status;
1132
1133         /* Create route */
1134         key.type = PIPELINE_ROUTING_ROUTE_IPV4;
1135         key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
1136         key.key.ipv4.depth = params->depth;
1137
1138         route_data.flags = PIPELINE_ROUTING_ROUTE_QINQ;
1139         route_data.port_id = params->port;
1140         route_data.ethernet.macaddr = params->macaddr;
1141         route_data.l2.qinq.svlan = params->svlan;
1142         route_data.l2.qinq.cvlan = params->cvlan;
1143
1144         status = app_pipeline_routing_add_route(app,
1145                 params->p,
1146                 &key,
1147                 &route_data);
1148
1149         if (status != 0) {
1150                 printf("Command failed\n");
1151                 return;
1152         }
1153 }
1154
1155 static cmdline_parse_token_string_t cmd_route_add3_p_string =
1156         TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, p_string,
1157         "p");
1158
1159 static cmdline_parse_token_num_t cmd_route_add3_p =
1160         TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, p, UINT32);
1161
1162 static cmdline_parse_token_string_t cmd_route_add3_route_string =
1163         TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, route_string,
1164         "route");
1165
1166 static cmdline_parse_token_string_t cmd_route_add3_add_string =
1167         TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, add_string,
1168         "add");
1169
1170 static cmdline_parse_token_ipaddr_t cmd_route_add3_ip =
1171         TOKEN_IPV4_INITIALIZER(struct cmd_route_add3_result, ip);
1172
1173 static cmdline_parse_token_num_t cmd_route_add3_depth =
1174         TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, depth, UINT32);
1175
1176 static cmdline_parse_token_string_t cmd_route_add3_port_string =
1177         TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, port_string,
1178         "port");
1179
1180 static cmdline_parse_token_num_t cmd_route_add3_port =
1181         TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, port, UINT32);
1182
1183 static cmdline_parse_token_string_t cmd_route_add3_ether_string =
1184         TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, ether_string,
1185         "ether");
1186
1187 static cmdline_parse_token_etheraddr_t cmd_route_add3_macaddr =
1188         TOKEN_ETHERADDR_INITIALIZER(struct cmd_route_add3_result, macaddr);
1189
1190 static cmdline_parse_token_string_t cmd_route_add3_qinq_string =
1191         TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, qinq_string,
1192         "qinq");
1193
1194 static cmdline_parse_token_num_t cmd_route_add3_svlan =
1195         TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, svlan, UINT32);
1196
1197 static cmdline_parse_token_num_t cmd_route_add3_cvlan =
1198         TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, cvlan, UINT32);
1199
1200 static cmdline_parse_inst_t cmd_route_add3 = {
1201         .f = cmd_route_add3_parsed,
1202         .data = NULL,
1203         .help_str = "Route add (qinq = yes, arp = no)",
1204         .tokens = {
1205                 (void *)&cmd_route_add3_p_string,
1206                 (void *)&cmd_route_add3_p,
1207                 (void *)&cmd_route_add3_route_string,
1208                 (void *)&cmd_route_add3_add_string,
1209                 (void *)&cmd_route_add3_ip,
1210                 (void *)&cmd_route_add3_depth,
1211                 (void *)&cmd_route_add3_port_string,
1212                 (void *)&cmd_route_add3_port,
1213                 (void *)&cmd_route_add3_ether_string,
1214                 (void *)&cmd_route_add3_macaddr,
1215                 (void *)&cmd_route_add3_qinq_string,
1216                 (void *)&cmd_route_add3_svlan,
1217                 (void *)&cmd_route_add3_cvlan,
1218                 NULL,
1219         },
1220 };
1221
1222 /*
1223  * route add (mpls = no, qinq = yes, arp = yes)
1224  */
1225
1226 struct cmd_route_add4_result {
1227         cmdline_fixed_string_t p_string;
1228         uint32_t p;
1229         cmdline_fixed_string_t route_string;
1230         cmdline_fixed_string_t add_string;
1231         cmdline_ipaddr_t ip;
1232         uint32_t depth;
1233         cmdline_fixed_string_t port_string;
1234         uint32_t port;
1235         cmdline_fixed_string_t ether_string;
1236         cmdline_ipaddr_t nh_ip;
1237         cmdline_fixed_string_t qinq_string;
1238         uint32_t svlan;
1239         uint32_t cvlan;
1240 };
1241
1242 static void
1243 cmd_route_add4_parsed(
1244         void *parsed_result,
1245         __rte_unused struct cmdline *cl,
1246         void *data)
1247 {
1248         struct cmd_route_add4_result *params = parsed_result;
1249         struct app_params *app = data;
1250         struct pipeline_routing_route_key key;
1251         struct pipeline_routing_route_data route_data;
1252         int status;
1253
1254         /* Create route */
1255         key.type = PIPELINE_ROUTING_ROUTE_IPV4;
1256         key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
1257         key.key.ipv4.depth = params->depth;
1258
1259         route_data.flags = PIPELINE_ROUTING_ROUTE_QINQ |
1260                 PIPELINE_ROUTING_ROUTE_ARP;
1261         route_data.port_id = params->port;
1262         route_data.ethernet.ip =
1263                 rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
1264         route_data.l2.qinq.svlan = params->svlan;
1265         route_data.l2.qinq.cvlan = params->cvlan;
1266
1267         status = app_pipeline_routing_add_route(app,
1268                 params->p,
1269                 &key,
1270                 &route_data);
1271
1272         if (status != 0) {
1273                 printf("Command failed\n");
1274                 return;
1275         }
1276 }
1277
1278 static cmdline_parse_token_string_t cmd_route_add4_p_string =
1279         TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, p_string,
1280         "p");
1281
1282 static cmdline_parse_token_num_t cmd_route_add4_p =
1283         TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, p, UINT32);
1284
1285 static cmdline_parse_token_string_t cmd_route_add4_route_string =
1286         TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, route_string,
1287         "route");
1288
1289 static cmdline_parse_token_string_t cmd_route_add4_add_string =
1290         TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, add_string,
1291         "add");
1292
1293 static cmdline_parse_token_ipaddr_t cmd_route_add4_ip =
1294         TOKEN_IPV4_INITIALIZER(struct cmd_route_add4_result, ip);
1295
1296 static cmdline_parse_token_num_t cmd_route_add4_depth =
1297         TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, depth, UINT32);
1298
1299 static cmdline_parse_token_string_t cmd_route_add4_port_string =
1300         TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, port_string,
1301         "port");
1302
1303 static cmdline_parse_token_num_t cmd_route_add4_port =
1304         TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, port, UINT32);
1305
1306 static cmdline_parse_token_string_t cmd_route_add4_ether_string =
1307         TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, ether_string,
1308         "ether");
1309
1310 static cmdline_parse_token_ipaddr_t cmd_route_add4_nh_ip =
1311         TOKEN_IPV4_INITIALIZER(struct cmd_route_add4_result, nh_ip);
1312
1313 static cmdline_parse_token_string_t cmd_route_add4_qinq_string =
1314         TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, qinq_string,
1315         "qinq");
1316
1317 static cmdline_parse_token_num_t cmd_route_add4_svlan =
1318         TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, svlan, UINT32);
1319
1320 static cmdline_parse_token_num_t cmd_route_add4_cvlan =
1321         TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, cvlan, UINT32);
1322
1323 static cmdline_parse_inst_t cmd_route_add4 = {
1324         .f = cmd_route_add4_parsed,
1325         .data = NULL,
1326         .help_str = "Route add (qinq = yes, arp = yes)",
1327         .tokens = {
1328                 (void *)&cmd_route_add4_p_string,
1329                 (void *)&cmd_route_add4_p,
1330                 (void *)&cmd_route_add4_route_string,
1331                 (void *)&cmd_route_add4_add_string,
1332                 (void *)&cmd_route_add4_ip,
1333                 (void *)&cmd_route_add4_depth,
1334                 (void *)&cmd_route_add4_port_string,
1335                 (void *)&cmd_route_add4_port,
1336                 (void *)&cmd_route_add4_ether_string,
1337                 (void *)&cmd_route_add4_nh_ip,
1338                 (void *)&cmd_route_add4_qinq_string,
1339                 (void *)&cmd_route_add4_svlan,
1340                 (void *)&cmd_route_add4_cvlan,
1341                 NULL,
1342         },
1343 };
1344
1345 /*
1346  * route add (mpls = yes, qinq = no, arp = no)
1347  */
1348
1349 struct cmd_route_add5_result {
1350         cmdline_fixed_string_t p_string;
1351         uint32_t p;
1352         cmdline_fixed_string_t route_string;
1353         cmdline_fixed_string_t add_string;
1354         cmdline_ipaddr_t ip;
1355         uint32_t depth;
1356         cmdline_fixed_string_t port_string;
1357         uint32_t port;
1358         cmdline_fixed_string_t ether_string;
1359         struct ether_addr macaddr;
1360         cmdline_fixed_string_t mpls_string;
1361         cmdline_fixed_string_t mpls_labels;
1362 };
1363
1364 static void
1365 cmd_route_add5_parsed(
1366         void *parsed_result,
1367         __rte_unused struct cmdline *cl,
1368         void *data)
1369 {
1370         struct cmd_route_add5_result *params = parsed_result;
1371         struct app_params *app = data;
1372         struct pipeline_routing_route_key key;
1373         struct pipeline_routing_route_data route_data;
1374         uint32_t mpls_labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
1375         uint32_t n_labels = RTE_DIM(mpls_labels);
1376         uint32_t i;
1377         int status;
1378
1379         /* Parse MPLS labels */
1380         status = parse_labels(params->mpls_labels, mpls_labels, &n_labels);
1381         if (status) {
1382                 printf("MPLS labels parse error\n");
1383                 return;
1384         }
1385
1386         /* Create route */
1387         key.type = PIPELINE_ROUTING_ROUTE_IPV4;
1388         key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
1389         key.key.ipv4.depth = params->depth;
1390
1391         route_data.flags = PIPELINE_ROUTING_ROUTE_MPLS;
1392         route_data.port_id = params->port;
1393         route_data.ethernet.macaddr = params->macaddr;
1394         for (i = 0; i < n_labels; i++)
1395                 route_data.l2.mpls.labels[i] = mpls_labels[i];
1396         route_data.l2.mpls.n_labels = n_labels;
1397
1398         status = app_pipeline_routing_add_route(app,
1399                 params->p,
1400                 &key,
1401                 &route_data);
1402
1403         if (status != 0) {
1404                 printf("Command failed\n");
1405                 return;
1406         }
1407 }
1408
1409 static cmdline_parse_token_string_t cmd_route_add5_p_string =
1410         TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, p_string,
1411         "p");
1412
1413 static cmdline_parse_token_num_t cmd_route_add5_p =
1414         TOKEN_NUM_INITIALIZER(struct cmd_route_add5_result, p, UINT32);
1415
1416 static cmdline_parse_token_string_t cmd_route_add5_route_string =
1417         TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, route_string,
1418         "route");
1419
1420 static cmdline_parse_token_string_t cmd_route_add5_add_string =
1421         TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, add_string,
1422         "add");
1423
1424 static cmdline_parse_token_ipaddr_t cmd_route_add5_ip =
1425         TOKEN_IPV4_INITIALIZER(struct cmd_route_add5_result, ip);
1426
1427 static cmdline_parse_token_num_t cmd_route_add5_depth =
1428         TOKEN_NUM_INITIALIZER(struct cmd_route_add5_result, depth, UINT32);
1429
1430 static cmdline_parse_token_string_t cmd_route_add5_port_string =
1431         TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, port_string,
1432         "port");
1433
1434 static cmdline_parse_token_num_t cmd_route_add5_port =
1435         TOKEN_NUM_INITIALIZER(struct cmd_route_add5_result, port, UINT32);
1436
1437 static cmdline_parse_token_string_t cmd_route_add5_ether_string =
1438         TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, ether_string,
1439         "ether");
1440
1441 static cmdline_parse_token_etheraddr_t cmd_route_add5_macaddr =
1442         TOKEN_ETHERADDR_INITIALIZER(struct cmd_route_add5_result, macaddr);
1443
1444 static cmdline_parse_token_string_t cmd_route_add5_mpls_string =
1445         TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, mpls_string,
1446         "mpls");
1447
1448 static cmdline_parse_token_string_t cmd_route_add5_mpls_labels =
1449         TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, mpls_labels,
1450         NULL);
1451
1452 static cmdline_parse_inst_t cmd_route_add5 = {
1453         .f = cmd_route_add5_parsed,
1454         .data = NULL,
1455         .help_str = "Route add (mpls = yes, arp = no)",
1456         .tokens = {
1457                 (void *)&cmd_route_add5_p_string,
1458                 (void *)&cmd_route_add5_p,
1459                 (void *)&cmd_route_add5_route_string,
1460                 (void *)&cmd_route_add5_add_string,
1461                 (void *)&cmd_route_add5_ip,
1462                 (void *)&cmd_route_add5_depth,
1463                 (void *)&cmd_route_add5_port_string,
1464                 (void *)&cmd_route_add5_port,
1465                 (void *)&cmd_route_add5_ether_string,
1466                 (void *)&cmd_route_add5_macaddr,
1467                 (void *)&cmd_route_add5_mpls_string,
1468                 (void *)&cmd_route_add5_mpls_labels,
1469                 NULL,
1470         },
1471 };
1472
1473 /*
1474  * route add (mpls = yes, qinq = no, arp = yes)
1475  */
1476
1477 struct cmd_route_add6_result {
1478         cmdline_fixed_string_t p_string;
1479         uint32_t p;
1480         cmdline_fixed_string_t route_string;
1481         cmdline_fixed_string_t add_string;
1482         cmdline_ipaddr_t ip;
1483         uint32_t depth;
1484         cmdline_fixed_string_t port_string;
1485         uint32_t port;
1486         cmdline_fixed_string_t ether_string;
1487         cmdline_ipaddr_t nh_ip;
1488         cmdline_fixed_string_t mpls_string;
1489         cmdline_fixed_string_t mpls_labels;
1490 };
1491
1492 static void
1493 cmd_route_add6_parsed(
1494         void *parsed_result,
1495         __rte_unused struct cmdline *cl,
1496         void *data)
1497 {
1498         struct cmd_route_add6_result *params = parsed_result;
1499         struct app_params *app = data;
1500         struct pipeline_routing_route_key key;
1501         struct pipeline_routing_route_data route_data;
1502         uint32_t mpls_labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
1503         uint32_t n_labels = RTE_DIM(mpls_labels);
1504         uint32_t i;
1505         int status;
1506
1507         /* Parse MPLS labels */
1508         status = parse_labels(params->mpls_labels, mpls_labels, &n_labels);
1509         if (status) {
1510                 printf("MPLS labels parse error\n");
1511                 return;
1512         }
1513
1514         /* Create route */
1515         key.type = PIPELINE_ROUTING_ROUTE_IPV4;
1516         key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
1517         key.key.ipv4.depth = params->depth;
1518
1519         route_data.flags = PIPELINE_ROUTING_ROUTE_MPLS |
1520                 PIPELINE_ROUTING_ROUTE_ARP;
1521         route_data.port_id = params->port;
1522         route_data.ethernet.ip =
1523                 rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
1524         for (i = 0; i < n_labels; i++)
1525                 route_data.l2.mpls.labels[i] = mpls_labels[i];
1526         route_data.l2.mpls.n_labels = n_labels;
1527
1528         status = app_pipeline_routing_add_route(app,
1529                 params->p,
1530                 &key,
1531                 &route_data);
1532
1533         if (status != 0) {
1534                 printf("Command failed\n");
1535                 return;
1536         }
1537 }
1538
1539 static cmdline_parse_token_string_t cmd_route_add6_p_string =
1540         TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, p_string,
1541         "p");
1542
1543 static cmdline_parse_token_num_t cmd_route_add6_p =
1544         TOKEN_NUM_INITIALIZER(struct cmd_route_add6_result, p, UINT32);
1545
1546 static cmdline_parse_token_string_t cmd_route_add6_route_string =
1547         TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, route_string,
1548         "route");
1549
1550 static cmdline_parse_token_string_t cmd_route_add6_add_string =
1551         TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, add_string,
1552         "add");
1553
1554 static cmdline_parse_token_ipaddr_t cmd_route_add6_ip =
1555         TOKEN_IPV4_INITIALIZER(struct cmd_route_add6_result, ip);
1556
1557 static cmdline_parse_token_num_t cmd_route_add6_depth =
1558         TOKEN_NUM_INITIALIZER(struct cmd_route_add6_result, depth, UINT32);
1559
1560 static cmdline_parse_token_string_t cmd_route_add6_port_string =
1561         TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, port_string,
1562         "port");
1563
1564 static cmdline_parse_token_num_t cmd_route_add6_port =
1565         TOKEN_NUM_INITIALIZER(struct cmd_route_add6_result, port, UINT32);
1566
1567 static cmdline_parse_token_string_t cmd_route_add6_ether_string =
1568         TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, ether_string,
1569         "ether");
1570
1571 static cmdline_parse_token_ipaddr_t cmd_route_add6_nh_ip =
1572         TOKEN_IPV4_INITIALIZER(struct cmd_route_add6_result, nh_ip);
1573
1574 static cmdline_parse_token_string_t cmd_route_add6_mpls_string =
1575         TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, mpls_string,
1576         "mpls");
1577
1578 static cmdline_parse_token_string_t cmd_route_add6_mpls_labels =
1579         TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, mpls_labels,
1580         NULL);
1581
1582 static cmdline_parse_inst_t cmd_route_add6 = {
1583         .f = cmd_route_add6_parsed,
1584         .data = NULL,
1585         .help_str = "Route add (mpls = yes, arp = yes)",
1586         .tokens = {
1587                 (void *)&cmd_route_add6_p_string,
1588                 (void *)&cmd_route_add6_p,
1589                 (void *)&cmd_route_add6_route_string,
1590                 (void *)&cmd_route_add6_add_string,
1591                 (void *)&cmd_route_add6_ip,
1592                 (void *)&cmd_route_add6_depth,
1593                 (void *)&cmd_route_add6_port_string,
1594                 (void *)&cmd_route_add6_port,
1595                 (void *)&cmd_route_add6_ether_string,
1596                 (void *)&cmd_route_add6_nh_ip,
1597                 (void *)&cmd_route_add6_mpls_string,
1598                 (void *)&cmd_route_add6_mpls_labels,
1599                 NULL,
1600         },
1601 };
1602
1603 /*
1604  * route del
1605  */
1606
1607 struct cmd_route_del_result {
1608         cmdline_fixed_string_t p_string;
1609         uint32_t p;
1610         cmdline_fixed_string_t route_string;
1611         cmdline_fixed_string_t del_string;
1612         cmdline_ipaddr_t ip;
1613         uint32_t depth;
1614 };
1615
1616 static void
1617 cmd_route_del_parsed(
1618         void *parsed_result,
1619         __rte_unused struct cmdline *cl,
1620         void *data)
1621 {
1622         struct cmd_route_del_result *params = parsed_result;
1623         struct app_params *app = data;
1624         struct pipeline_routing_route_key key;
1625
1626         int status;
1627
1628         /* Create route */
1629         key.type = PIPELINE_ROUTING_ROUTE_IPV4;
1630         key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
1631         key.key.ipv4.depth = params->depth;
1632
1633         status = app_pipeline_routing_delete_route(app, params->p, &key);
1634
1635         if (status != 0) {
1636                 printf("Command failed\n");
1637                 return;
1638         }
1639 }
1640
1641 static cmdline_parse_token_string_t cmd_route_del_p_string =
1642         TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, p_string,
1643         "p");
1644
1645 static cmdline_parse_token_num_t cmd_route_del_p =
1646         TOKEN_NUM_INITIALIZER(struct cmd_route_del_result, p, UINT32);
1647
1648 static cmdline_parse_token_string_t cmd_route_del_route_string =
1649         TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, route_string,
1650         "route");
1651
1652 static cmdline_parse_token_string_t cmd_route_del_del_string =
1653         TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, del_string,
1654         "del");
1655
1656 static cmdline_parse_token_ipaddr_t cmd_route_del_ip =
1657         TOKEN_IPV4_INITIALIZER(struct cmd_route_del_result, ip);
1658
1659 static cmdline_parse_token_num_t cmd_route_del_depth =
1660         TOKEN_NUM_INITIALIZER(struct cmd_route_del_result, depth, UINT32);
1661
1662 static cmdline_parse_inst_t cmd_route_del = {
1663         .f = cmd_route_del_parsed,
1664         .data = NULL,
1665         .help_str = "Route delete",
1666         .tokens = {
1667                 (void *)&cmd_route_del_p_string,
1668                 (void *)&cmd_route_del_p,
1669                 (void *)&cmd_route_del_route_string,
1670                 (void *)&cmd_route_del_del_string,
1671                 (void *)&cmd_route_del_ip,
1672                 (void *)&cmd_route_del_depth,
1673                 NULL,
1674         },
1675 };
1676
1677 /*
1678  * route add default
1679  */
1680
1681 struct cmd_route_add_default_result {
1682         cmdline_fixed_string_t p_string;
1683         uint32_t p;
1684         cmdline_fixed_string_t route_string;
1685         cmdline_fixed_string_t add_string;
1686         cmdline_fixed_string_t default_string;
1687         uint32_t port;
1688 };
1689
1690 static void
1691 cmd_route_add_default_parsed(
1692         void *parsed_result,
1693         __attribute__((unused)) struct cmdline *cl,
1694         void *data)
1695 {
1696         struct cmd_route_add_default_result *params = parsed_result;
1697         struct app_params *app = data;
1698         int status;
1699
1700         status = app_pipeline_routing_add_default_route(app, params->p,
1701                         params->port);
1702
1703         if (status != 0) {
1704                 printf("Command failed\n");
1705                 return;
1706         }
1707 }
1708
1709 static cmdline_parse_token_string_t cmd_route_add_default_p_string =
1710         TOKEN_STRING_INITIALIZER(struct cmd_route_add_default_result, p_string,
1711         "p");
1712
1713 static cmdline_parse_token_num_t cmd_route_add_default_p =
1714         TOKEN_NUM_INITIALIZER(struct cmd_route_add_default_result, p, UINT32);
1715
1716 cmdline_parse_token_string_t cmd_route_add_default_route_string =
1717         TOKEN_STRING_INITIALIZER(struct cmd_route_add_default_result,
1718                 route_string, "route");
1719
1720 cmdline_parse_token_string_t cmd_route_add_default_add_string =
1721         TOKEN_STRING_INITIALIZER(struct cmd_route_add_default_result,
1722                 add_string, "add");
1723
1724 cmdline_parse_token_string_t cmd_route_add_default_default_string =
1725         TOKEN_STRING_INITIALIZER(struct cmd_route_add_default_result,
1726         default_string, "default");
1727
1728 cmdline_parse_token_num_t cmd_route_add_default_port =
1729         TOKEN_NUM_INITIALIZER(struct cmd_route_add_default_result,
1730                 port, UINT32);
1731
1732 cmdline_parse_inst_t cmd_route_add_default = {
1733         .f = cmd_route_add_default_parsed,
1734         .data = NULL,
1735         .help_str = "Route default set",
1736         .tokens = {
1737                 (void *)&cmd_route_add_default_p_string,
1738                 (void *)&cmd_route_add_default_p,
1739                 (void *)&cmd_route_add_default_route_string,
1740                 (void *)&cmd_route_add_default_add_string,
1741                 (void *)&cmd_route_add_default_default_string,
1742                 (void *)&cmd_route_add_default_port,
1743                 NULL,
1744         },
1745 };
1746
1747 /*
1748  * route del default
1749  */
1750
1751 struct cmd_route_del_default_result {
1752         cmdline_fixed_string_t p_string;
1753         uint32_t p;
1754         cmdline_fixed_string_t route_string;
1755         cmdline_fixed_string_t del_string;
1756         cmdline_fixed_string_t default_string;
1757 };
1758
1759 static void
1760 cmd_route_del_default_parsed(
1761         void *parsed_result,
1762         __rte_unused struct cmdline *cl,
1763          void *data)
1764 {
1765         struct cmd_route_del_default_result *params = parsed_result;
1766         struct app_params *app = data;
1767         int status;
1768
1769         status = app_pipeline_routing_delete_default_route(app, params->p);
1770
1771         if (status != 0) {
1772                 printf("Command failed\n");
1773                 return;
1774         }
1775 }
1776
1777 static cmdline_parse_token_string_t cmd_route_del_default_p_string =
1778         TOKEN_STRING_INITIALIZER(struct cmd_route_del_default_result, p_string,
1779         "p");
1780
1781 static cmdline_parse_token_num_t cmd_route_del_default_p =
1782         TOKEN_NUM_INITIALIZER(struct cmd_route_del_default_result, p, UINT32);
1783
1784 static cmdline_parse_token_string_t cmd_route_del_default_route_string =
1785         TOKEN_STRING_INITIALIZER(struct cmd_route_del_default_result,
1786                 route_string, "route");
1787
1788 static cmdline_parse_token_string_t cmd_route_del_default_del_string =
1789         TOKEN_STRING_INITIALIZER(struct cmd_route_del_default_result,
1790                 del_string, "del");
1791
1792 static cmdline_parse_token_string_t cmd_route_del_default_default_string =
1793         TOKEN_STRING_INITIALIZER(struct cmd_route_del_default_result,
1794         default_string, "default");
1795
1796
1797 static cmdline_parse_inst_t cmd_route_del_default = {
1798         .f = cmd_route_del_default_parsed,
1799         .data = NULL,
1800         .help_str = "Route default clear",
1801         .tokens = {
1802                 (void *)&cmd_route_del_default_p_string,
1803                 (void *)&cmd_route_del_default_p,
1804                 (void *)&cmd_route_del_default_route_string,
1805                 (void *)&cmd_route_del_default_del_string,
1806                 (void *)&cmd_route_del_default_default_string,
1807                 NULL,
1808         },
1809 };
1810
1811 /*
1812  * route ls
1813  */
1814
1815 struct cmd_route_ls_result {
1816         cmdline_fixed_string_t p_string;
1817         uint32_t p;
1818         cmdline_fixed_string_t route_string;
1819         cmdline_fixed_string_t ls_string;
1820 };
1821
1822 static void
1823 cmd_route_ls_parsed(
1824         void *parsed_result,
1825         __rte_unused struct cmdline *cl,
1826         void *data)
1827 {
1828         struct cmd_route_ls_result *params = parsed_result;
1829         struct app_params *app = data;
1830         int status;
1831
1832         status = app_pipeline_routing_route_ls(app, params->p);
1833
1834         if (status != 0) {
1835                 printf("Command failed\n");
1836                 return;
1837         }
1838 }
1839
1840 static cmdline_parse_token_string_t cmd_route_ls_p_string =
1841         TOKEN_STRING_INITIALIZER(struct cmd_route_ls_result, p_string, "p");
1842
1843 static cmdline_parse_token_num_t cmd_route_ls_p =
1844         TOKEN_NUM_INITIALIZER(struct cmd_route_ls_result, p, UINT32);
1845
1846 static cmdline_parse_token_string_t cmd_route_ls_route_string =
1847         TOKEN_STRING_INITIALIZER(struct cmd_route_ls_result,
1848         route_string, "route");
1849
1850 static cmdline_parse_token_string_t cmd_route_ls_ls_string =
1851         TOKEN_STRING_INITIALIZER(struct cmd_route_ls_result, ls_string,
1852         "ls");
1853
1854 static cmdline_parse_inst_t cmd_route_ls = {
1855         .f = cmd_route_ls_parsed,
1856         .data = NULL,
1857         .help_str = "Route list",
1858         .tokens = {
1859                 (void *)&cmd_route_ls_p_string,
1860                 (void *)&cmd_route_ls_p,
1861                 (void *)&cmd_route_ls_route_string,
1862                 (void *)&cmd_route_ls_ls_string,
1863                 NULL,
1864         },
1865 };
1866
1867 /*
1868  * arp add
1869  */
1870
1871 struct cmd_arp_add_result {
1872         cmdline_fixed_string_t p_string;
1873         uint32_t p;
1874         cmdline_fixed_string_t arp_string;
1875         cmdline_fixed_string_t add_string;
1876         uint32_t port_id;
1877         cmdline_ipaddr_t ip;
1878         struct ether_addr macaddr;
1879
1880 };
1881
1882 static void
1883 cmd_arp_add_parsed(
1884         void *parsed_result,
1885         __rte_unused struct cmdline *cl,
1886         void *data)
1887 {
1888         struct cmd_arp_add_result *params = parsed_result;
1889         struct app_params *app = data;
1890
1891         struct pipeline_routing_arp_key key;
1892         int status;
1893
1894         key.type = PIPELINE_ROUTING_ARP_IPV4;
1895         key.key.ipv4.port_id = params->port_id;
1896         key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
1897
1898         status = app_pipeline_routing_add_arp_entry(app,
1899                 params->p,
1900                 &key,
1901                 &params->macaddr);
1902
1903         if (status != 0) {
1904                 printf("Command failed\n");
1905                 return;
1906         }
1907 }
1908
1909 static cmdline_parse_token_string_t cmd_arp_add_p_string =
1910         TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, p_string,
1911         "p");
1912
1913 static cmdline_parse_token_num_t cmd_arp_add_p =
1914         TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, p, UINT32);
1915
1916 static cmdline_parse_token_string_t cmd_arp_add_arp_string =
1917         TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, arp_string, "arp");
1918
1919 static cmdline_parse_token_string_t cmd_arp_add_add_string =
1920         TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, add_string, "add");
1921
1922 static cmdline_parse_token_num_t cmd_arp_add_port_id =
1923         TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, port_id, UINT32);
1924
1925 static cmdline_parse_token_ipaddr_t cmd_arp_add_ip =
1926         TOKEN_IPV4_INITIALIZER(struct cmd_arp_add_result, ip);
1927
1928 static cmdline_parse_token_etheraddr_t cmd_arp_add_macaddr =
1929         TOKEN_ETHERADDR_INITIALIZER(struct cmd_arp_add_result, macaddr);
1930
1931 static cmdline_parse_inst_t cmd_arp_add = {
1932         .f = cmd_arp_add_parsed,
1933         .data = NULL,
1934         .help_str = "ARP add",
1935         .tokens = {
1936                 (void *)&cmd_arp_add_p_string,
1937                 (void *)&cmd_arp_add_p,
1938                 (void *)&cmd_arp_add_arp_string,
1939                 (void *)&cmd_arp_add_add_string,
1940                 (void *)&cmd_arp_add_port_id,
1941                 (void *)&cmd_arp_add_ip,
1942                 (void *)&cmd_arp_add_macaddr,
1943                 NULL,
1944         },
1945 };
1946
1947 /*
1948  * arp del
1949  */
1950
1951 struct cmd_arp_del_result {
1952         cmdline_fixed_string_t p_string;
1953         uint32_t p;
1954         cmdline_fixed_string_t arp_string;
1955         cmdline_fixed_string_t del_string;
1956         uint32_t port_id;
1957         cmdline_ipaddr_t ip;
1958 };
1959
1960 static void
1961 cmd_arp_del_parsed(
1962         void *parsed_result,
1963         __rte_unused struct cmdline *cl,
1964         void *data)
1965 {
1966         struct cmd_arp_del_result *params = parsed_result;
1967         struct app_params *app = data;
1968
1969         struct pipeline_routing_arp_key key;
1970         int status;
1971
1972         key.type = PIPELINE_ROUTING_ARP_IPV4;
1973         key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
1974         key.key.ipv4.port_id = params->port_id;
1975
1976         status = app_pipeline_routing_delete_arp_entry(app, params->p, &key);
1977
1978         if (status != 0) {
1979                 printf("Command failed\n");
1980                 return;
1981         }
1982 }
1983
1984 static cmdline_parse_token_string_t cmd_arp_del_p_string =
1985         TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, p_string,
1986         "p");
1987
1988 static cmdline_parse_token_num_t cmd_arp_del_p =
1989         TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, p, UINT32);
1990
1991 static cmdline_parse_token_string_t cmd_arp_del_arp_string =
1992         TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "arp");
1993
1994 static cmdline_parse_token_string_t cmd_arp_del_del_string =
1995         TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, del_string, "del");
1996
1997 static cmdline_parse_token_num_t cmd_arp_del_port_id =
1998         TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, port_id, UINT32);
1999
2000 static cmdline_parse_token_ipaddr_t cmd_arp_del_ip =
2001         TOKEN_IPV4_INITIALIZER(struct cmd_arp_del_result, ip);
2002
2003 static cmdline_parse_inst_t cmd_arp_del = {
2004         .f = cmd_arp_del_parsed,
2005         .data = NULL,
2006         .help_str = "ARP delete",
2007         .tokens = {
2008                 (void *)&cmd_arp_del_p_string,
2009                 (void *)&cmd_arp_del_p,
2010                 (void *)&cmd_arp_del_arp_string,
2011                 (void *)&cmd_arp_del_del_string,
2012                 (void *)&cmd_arp_del_port_id,
2013                 (void *)&cmd_arp_del_ip,
2014                 NULL,
2015         },
2016 };
2017
2018 /*
2019  * arp add default
2020  */
2021
2022 struct cmd_arp_add_default_result {
2023         cmdline_fixed_string_t p_string;
2024         uint32_t p;
2025         cmdline_fixed_string_t arp_string;
2026         cmdline_fixed_string_t add_string;
2027         cmdline_fixed_string_t default_string;
2028         uint32_t port_id;
2029 };
2030
2031 static void
2032 cmd_arp_add_default_parsed(
2033         void *parsed_result,
2034         __rte_unused struct cmdline *cl,
2035         void *data)
2036 {
2037         struct cmd_arp_add_default_result *params = parsed_result;
2038         struct app_params *app = data;
2039
2040         int status;
2041
2042         status = app_pipeline_routing_add_default_arp_entry(app,
2043                 params->p,
2044                 params->port_id);
2045
2046         if (status != 0) {
2047                 printf("Command failed\n");
2048                 return;
2049         }
2050 }
2051
2052 static cmdline_parse_token_string_t cmd_arp_add_default_p_string =
2053         TOKEN_STRING_INITIALIZER(struct cmd_arp_add_default_result, p_string,
2054         "p");
2055
2056 static cmdline_parse_token_num_t cmd_arp_add_default_p =
2057         TOKEN_NUM_INITIALIZER(struct cmd_arp_add_default_result, p, UINT32);
2058
2059 static cmdline_parse_token_string_t cmd_arp_add_default_arp_string =
2060         TOKEN_STRING_INITIALIZER(struct cmd_arp_add_default_result, arp_string,
2061         "arp");
2062
2063 static cmdline_parse_token_string_t cmd_arp_add_default_add_string =
2064         TOKEN_STRING_INITIALIZER(struct cmd_arp_add_default_result, add_string,
2065         "add");
2066
2067 static cmdline_parse_token_string_t cmd_arp_add_default_default_string =
2068         TOKEN_STRING_INITIALIZER(struct cmd_arp_add_default_result,
2069                 default_string, "default");
2070
2071 static cmdline_parse_token_num_t cmd_arp_add_default_port_id =
2072         TOKEN_NUM_INITIALIZER(struct cmd_arp_add_default_result, port_id,
2073         UINT32);
2074
2075 static cmdline_parse_inst_t cmd_arp_add_default = {
2076         .f = cmd_arp_add_default_parsed,
2077         .data = NULL,
2078         .help_str = "ARP add default",
2079         .tokens = {
2080                 (void *)&cmd_arp_add_default_p_string,
2081                 (void *)&cmd_arp_add_default_p,
2082                 (void *)&cmd_arp_add_default_arp_string,
2083                 (void *)&cmd_arp_add_default_add_string,
2084                 (void *)&cmd_arp_add_default_default_string,
2085                 (void *)&cmd_arp_add_default_port_id,
2086                 NULL,
2087         },
2088 };
2089
2090 /*
2091  * arp del default
2092  */
2093
2094 struct cmd_arp_del_default_result {
2095         cmdline_fixed_string_t p_string;
2096         uint32_t p;
2097         cmdline_fixed_string_t arp_string;
2098         cmdline_fixed_string_t del_string;
2099         cmdline_fixed_string_t default_string;
2100 };
2101
2102 static void
2103 cmd_arp_del_default_parsed(
2104         void *parsed_result,
2105         __rte_unused struct cmdline *cl,
2106         void *data)
2107 {
2108         struct cmd_arp_del_default_result *params = parsed_result;
2109         struct app_params *app = data;
2110
2111         int status;
2112
2113         status = app_pipeline_routing_delete_default_arp_entry(app, params->p);
2114
2115         if (status != 0) {
2116                 printf("Command failed\n");
2117                 return;
2118         }
2119 }
2120
2121 static cmdline_parse_token_string_t cmd_arp_del_default_p_string =
2122         TOKEN_STRING_INITIALIZER(struct cmd_arp_del_default_result, p_string,
2123         "p");
2124
2125 static cmdline_parse_token_num_t cmd_arp_del_default_p =
2126         TOKEN_NUM_INITIALIZER(struct cmd_arp_del_default_result, p, UINT32);
2127
2128 static cmdline_parse_token_string_t cmd_arp_del_default_arp_string =
2129         TOKEN_STRING_INITIALIZER(struct cmd_arp_del_default_result, arp_string,
2130         "arp");
2131
2132 static cmdline_parse_token_string_t cmd_arp_del_default_del_string =
2133         TOKEN_STRING_INITIALIZER(struct cmd_arp_del_default_result, del_string,
2134         "del");
2135
2136 static cmdline_parse_token_string_t cmd_arp_del_default_default_string =
2137         TOKEN_STRING_INITIALIZER(struct cmd_arp_del_default_result,
2138                 default_string, "default");
2139
2140 static cmdline_parse_inst_t cmd_arp_del_default = {
2141         .f = cmd_arp_del_default_parsed,
2142         .data = NULL,
2143         .help_str = "ARP delete default",
2144         .tokens = {
2145                 (void *)&cmd_arp_del_default_p_string,
2146                 (void *)&cmd_arp_del_default_p,
2147                 (void *)&cmd_arp_del_default_arp_string,
2148                 (void *)&cmd_arp_del_default_del_string,
2149                 (void *)&cmd_arp_del_default_default_string,
2150                 NULL,
2151         },
2152 };
2153
2154 /*
2155  * arp ls
2156  */
2157
2158 struct cmd_arp_ls_result {
2159         cmdline_fixed_string_t p_string;
2160         uint32_t p;
2161         cmdline_fixed_string_t arp_string;
2162         cmdline_fixed_string_t ls_string;
2163 };
2164
2165 static void
2166 cmd_arp_ls_parsed(
2167         void *parsed_result,
2168         __rte_unused struct cmdline *cl,
2169         void *data)
2170 {
2171         struct cmd_arp_ls_result *params = parsed_result;
2172         struct app_params *app = data;
2173         struct pipeline_routing *p;
2174
2175         p = app_pipeline_data_fe(app, params->p, &pipeline_routing);
2176         if (p == NULL)
2177                 return;
2178
2179         app_pipeline_routing_arp_ls(app, params->p);
2180 }
2181
2182 static cmdline_parse_token_string_t cmd_arp_ls_p_string =
2183         TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, p_string,
2184         "p");
2185
2186 static cmdline_parse_token_num_t cmd_arp_ls_p =
2187         TOKEN_NUM_INITIALIZER(struct cmd_arp_ls_result, p, UINT32);
2188
2189 static cmdline_parse_token_string_t cmd_arp_ls_arp_string =
2190         TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, arp_string,
2191         "arp");
2192
2193 static cmdline_parse_token_string_t cmd_arp_ls_ls_string =
2194         TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, ls_string,
2195         "ls");
2196
2197 static cmdline_parse_inst_t cmd_arp_ls = {
2198         .f = cmd_arp_ls_parsed,
2199         .data = NULL,
2200         .help_str = "ARP list",
2201         .tokens = {
2202                 (void *)&cmd_arp_ls_p_string,
2203                 (void *)&cmd_arp_ls_p,
2204                 (void *)&cmd_arp_ls_arp_string,
2205                 (void *)&cmd_arp_ls_ls_string,
2206                 NULL,
2207         },
2208 };
2209
2210 static cmdline_parse_ctx_t pipeline_cmds[] = {
2211         (cmdline_parse_inst_t *)&cmd_route_add1,
2212         (cmdline_parse_inst_t *)&cmd_route_add2,
2213         (cmdline_parse_inst_t *)&cmd_route_add3,
2214         (cmdline_parse_inst_t *)&cmd_route_add4,
2215         (cmdline_parse_inst_t *)&cmd_route_add5,
2216         (cmdline_parse_inst_t *)&cmd_route_add6,
2217         (cmdline_parse_inst_t *)&cmd_route_del,
2218         (cmdline_parse_inst_t *)&cmd_route_add_default,
2219         (cmdline_parse_inst_t *)&cmd_route_del_default,
2220         (cmdline_parse_inst_t *)&cmd_route_ls,
2221         (cmdline_parse_inst_t *)&cmd_arp_add,
2222         (cmdline_parse_inst_t *)&cmd_arp_del,
2223         (cmdline_parse_inst_t *)&cmd_arp_add_default,
2224         (cmdline_parse_inst_t *)&cmd_arp_del_default,
2225         (cmdline_parse_inst_t *)&cmd_arp_ls,
2226         NULL,
2227 };
2228
2229 static struct pipeline_fe_ops pipeline_routing_fe_ops = {
2230         .f_init = pipeline_routing_init,
2231         .f_free = app_pipeline_routing_free,
2232         .cmds = pipeline_cmds,
2233 };
2234
2235 struct pipeline_type pipeline_routing = {
2236         .name = "ROUTING",
2237         .be_ops = &pipeline_routing_be_ops,
2238         .fe_ops = &pipeline_routing_fe_ops,
2239 };