4 * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 #include <cmdline_parse.h>
35 #include <cmdline_parse_num.h>
36 #include <cmdline_parse_string.h>
39 #include "pipeline_common_fe.h"
40 #include "pipeline_routing.h"
43 struct app_pipeline_routing_route {
44 struct pipeline_routing_route_key key;
45 struct pipeline_routing_route_data data;
48 TAILQ_ENTRY(app_pipeline_routing_route) node;
51 struct app_pipeline_routing_arp_entry {
52 struct pipeline_routing_arp_key key;
53 struct ether_addr macaddr;
56 TAILQ_ENTRY(app_pipeline_routing_arp_entry) node;
59 struct pipeline_routing {
61 struct app_params *app;
65 struct pipeline_routing_params rp;
68 uint32_t link_id[PIPELINE_MAX_PORT_OUT];
71 TAILQ_HEAD(, app_pipeline_routing_route) routes;
74 uint32_t default_route_present;
75 uint32_t default_route_port_id;
76 void *default_route_entry_ptr;
79 TAILQ_HEAD(, app_pipeline_routing_arp_entry) arp_entries;
80 uint32_t n_arp_entries;
82 uint32_t default_arp_entry_present;
83 uint32_t default_arp_entry_port_id;
84 void *default_arp_entry_ptr;
88 app_pipeline_routing_find_link(struct pipeline_routing *p,
94 for (i = 0; i < p->n_ports_out; i++)
95 if (p->link_id[i] == link_id) {
104 app_pipeline_routing_link_op(__rte_unused struct app_params *app,
109 struct pipeline_routing_route_key key0, key1;
110 struct pipeline_routing *p = arg;
111 struct app_link_params *lp;
112 uint32_t port_id, netmask;
118 APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, lp);
122 status = app_pipeline_routing_find_link(p,
128 netmask = (~0U) << (32 - lp->depth);
130 /* Local network (directly attached network) */
131 key0.type = PIPELINE_ROUTING_ROUTE_IPV4;
132 key0.key.ipv4.ip = lp->ip & netmask;
133 key0.key.ipv4.depth = lp->depth;
135 /* Local termination */
136 key1.type = PIPELINE_ROUTING_ROUTE_IPV4;
137 key1.key.ipv4.ip = lp->ip;
138 key1.key.ipv4.depth = 32;
141 struct pipeline_routing_route_data data0, data1;
143 /* Local network (directly attached network) */
144 memset(&data0, 0, sizeof(data0));
145 data0.flags = PIPELINE_ROUTING_ROUTE_LOCAL |
146 PIPELINE_ROUTING_ROUTE_ARP;
147 if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ)
148 data0.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
149 if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) {
150 data0.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
151 data0.l2.mpls.n_labels = 1;
153 data0.port_id = port_id;
155 if (p->rp.n_arp_entries)
156 app_pipeline_routing_add_route(app,
161 /* Local termination */
162 memset(&data1, 0, sizeof(data1));
163 data1.flags = PIPELINE_ROUTING_ROUTE_LOCAL |
164 PIPELINE_ROUTING_ROUTE_ARP;
165 if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ)
166 data1.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
167 if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) {
168 data1.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
169 data1.l2.mpls.n_labels = 1;
171 data1.port_id = p->rp.port_local_dest;
173 app_pipeline_routing_add_route(app,
178 /* Local network (directly attached network) */
179 if (p->rp.n_arp_entries)
180 app_pipeline_routing_delete_route(app,
184 /* Local termination */
185 app_pipeline_routing_delete_route(app,
192 app_pipeline_routing_set_link_op(
193 struct app_params *app,
194 struct pipeline_routing *p)
198 for (port_id = 0; port_id < p->n_ports_out; port_id++) {
199 struct app_link_params *link;
203 link = app_pipeline_track_pktq_out_to_link(app,
209 link_id = link - app->link_params;
210 p->link_id[port_id] = link_id;
212 status = app_link_set_op(app,
215 app_pipeline_routing_link_op,
225 app_pipeline_routing_init(struct pipeline_params *params,
228 struct app_params *app = (struct app_params *) arg;
229 struct pipeline_routing *p;
230 uint32_t pipeline_id, size;
233 /* Check input arguments */
234 if ((params == NULL) ||
235 (params->n_ports_in == 0) ||
236 (params->n_ports_out == 0))
239 APP_PARAM_GET_ID(params, "PIPELINE", pipeline_id);
241 /* Memory allocation */
242 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_routing));
243 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
249 p->pipeline_id = pipeline_id;
250 p->n_ports_in = params->n_ports_in;
251 p->n_ports_out = params->n_ports_out;
253 status = pipeline_routing_parse_args(&p->rp, params);
258 TAILQ_INIT(&p->routes);
261 TAILQ_INIT(&p->arp_entries);
262 p->n_arp_entries = 0;
264 app_pipeline_routing_set_link_op(app, p);
270 app_pipeline_routing_post_init(void *pipeline)
272 struct pipeline_routing *p = pipeline;
274 /* Check input arguments */
278 return app_pipeline_routing_set_macaddr(p->app, p->pipeline_id);
282 app_pipeline_routing_free(void *pipeline)
284 struct pipeline_routing *p = pipeline;
286 /* Check input arguments */
291 while (!TAILQ_EMPTY(&p->routes)) {
292 struct app_pipeline_routing_route *route;
294 route = TAILQ_FIRST(&p->routes);
295 TAILQ_REMOVE(&p->routes, route, node);
299 while (!TAILQ_EMPTY(&p->arp_entries)) {
300 struct app_pipeline_routing_arp_entry *arp_entry;
302 arp_entry = TAILQ_FIRST(&p->arp_entries);
303 TAILQ_REMOVE(&p->arp_entries, arp_entry, node);
311 static struct app_pipeline_routing_route *
312 app_pipeline_routing_find_route(struct pipeline_routing *p,
313 const struct pipeline_routing_route_key *key)
315 struct app_pipeline_routing_route *it, *found;
318 TAILQ_FOREACH(it, &p->routes, node) {
319 if ((key->type == it->key.type) &&
320 (key->key.ipv4.ip == it->key.key.ipv4.ip) &&
321 (key->key.ipv4.depth == it->key.key.ipv4.depth)) {
330 static struct app_pipeline_routing_arp_entry *
331 app_pipeline_routing_find_arp_entry(struct pipeline_routing *p,
332 const struct pipeline_routing_arp_key *key)
334 struct app_pipeline_routing_arp_entry *it, *found;
337 TAILQ_FOREACH(it, &p->arp_entries, node) {
338 if ((key->type == it->key.type) &&
339 (key->key.ipv4.port_id == it->key.key.ipv4.port_id) &&
340 (key->key.ipv4.ip == it->key.key.ipv4.ip)) {
350 print_route(const struct app_pipeline_routing_route *route)
352 if (route->key.type == PIPELINE_ROUTING_ROUTE_IPV4) {
353 const struct pipeline_routing_route_key_ipv4 *key =
354 &route->key.key.ipv4;
356 printf("IP Prefix = %" PRIu32 ".%" PRIu32
357 ".%" PRIu32 ".%" PRIu32 "/%" PRIu32
358 " => (Port = %" PRIu32,
360 (key->ip >> 24) & 0xFF,
361 (key->ip >> 16) & 0xFF,
362 (key->ip >> 8) & 0xFF,
366 route->data.port_id);
368 if (route->data.flags & PIPELINE_ROUTING_ROUTE_LOCAL)
370 else if (route->data.flags & PIPELINE_ROUTING_ROUTE_ARP)
372 ", Next Hop IP = %" PRIu32 ".%" PRIu32
373 ".%" PRIu32 ".%" PRIu32,
375 (route->data.ethernet.ip >> 24) & 0xFF,
376 (route->data.ethernet.ip >> 16) & 0xFF,
377 (route->data.ethernet.ip >> 8) & 0xFF,
378 route->data.ethernet.ip & 0xFF);
381 ", Next Hop HWaddress = %02" PRIx32
382 ":%02" PRIx32 ":%02" PRIx32
383 ":%02" PRIx32 ":%02" PRIx32
386 route->data.ethernet.macaddr.addr_bytes[0],
387 route->data.ethernet.macaddr.addr_bytes[1],
388 route->data.ethernet.macaddr.addr_bytes[2],
389 route->data.ethernet.macaddr.addr_bytes[3],
390 route->data.ethernet.macaddr.addr_bytes[4],
391 route->data.ethernet.macaddr.addr_bytes[5]);
393 if (route->data.flags & PIPELINE_ROUTING_ROUTE_QINQ)
394 printf(", QinQ SVLAN = %" PRIu32 " CVLAN = %" PRIu32,
395 route->data.l2.qinq.svlan,
396 route->data.l2.qinq.cvlan);
398 if (route->data.flags & PIPELINE_ROUTING_ROUTE_MPLS) {
401 printf(", MPLS labels");
402 for (i = 0; i < route->data.l2.mpls.n_labels; i++)
404 route->data.l2.mpls.labels[i]);
412 print_arp_entry(const struct app_pipeline_routing_arp_entry *entry)
414 printf("(Port = %" PRIu32 ", IP = %" PRIu32 ".%" PRIu32
415 ".%" PRIu32 ".%" PRIu32
416 ") => HWaddress = %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32
417 ":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\n",
419 entry->key.key.ipv4.port_id,
420 (entry->key.key.ipv4.ip >> 24) & 0xFF,
421 (entry->key.key.ipv4.ip >> 16) & 0xFF,
422 (entry->key.key.ipv4.ip >> 8) & 0xFF,
423 entry->key.key.ipv4.ip & 0xFF,
425 entry->macaddr.addr_bytes[0],
426 entry->macaddr.addr_bytes[1],
427 entry->macaddr.addr_bytes[2],
428 entry->macaddr.addr_bytes[3],
429 entry->macaddr.addr_bytes[4],
430 entry->macaddr.addr_bytes[5]);
434 app_pipeline_routing_route_ls(struct app_params *app, uint32_t pipeline_id)
436 struct pipeline_routing *p;
437 struct app_pipeline_routing_route *it;
439 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
443 TAILQ_FOREACH(it, &p->routes, node)
446 if (p->default_route_present)
447 printf("Default route: port %" PRIu32 " (entry ptr = %p)\n",
448 p->default_route_port_id,
449 p->default_route_entry_ptr);
451 printf("Default: DROP\n");
457 app_pipeline_routing_add_route(struct app_params *app,
458 uint32_t pipeline_id,
459 struct pipeline_routing_route_key *key,
460 struct pipeline_routing_route_data *data)
462 struct pipeline_routing *p;
464 struct pipeline_routing_route_add_msg_req *req;
465 struct pipeline_routing_route_add_msg_rsp *rsp;
467 struct app_pipeline_routing_route *entry;
471 /* Check input arguments */
477 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
482 case PIPELINE_ROUTING_ROUTE_IPV4:
484 uint32_t depth = key->key.ipv4.depth;
488 if ((depth == 0) || (depth > 32))
491 netmask = (~0U) << (32 - depth);
492 key->key.ipv4.ip &= netmask;
495 if (data->port_id >= p->n_ports_out)
504 /* Find existing rule or allocate new rule */
505 entry = app_pipeline_routing_find_route(p, key);
506 new_entry = (entry == NULL);
508 entry = rte_malloc(NULL, sizeof(*entry), RTE_CACHE_LINE_SIZE);
514 /* Allocate and write request */
515 req = app_msg_alloc(app);
522 req->type = PIPELINE_MSG_REQ_CUSTOM;
523 req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD;
524 memcpy(&req->key, key, sizeof(*key));
525 memcpy(&req->data, data, sizeof(*data));
527 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
534 /* Read response and write entry */
536 (rsp->entry_ptr == NULL) ||
537 ((new_entry == 0) && (rsp->key_found == 0)) ||
538 ((new_entry == 1) && (rsp->key_found == 1))) {
539 app_msg_free(app, rsp);
545 memcpy(&entry->key, key, sizeof(*key));
546 memcpy(&entry->data, data, sizeof(*data));
547 entry->entry_ptr = rsp->entry_ptr;
551 TAILQ_INSERT_TAIL(&p->routes, entry, node);
555 /* Message buffer free */
556 app_msg_free(app, rsp);
561 app_pipeline_routing_delete_route(struct app_params *app,
562 uint32_t pipeline_id,
563 struct pipeline_routing_route_key *key)
565 struct pipeline_routing *p;
567 struct pipeline_routing_route_delete_msg_req *req;
568 struct pipeline_routing_route_delete_msg_rsp *rsp;
570 struct app_pipeline_routing_route *entry;
572 /* Check input arguments */
577 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
582 case PIPELINE_ROUTING_ROUTE_IPV4:
584 uint32_t depth = key->key.ipv4.depth;
588 if ((depth == 0) || (depth > 32))
591 netmask = (~0U) << (32 - depth);
592 key->key.ipv4.ip &= netmask;
601 entry = app_pipeline_routing_find_route(p, key);
605 /* Allocate and write request */
606 req = app_msg_alloc(app);
610 req->type = PIPELINE_MSG_REQ_CUSTOM;
611 req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL;
612 memcpy(&req->key, key, sizeof(*key));
614 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
619 if (rsp->status || !rsp->key_found) {
620 app_msg_free(app, rsp);
625 TAILQ_REMOVE(&p->routes, entry, node);
630 app_msg_free(app, rsp);
636 app_pipeline_routing_add_default_route(struct app_params *app,
637 uint32_t pipeline_id,
640 struct pipeline_routing *p;
642 struct pipeline_routing_route_add_default_msg_req *req;
643 struct pipeline_routing_route_add_default_msg_rsp *rsp;
645 /* Check input arguments */
649 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
653 if (port_id >= p->n_ports_out)
656 /* Allocate and write request */
657 req = app_msg_alloc(app);
661 req->type = PIPELINE_MSG_REQ_CUSTOM;
662 req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD_DEFAULT;
663 req->port_id = port_id;
665 /* Send request and wait for response */
666 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
670 /* Read response and write route */
671 if (rsp->status || (rsp->entry_ptr == NULL)) {
672 app_msg_free(app, rsp);
676 p->default_route_port_id = port_id;
677 p->default_route_entry_ptr = rsp->entry_ptr;
680 p->default_route_present = 1;
683 app_msg_free(app, rsp);
689 app_pipeline_routing_delete_default_route(struct app_params *app,
690 uint32_t pipeline_id)
692 struct pipeline_routing *p;
694 struct pipeline_routing_arp_delete_default_msg_req *req;
695 struct pipeline_routing_arp_delete_default_msg_rsp *rsp;
697 /* Check input arguments */
701 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
705 /* Allocate and write request */
706 req = app_msg_alloc(app);
710 req->type = PIPELINE_MSG_REQ_CUSTOM;
711 req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL_DEFAULT;
713 /* Send request and wait for response */
714 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
718 /* Read response and write route */
720 app_msg_free(app, rsp);
725 p->default_route_present = 0;
728 app_msg_free(app, rsp);
734 app_pipeline_routing_arp_ls(struct app_params *app, uint32_t pipeline_id)
736 struct pipeline_routing *p;
737 struct app_pipeline_routing_arp_entry *it;
739 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
743 TAILQ_FOREACH(it, &p->arp_entries, node)
746 if (p->default_arp_entry_present)
747 printf("Default entry: port %" PRIu32 " (entry ptr = %p)\n",
748 p->default_arp_entry_port_id,
749 p->default_arp_entry_ptr);
751 printf("Default: DROP\n");
757 app_pipeline_routing_add_arp_entry(struct app_params *app, uint32_t pipeline_id,
758 struct pipeline_routing_arp_key *key,
759 struct ether_addr *macaddr)
761 struct pipeline_routing *p;
763 struct pipeline_routing_arp_add_msg_req *req;
764 struct pipeline_routing_arp_add_msg_rsp *rsp;
766 struct app_pipeline_routing_arp_entry *entry;
770 /* Check input arguments */
776 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
781 case PIPELINE_ROUTING_ARP_IPV4:
783 uint32_t port_id = key->key.ipv4.port_id;
786 if (port_id >= p->n_ports_out)
795 /* Find existing entry or allocate new */
796 entry = app_pipeline_routing_find_arp_entry(p, key);
797 new_entry = (entry == NULL);
799 entry = rte_malloc(NULL, sizeof(*entry), RTE_CACHE_LINE_SIZE);
805 /* Message buffer allocation */
806 req = app_msg_alloc(app);
813 req->type = PIPELINE_MSG_REQ_CUSTOM;
814 req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_ADD;
815 memcpy(&req->key, key, sizeof(*key));
816 ether_addr_copy(macaddr, &req->macaddr);
818 /* Send request and wait for response */
819 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
826 /* Read response and write entry */
828 (rsp->entry_ptr == NULL) ||
829 ((new_entry == 0) && (rsp->key_found == 0)) ||
830 ((new_entry == 1) && (rsp->key_found == 1))) {
831 app_msg_free(app, rsp);
837 memcpy(&entry->key, key, sizeof(*key));
838 ether_addr_copy(macaddr, &entry->macaddr);
839 entry->entry_ptr = rsp->entry_ptr;
843 TAILQ_INSERT_TAIL(&p->arp_entries, entry, node);
847 /* Message buffer free */
848 app_msg_free(app, rsp);
853 app_pipeline_routing_delete_arp_entry(struct app_params *app,
854 uint32_t pipeline_id,
855 struct pipeline_routing_arp_key *key)
857 struct pipeline_routing *p;
859 struct pipeline_routing_arp_delete_msg_req *req;
860 struct pipeline_routing_arp_delete_msg_rsp *rsp;
862 struct app_pipeline_routing_arp_entry *entry;
864 /* Check input arguments */
869 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
874 case PIPELINE_ROUTING_ARP_IPV4:
876 uint32_t port_id = key->key.ipv4.port_id;
879 if (port_id >= p->n_ports_out)
889 entry = app_pipeline_routing_find_arp_entry(p, key);
893 /* Allocate and write request */
894 req = app_msg_alloc(app);
898 req->type = PIPELINE_MSG_REQ_CUSTOM;
899 req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_DEL;
900 memcpy(&req->key, key, sizeof(*key));
902 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
907 if (rsp->status || !rsp->key_found) {
908 app_msg_free(app, rsp);
913 TAILQ_REMOVE(&p->arp_entries, entry, node);
918 app_msg_free(app, rsp);
924 app_pipeline_routing_add_default_arp_entry(struct app_params *app,
925 uint32_t pipeline_id,
928 struct pipeline_routing *p;
930 struct pipeline_routing_arp_add_default_msg_req *req;
931 struct pipeline_routing_arp_add_default_msg_rsp *rsp;
933 /* Check input arguments */
937 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
941 if (port_id >= p->n_ports_out)
944 /* Allocate and write request */
945 req = app_msg_alloc(app);
949 req->type = PIPELINE_MSG_REQ_CUSTOM;
950 req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT;
951 req->port_id = port_id;
953 /* Send request and wait for response */
954 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
958 /* Read response and write entry */
959 if (rsp->status || rsp->entry_ptr == NULL) {
960 app_msg_free(app, rsp);
964 p->default_arp_entry_port_id = port_id;
965 p->default_arp_entry_ptr = rsp->entry_ptr;
968 p->default_arp_entry_present = 1;
971 app_msg_free(app, rsp);
977 app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
978 uint32_t pipeline_id)
980 struct pipeline_routing *p;
982 struct pipeline_routing_arp_delete_default_msg_req *req;
983 struct pipeline_routing_arp_delete_default_msg_rsp *rsp;
985 /* Check input arguments */
989 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
993 /* Allocate and write request */
994 req = app_msg_alloc(app);
998 req->type = PIPELINE_MSG_REQ_CUSTOM;
999 req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT;
1001 /* Send request and wait for response */
1002 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
1006 /* Read response and write entry */
1008 app_msg_free(app, rsp);
1013 p->default_arp_entry_present = 0;
1016 app_msg_free(app, rsp);
1022 app_pipeline_routing_set_macaddr(struct app_params *app,
1023 uint32_t pipeline_id)
1025 struct app_pipeline_params *p;
1026 struct pipeline_routing_set_macaddr_msg_req *req;
1027 struct pipeline_routing_set_macaddr_msg_rsp *rsp;
1030 /* Check input arguments */
1034 APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
1038 /* Allocate and write request */
1039 req = app_msg_alloc(app);
1043 req->type = PIPELINE_MSG_REQ_CUSTOM;
1044 req->subtype = PIPELINE_ROUTING_MSG_REQ_SET_MACADDR;
1046 memset(req->macaddr, 0, sizeof(req->macaddr));
1047 for (port_id = 0; port_id < p->n_pktq_out; port_id++) {
1048 struct app_link_params *link;
1050 link = app_pipeline_track_pktq_out_to_link(app,
1054 req->macaddr[port_id] = link->mac_addr;
1057 /* Send request and wait for response */
1058 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
1062 /* Read response and write entry */
1064 app_msg_free(app, rsp);
1069 app_msg_free(app, rsp);
1077 * route add (ARP = ON/OFF, MPLS = ON/OFF, QINQ = ON/OFF):
1078 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr>
1079 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr>
1080 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr> qinq <svlan> <cvlan>
1081 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr> qinq <svlan> <cvlan>
1082 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr> mpls <mpls labels>
1083 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr> mpls <mpls labels>
1085 * route add default:
1086 * p <pipelineid> route add default <portid>
1089 * p <pipelineid> route del <ipaddr> <depth>
1091 * route del default:
1092 * p <pipelineid> route del default
1095 * p <pipelineid> route ls
1098 struct cmd_route_result {
1099 cmdline_fixed_string_t p_string;
1101 cmdline_fixed_string_t route_string;
1102 cmdline_multi_string_t multi_string;
1107 void *parsed_result,
1108 __rte_unused struct cmdline *cl,
1111 struct cmd_route_result *params = parsed_result;
1112 struct app_params *app = data;
1115 uint32_t n_tokens = RTE_DIM(tokens);
1118 status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
1120 printf(CMD_MSG_TOO_MANY_ARGS, "route");
1125 if ((n_tokens >= 2) &&
1126 (strcmp(tokens[0], "add") == 0) &&
1127 strcmp(tokens[1], "default")) {
1128 struct pipeline_routing_route_key key;
1129 struct pipeline_routing_route_data route_data;
1130 struct in_addr ipv4, nh_ipv4;
1131 struct ether_addr mac_addr;
1132 uint32_t depth, port_id, svlan, cvlan, i;
1133 uint32_t mpls_labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
1134 uint32_t n_labels = RTE_DIM(mpls_labels);
1136 memset(&key, 0, sizeof(key));
1137 memset(&route_data, 0, sizeof(route_data));
1140 printf(CMD_MSG_NOT_ENOUGH_ARGS, "route add");
1144 if (parse_ipv4_addr(tokens[1], &ipv4)) {
1145 printf(CMD_MSG_INVALID_ARG, "ipaddr");
1149 if (parser_read_uint32(&depth, tokens[2])) {
1150 printf(CMD_MSG_INVALID_ARG, "depth");
1154 if (strcmp(tokens[3], "port")) {
1155 printf(CMD_MSG_ARG_NOT_FOUND, "port");
1159 if (parser_read_uint32(&port_id, tokens[4])) {
1160 printf(CMD_MSG_INVALID_ARG, "portid");
1164 if (strcmp(tokens[5], "ether")) {
1165 printf(CMD_MSG_ARG_NOT_FOUND, "ether");
1169 if (parse_mac_addr(tokens[6], &mac_addr)) {
1170 if (parse_ipv4_addr(tokens[6], &nh_ipv4)) {
1171 printf(CMD_MSG_INVALID_ARG, "nhmacaddr or nhipaddr");
1175 route_data.flags |= PIPELINE_ROUTING_ROUTE_ARP;
1179 if (strcmp(tokens[7], "mpls") == 0) {
1180 if (n_tokens != 9) {
1181 printf(CMD_MSG_MISMATCH_ARGS, "route add mpls");
1185 if (parse_mpls_labels(tokens[8], mpls_labels, &n_labels)) {
1186 printf(CMD_MSG_INVALID_ARG, "mpls labels");
1190 route_data.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
1191 } else if (strcmp(tokens[7], "qinq") == 0) {
1192 if (n_tokens != 10) {
1193 printf(CMD_MSG_MISMATCH_ARGS, "route add qinq");
1197 if (parser_read_uint32(&svlan, tokens[8])) {
1198 printf(CMD_MSG_INVALID_ARG, "svlan");
1201 if (parser_read_uint32(&cvlan, tokens[9])) {
1202 printf(CMD_MSG_INVALID_ARG, "cvlan");
1206 route_data.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
1208 printf(CMD_MSG_ARG_NOT_FOUND, "mpls or qinq");
1213 switch (route_data.flags) {
1215 route_data.port_id = port_id;
1216 route_data.ethernet.macaddr = mac_addr;
1219 case PIPELINE_ROUTING_ROUTE_ARP:
1220 route_data.port_id = port_id;
1221 route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
1224 case PIPELINE_ROUTING_ROUTE_MPLS:
1225 route_data.port_id = port_id;
1226 route_data.ethernet.macaddr = mac_addr;
1227 for (i = 0; i < n_labels; i++)
1228 route_data.l2.mpls.labels[i] = mpls_labels[i];
1229 route_data.l2.mpls.n_labels = n_labels;
1232 case PIPELINE_ROUTING_ROUTE_MPLS | PIPELINE_ROUTING_ROUTE_ARP:
1233 route_data.port_id = port_id;
1234 route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
1235 for (i = 0; i < n_labels; i++)
1236 route_data.l2.mpls.labels[i] = mpls_labels[i];
1237 route_data.l2.mpls.n_labels = n_labels;
1240 case PIPELINE_ROUTING_ROUTE_QINQ:
1241 route_data.port_id = port_id;
1242 route_data.ethernet.macaddr = mac_addr;
1243 route_data.l2.qinq.svlan = svlan;
1244 route_data.l2.qinq.cvlan = cvlan;
1247 case PIPELINE_ROUTING_ROUTE_QINQ | PIPELINE_ROUTING_ROUTE_ARP:
1249 route_data.port_id = port_id;
1250 route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
1251 route_data.l2.qinq.svlan = svlan;
1252 route_data.l2.qinq.cvlan = cvlan;
1256 key.type = PIPELINE_ROUTING_ROUTE_IPV4;
1257 key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
1258 key.key.ipv4.depth = depth;
1260 status = app_pipeline_routing_add_route(app,
1265 printf(CMD_MSG_FAIL, "route add");
1270 /* route add default */
1271 if ((n_tokens >= 2) &&
1272 (strcmp(tokens[0], "add") == 0) &&
1273 (strcmp(tokens[1], "default") == 0)) {
1276 if (n_tokens != 3) {
1277 printf(CMD_MSG_MISMATCH_ARGS, "route add default");
1281 if (parser_read_uint32(&port_id, tokens[2])) {
1282 printf(CMD_MSG_INVALID_ARG, "portid");
1286 status = app_pipeline_routing_add_default_route(app,
1290 printf(CMD_MSG_FAIL, "route add default");
1293 } /* route add default */
1296 if ((n_tokens >= 2) &&
1297 (strcmp(tokens[0], "del") == 0) &&
1298 strcmp(tokens[1], "default")) {
1299 struct pipeline_routing_route_key key;
1300 struct in_addr ipv4;
1303 memset(&key, 0, sizeof(key));
1305 if (n_tokens != 3) {
1306 printf(CMD_MSG_MISMATCH_ARGS, "route del");
1310 if (parse_ipv4_addr(tokens[1], &ipv4)) {
1311 printf(CMD_MSG_INVALID_ARG, "ipaddr");
1315 if (parser_read_uint32(&depth, tokens[2])) {
1316 printf(CMD_MSG_INVALID_ARG, "depth");
1320 key.type = PIPELINE_ROUTING_ROUTE_IPV4;
1321 key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
1322 key.key.ipv4.depth = depth;
1324 status = app_pipeline_routing_delete_route(app, params->p, &key);
1326 printf(CMD_MSG_FAIL, "route del");
1331 /* route del default */
1332 if ((n_tokens >= 2) &&
1333 (strcmp(tokens[0], "del") == 0) &&
1334 (strcmp(tokens[1], "default") == 0)) {
1335 if (n_tokens != 2) {
1336 printf(CMD_MSG_MISMATCH_ARGS, "route del default");
1340 status = app_pipeline_routing_delete_default_route(app,
1343 printf(CMD_MSG_FAIL, "route del default");
1346 } /* route del default */
1349 if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
1350 if (n_tokens != 1) {
1351 printf(CMD_MSG_MISMATCH_ARGS, "route ls");
1355 status = app_pipeline_routing_route_ls(app, params->p);
1357 printf(CMD_MSG_FAIL, "route ls");
1362 printf(CMD_MSG_MISMATCH_ARGS, "route");
1365 static cmdline_parse_token_string_t cmd_route_p_string =
1366 TOKEN_STRING_INITIALIZER(struct cmd_route_result, p_string, "p");
1368 static cmdline_parse_token_num_t cmd_route_p =
1369 TOKEN_NUM_INITIALIZER(struct cmd_route_result, p, UINT32);
1371 static cmdline_parse_token_string_t cmd_route_route_string =
1372 TOKEN_STRING_INITIALIZER(struct cmd_route_result, route_string, "route");
1374 static cmdline_parse_token_string_t cmd_route_multi_string =
1375 TOKEN_STRING_INITIALIZER(struct cmd_route_result, multi_string,
1376 TOKEN_STRING_MULTI);
1378 static cmdline_parse_inst_t cmd_route = {
1379 .f = cmd_route_parsed,
1381 .help_str = "route add / add default / del / del default / ls",
1383 (void *)&cmd_route_p_string,
1384 (void *)&cmd_route_p,
1385 (void *)&cmd_route_route_string,
1386 (void *)&cmd_route_multi_string,
1395 * p <pipelineid> arp add <portid> <ipaddr> <macaddr>
1398 * p <pipelineid> arp add default <portid>
1401 * p <pipelineid> arp del <portid> <ipaddr>
1404 * p <pipelineid> arp del default
1407 * p <pipelineid> arp ls
1410 struct cmd_arp_result {
1411 cmdline_fixed_string_t p_string;
1413 cmdline_fixed_string_t arp_string;
1414 cmdline_multi_string_t multi_string;
1419 void *parsed_result,
1420 __rte_unused struct cmdline *cl,
1423 struct cmd_arp_result *params = parsed_result;
1424 struct app_params *app = data;
1427 uint32_t n_tokens = RTE_DIM(tokens);
1430 status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
1432 printf(CMD_MSG_TOO_MANY_ARGS, "arp");
1437 if ((n_tokens >= 2) &&
1438 (strcmp(tokens[0], "add") == 0) &&
1439 strcmp(tokens[1], "default")) {
1440 struct pipeline_routing_arp_key key;
1441 struct in_addr ipv4;
1442 struct ether_addr mac_addr;
1445 memset(&key, 0, sizeof(key));
1447 if (n_tokens != 4) {
1448 printf(CMD_MSG_MISMATCH_ARGS, "arp add");
1452 if (parser_read_uint32(&port_id, tokens[1])) {
1453 printf(CMD_MSG_INVALID_ARG, "portid");
1457 if (parse_ipv4_addr(tokens[2], &ipv4)) {
1458 printf(CMD_MSG_INVALID_ARG, "ipaddr");
1462 if (parse_mac_addr(tokens[3], &mac_addr)) {
1463 printf(CMD_MSG_INVALID_ARG, "macaddr");
1467 key.type = PIPELINE_ROUTING_ARP_IPV4;
1468 key.key.ipv4.port_id = port_id;
1469 key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
1471 status = app_pipeline_routing_add_arp_entry(app,
1476 printf(CMD_MSG_FAIL, "arp add");
1481 /* arp add default */
1482 if ((n_tokens >= 2) &&
1483 (strcmp(tokens[0], "add") == 0) &&
1484 (strcmp(tokens[1], "default") == 0)) {
1487 if (n_tokens != 3) {
1488 printf(CMD_MSG_MISMATCH_ARGS, "arp add default");
1492 if (parser_read_uint32(&port_id, tokens[2])) {
1493 printf(CMD_MSG_INVALID_ARG, "portid");
1497 status = app_pipeline_routing_add_default_arp_entry(app,
1501 printf(CMD_MSG_FAIL, "arp add default");
1504 } /* arp add default */
1507 if ((n_tokens >= 2) &&
1508 (strcmp(tokens[0], "del") == 0) &&
1509 strcmp(tokens[1], "default")) {
1510 struct pipeline_routing_arp_key key;
1511 struct in_addr ipv4;
1514 memset(&key, 0, sizeof(key));
1516 if (n_tokens != 3) {
1517 printf(CMD_MSG_MISMATCH_ARGS, "arp del");
1521 if (parser_read_uint32(&port_id, tokens[1])) {
1522 printf(CMD_MSG_INVALID_ARG, "portid");
1526 if (parse_ipv4_addr(tokens[2], &ipv4)) {
1527 printf(CMD_MSG_INVALID_ARG, "ipaddr");
1531 key.type = PIPELINE_ROUTING_ARP_IPV4;
1532 key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
1533 key.key.ipv4.port_id = port_id;
1535 status = app_pipeline_routing_delete_arp_entry(app,
1539 printf(CMD_MSG_FAIL, "arp del");
1544 /* arp del default */
1545 if ((n_tokens >= 2) &&
1546 (strcmp(tokens[0], "del") == 0) &&
1547 (strcmp(tokens[1], "default") == 0)) {
1548 if (n_tokens != 2) {
1549 printf(CMD_MSG_MISMATCH_ARGS, "arp del default");
1553 status = app_pipeline_routing_delete_default_arp_entry(app,
1556 printf(CMD_MSG_FAIL, "arp del default");
1559 } /* arp del default */
1562 if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
1563 if (n_tokens != 1) {
1564 printf(CMD_MSG_MISMATCH_ARGS, "arp ls");
1568 status = app_pipeline_routing_arp_ls(app, params->p);
1570 printf(CMD_MSG_FAIL, "arp ls");
1575 printf(CMD_MSG_FAIL, "arp");
1578 static cmdline_parse_token_string_t cmd_arp_p_string =
1579 TOKEN_STRING_INITIALIZER(struct cmd_arp_result, p_string, "p");
1581 static cmdline_parse_token_num_t cmd_arp_p =
1582 TOKEN_NUM_INITIALIZER(struct cmd_arp_result, p, UINT32);
1584 static cmdline_parse_token_string_t cmd_arp_arp_string =
1585 TOKEN_STRING_INITIALIZER(struct cmd_arp_result, arp_string, "arp");
1587 static cmdline_parse_token_string_t cmd_arp_multi_string =
1588 TOKEN_STRING_INITIALIZER(struct cmd_arp_result, multi_string,
1589 TOKEN_STRING_MULTI);
1591 static cmdline_parse_inst_t cmd_arp = {
1592 .f = cmd_arp_parsed,
1594 .help_str = "arp add / add default / del / del default / ls",
1596 (void *)&cmd_arp_p_string,
1598 (void *)&cmd_arp_arp_string,
1599 (void *)&cmd_arp_multi_string,
1604 static cmdline_parse_ctx_t pipeline_cmds[] = {
1605 (cmdline_parse_inst_t *)&cmd_route,
1606 (cmdline_parse_inst_t *)&cmd_arp,
1610 static struct pipeline_fe_ops pipeline_routing_fe_ops = {
1611 .f_init = app_pipeline_routing_init,
1612 .f_post_init = app_pipeline_routing_post_init,
1613 .f_free = app_pipeline_routing_free,
1614 .f_track = app_pipeline_track_default,
1615 .cmds = pipeline_cmds,
1618 struct pipeline_type pipeline_routing = {
1620 .be_ops = &pipeline_routing_be_ops,
1621 .fe_ops = &pipeline_routing_fe_ops,