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 {
65 TAILQ_HEAD(, app_pipeline_routing_route) routes;
68 uint32_t default_route_present;
69 uint32_t default_route_port_id;
70 void *default_route_entry_ptr;
73 TAILQ_HEAD(, app_pipeline_routing_arp_entry) arp_entries;
74 uint32_t n_arp_entries;
76 uint32_t default_arp_entry_present;
77 uint32_t default_arp_entry_port_id;
78 void *default_arp_entry_ptr;
82 pipeline_routing_init(struct pipeline_params *params,
83 __rte_unused void *arg)
85 struct pipeline_routing *p;
88 /* Check input arguments */
89 if ((params == NULL) ||
90 (params->n_ports_in == 0) ||
91 (params->n_ports_out == 0))
94 /* Memory allocation */
95 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_routing));
96 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
101 p->n_ports_in = params->n_ports_in;
102 p->n_ports_out = params->n_ports_out;
104 TAILQ_INIT(&p->routes);
107 TAILQ_INIT(&p->arp_entries);
108 p->n_arp_entries = 0;
114 app_pipeline_routing_free(void *pipeline)
116 struct pipeline_routing *p = pipeline;
118 /* Check input arguments */
123 while (!TAILQ_EMPTY(&p->routes)) {
124 struct app_pipeline_routing_route *route;
126 route = TAILQ_FIRST(&p->routes);
127 TAILQ_REMOVE(&p->routes, route, node);
131 while (!TAILQ_EMPTY(&p->arp_entries)) {
132 struct app_pipeline_routing_arp_entry *arp_entry;
134 arp_entry = TAILQ_FIRST(&p->arp_entries);
135 TAILQ_REMOVE(&p->arp_entries, arp_entry, node);
143 static struct app_pipeline_routing_route *
144 app_pipeline_routing_find_route(struct pipeline_routing *p,
145 const struct pipeline_routing_route_key *key)
147 struct app_pipeline_routing_route *it, *found;
150 TAILQ_FOREACH(it, &p->routes, node) {
151 if ((key->type == it->key.type) &&
152 (key->key.ipv4.ip == it->key.key.ipv4.ip) &&
153 (key->key.ipv4.depth == it->key.key.ipv4.depth)) {
162 static struct app_pipeline_routing_arp_entry *
163 app_pipeline_routing_find_arp_entry(struct pipeline_routing *p,
164 const struct pipeline_routing_arp_key *key)
166 struct app_pipeline_routing_arp_entry *it, *found;
169 TAILQ_FOREACH(it, &p->arp_entries, node) {
170 if ((key->type == it->key.type) &&
171 (key->key.ipv4.port_id == it->key.key.ipv4.port_id) &&
172 (key->key.ipv4.ip == it->key.key.ipv4.ip)) {
182 print_route(const struct app_pipeline_routing_route *route)
184 if (route->key.type == PIPELINE_ROUTING_ROUTE_IPV4) {
185 const struct pipeline_routing_route_key_ipv4 *key =
186 &route->key.key.ipv4;
188 printf("IP Prefix = %" PRIu32 ".%" PRIu32
189 ".%" PRIu32 ".%" PRIu32 "/%" PRIu32
190 " => (Port = %" PRIu32,
192 (key->ip >> 24) & 0xFF,
193 (key->ip >> 16) & 0xFF,
194 (key->ip >> 8) & 0xFF,
198 route->data.port_id);
200 if (route->data.flags & PIPELINE_ROUTING_ROUTE_ARP)
202 ", Next Hop IP = %" PRIu32 ".%" PRIu32
203 ".%" PRIu32 ".%" PRIu32,
205 (route->data.ethernet.ip >> 24) & 0xFF,
206 (route->data.ethernet.ip >> 16) & 0xFF,
207 (route->data.ethernet.ip >> 8) & 0xFF,
208 route->data.ethernet.ip & 0xFF);
211 ", Next Hop HWaddress = %02" PRIx32
212 ":%02" PRIx32 ":%02" PRIx32
213 ":%02" PRIx32 ":%02" PRIx32
216 route->data.ethernet.macaddr.addr_bytes[0],
217 route->data.ethernet.macaddr.addr_bytes[1],
218 route->data.ethernet.macaddr.addr_bytes[2],
219 route->data.ethernet.macaddr.addr_bytes[3],
220 route->data.ethernet.macaddr.addr_bytes[4],
221 route->data.ethernet.macaddr.addr_bytes[5]);
223 if (route->data.flags & PIPELINE_ROUTING_ROUTE_QINQ)
224 printf(", QinQ SVLAN = %" PRIu32 " CVLAN = %" PRIu32,
225 route->data.l2.qinq.svlan,
226 route->data.l2.qinq.cvlan);
228 if (route->data.flags & PIPELINE_ROUTING_ROUTE_MPLS) {
231 printf(", MPLS labels");
232 for (i = 0; i < route->data.l2.mpls.n_labels; i++)
234 route->data.l2.mpls.labels[i]);
242 print_arp_entry(const struct app_pipeline_routing_arp_entry *entry)
244 printf("(Port = %" PRIu32 ", IP = %" PRIu32 ".%" PRIu32
245 ".%" PRIu32 ".%" PRIu32
246 ") => HWaddress = %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32
247 ":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\n",
249 entry->key.key.ipv4.port_id,
250 (entry->key.key.ipv4.ip >> 24) & 0xFF,
251 (entry->key.key.ipv4.ip >> 16) & 0xFF,
252 (entry->key.key.ipv4.ip >> 8) & 0xFF,
253 entry->key.key.ipv4.ip & 0xFF,
255 entry->macaddr.addr_bytes[0],
256 entry->macaddr.addr_bytes[1],
257 entry->macaddr.addr_bytes[2],
258 entry->macaddr.addr_bytes[3],
259 entry->macaddr.addr_bytes[4],
260 entry->macaddr.addr_bytes[5]);
264 app_pipeline_routing_route_ls(struct app_params *app, uint32_t pipeline_id)
266 struct pipeline_routing *p;
267 struct app_pipeline_routing_route *it;
269 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
273 TAILQ_FOREACH(it, &p->routes, node)
276 if (p->default_route_present)
277 printf("Default route: port %" PRIu32 " (entry ptr = %p)\n",
278 p->default_route_port_id,
279 p->default_route_entry_ptr);
281 printf("Default: DROP\n");
287 app_pipeline_routing_add_route(struct app_params *app,
288 uint32_t pipeline_id,
289 struct pipeline_routing_route_key *key,
290 struct pipeline_routing_route_data *data)
292 struct pipeline_routing *p;
294 struct pipeline_routing_route_add_msg_req *req;
295 struct pipeline_routing_route_add_msg_rsp *rsp;
297 struct app_pipeline_routing_route *entry;
301 /* Check input arguments */
307 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
312 case PIPELINE_ROUTING_ROUTE_IPV4:
314 uint32_t depth = key->key.ipv4.depth;
318 if ((depth == 0) || (depth > 32))
321 netmask = (~0U) << (32 - depth);
322 key->key.ipv4.ip &= netmask;
325 if (data->port_id >= p->n_ports_out)
334 /* Find existing rule or allocate new rule */
335 entry = app_pipeline_routing_find_route(p, key);
336 new_entry = (entry == NULL);
338 entry = rte_malloc(NULL, sizeof(*entry), RTE_CACHE_LINE_SIZE);
344 /* Allocate and write request */
345 req = app_msg_alloc(app);
352 req->type = PIPELINE_MSG_REQ_CUSTOM;
353 req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD;
354 memcpy(&req->key, key, sizeof(*key));
355 memcpy(&req->data, data, sizeof(*data));
357 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
364 /* Read response and write entry */
366 (rsp->entry_ptr == NULL) ||
367 ((new_entry == 0) && (rsp->key_found == 0)) ||
368 ((new_entry == 1) && (rsp->key_found == 1))) {
369 app_msg_free(app, rsp);
375 memcpy(&entry->key, key, sizeof(*key));
376 memcpy(&entry->data, data, sizeof(*data));
377 entry->entry_ptr = rsp->entry_ptr;
381 TAILQ_INSERT_TAIL(&p->routes, entry, node);
387 /* Message buffer free */
388 app_msg_free(app, rsp);
393 app_pipeline_routing_delete_route(struct app_params *app,
394 uint32_t pipeline_id,
395 struct pipeline_routing_route_key *key)
397 struct pipeline_routing *p;
399 struct pipeline_routing_route_delete_msg_req *req;
400 struct pipeline_routing_route_delete_msg_rsp *rsp;
402 struct app_pipeline_routing_route *entry;
404 /* Check input arguments */
409 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
414 case PIPELINE_ROUTING_ROUTE_IPV4:
416 uint32_t depth = key->key.ipv4.depth;
420 if ((depth == 0) || (depth > 32))
423 netmask = (~0U) << (32 - depth);
424 key->key.ipv4.ip &= netmask;
433 entry = app_pipeline_routing_find_route(p, key);
437 /* Allocate and write request */
438 req = app_msg_alloc(app);
442 req->type = PIPELINE_MSG_REQ_CUSTOM;
443 req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL;
444 memcpy(&req->key, key, sizeof(*key));
446 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
451 if (rsp->status || !rsp->key_found) {
452 app_msg_free(app, rsp);
457 TAILQ_REMOVE(&p->routes, entry, node);
462 app_msg_free(app, rsp);
468 app_pipeline_routing_add_default_route(struct app_params *app,
469 uint32_t pipeline_id,
472 struct pipeline_routing *p;
474 struct pipeline_routing_route_add_default_msg_req *req;
475 struct pipeline_routing_route_add_default_msg_rsp *rsp;
477 /* Check input arguments */
481 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
485 if (port_id >= p->n_ports_out)
488 /* Allocate and write request */
489 req = app_msg_alloc(app);
493 req->type = PIPELINE_MSG_REQ_CUSTOM;
494 req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD_DEFAULT;
495 req->port_id = port_id;
497 /* Send request and wait for response */
498 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
502 /* Read response and write route */
503 if (rsp->status || (rsp->entry_ptr == NULL)) {
504 app_msg_free(app, rsp);
508 p->default_route_port_id = port_id;
509 p->default_route_entry_ptr = rsp->entry_ptr;
512 p->default_route_present = 1;
515 app_msg_free(app, rsp);
521 app_pipeline_routing_delete_default_route(struct app_params *app,
522 uint32_t pipeline_id)
524 struct pipeline_routing *p;
526 struct pipeline_routing_arp_delete_default_msg_req *req;
527 struct pipeline_routing_arp_delete_default_msg_rsp *rsp;
529 /* Check input arguments */
533 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
537 /* Allocate and write request */
538 req = app_msg_alloc(app);
542 req->type = PIPELINE_MSG_REQ_CUSTOM;
543 req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL_DEFAULT;
545 /* Send request and wait for response */
546 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
550 /* Read response and write route */
552 app_msg_free(app, rsp);
557 p->default_route_present = 0;
560 app_msg_free(app, rsp);
566 app_pipeline_routing_arp_ls(struct app_params *app, uint32_t pipeline_id)
568 struct pipeline_routing *p;
569 struct app_pipeline_routing_arp_entry *it;
571 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
575 TAILQ_FOREACH(it, &p->arp_entries, node)
578 if (p->default_arp_entry_present)
579 printf("Default entry: port %" PRIu32 " (entry ptr = %p)\n",
580 p->default_arp_entry_port_id,
581 p->default_arp_entry_ptr);
583 printf("Default: DROP\n");
589 app_pipeline_routing_add_arp_entry(struct app_params *app, uint32_t pipeline_id,
590 struct pipeline_routing_arp_key *key,
591 struct ether_addr *macaddr)
593 struct pipeline_routing *p;
595 struct pipeline_routing_arp_add_msg_req *req;
596 struct pipeline_routing_arp_add_msg_rsp *rsp;
598 struct app_pipeline_routing_arp_entry *entry;
602 /* Check input arguments */
608 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
613 case PIPELINE_ROUTING_ARP_IPV4:
615 uint32_t port_id = key->key.ipv4.port_id;
618 if (port_id >= p->n_ports_out)
627 /* Find existing entry or allocate new */
628 entry = app_pipeline_routing_find_arp_entry(p, key);
629 new_entry = (entry == NULL);
631 entry = rte_malloc(NULL, sizeof(*entry), RTE_CACHE_LINE_SIZE);
637 /* Message buffer allocation */
638 req = app_msg_alloc(app);
645 req->type = PIPELINE_MSG_REQ_CUSTOM;
646 req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_ADD;
647 memcpy(&req->key, key, sizeof(*key));
648 ether_addr_copy(macaddr, &req->macaddr);
650 /* Send request and wait for response */
651 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
658 /* Read response and write entry */
660 (rsp->entry_ptr == NULL) ||
661 ((new_entry == 0) && (rsp->key_found == 0)) ||
662 ((new_entry == 1) && (rsp->key_found == 1))) {
663 app_msg_free(app, rsp);
669 memcpy(&entry->key, key, sizeof(*key));
670 ether_addr_copy(macaddr, &entry->macaddr);
671 entry->entry_ptr = rsp->entry_ptr;
675 TAILQ_INSERT_TAIL(&p->arp_entries, entry, node);
679 print_arp_entry(entry);
681 /* Message buffer free */
682 app_msg_free(app, rsp);
687 app_pipeline_routing_delete_arp_entry(struct app_params *app,
688 uint32_t pipeline_id,
689 struct pipeline_routing_arp_key *key)
691 struct pipeline_routing *p;
693 struct pipeline_routing_arp_delete_msg_req *req;
694 struct pipeline_routing_arp_delete_msg_rsp *rsp;
696 struct app_pipeline_routing_arp_entry *entry;
698 /* Check input arguments */
703 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
708 case PIPELINE_ROUTING_ARP_IPV4:
710 uint32_t port_id = key->key.ipv4.port_id;
713 if (port_id >= p->n_ports_out)
723 entry = app_pipeline_routing_find_arp_entry(p, key);
727 /* Allocate and write request */
728 req = app_msg_alloc(app);
732 req->type = PIPELINE_MSG_REQ_CUSTOM;
733 req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_DEL;
734 memcpy(&req->key, key, sizeof(*key));
736 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
741 if (rsp->status || !rsp->key_found) {
742 app_msg_free(app, rsp);
747 TAILQ_REMOVE(&p->arp_entries, entry, node);
752 app_msg_free(app, rsp);
758 app_pipeline_routing_add_default_arp_entry(struct app_params *app,
759 uint32_t pipeline_id,
762 struct pipeline_routing *p;
764 struct pipeline_routing_arp_add_default_msg_req *req;
765 struct pipeline_routing_arp_add_default_msg_rsp *rsp;
767 /* Check input arguments */
771 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
775 if (port_id >= p->n_ports_out)
778 /* Allocate and write request */
779 req = app_msg_alloc(app);
783 req->type = PIPELINE_MSG_REQ_CUSTOM;
784 req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT;
785 req->port_id = port_id;
787 /* Send request and wait for response */
788 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
792 /* Read response and write entry */
793 if (rsp->status || rsp->entry_ptr == NULL) {
794 app_msg_free(app, rsp);
798 p->default_arp_entry_port_id = port_id;
799 p->default_arp_entry_ptr = rsp->entry_ptr;
802 p->default_arp_entry_present = 1;
805 app_msg_free(app, rsp);
811 app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
812 uint32_t pipeline_id)
814 struct pipeline_routing *p;
816 struct pipeline_routing_arp_delete_default_msg_req *req;
817 struct pipeline_routing_arp_delete_default_msg_rsp *rsp;
819 /* Check input arguments */
823 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
827 /* Allocate and write request */
828 req = app_msg_alloc(app);
832 req->type = PIPELINE_MSG_REQ_CUSTOM;
833 req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT;
835 /* Send request and wait for response */
836 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
840 /* Read response and write entry */
842 app_msg_free(app, rsp);
847 p->default_arp_entry_present = 0;
850 app_msg_free(app, rsp);
858 * route add (ARP = ON/OFF, MPLS = ON/OFF, QINQ = ON/OFF):
859 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr>
860 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr>
861 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr> qinq <svlan> <cvlan>
862 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr> qinq <svlan> <cvlan>
863 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr> mpls <mpls labels>
864 * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr> mpls <mpls labels>
867 * p <pipelineid> route add default <portid>
870 * p <pipelineid> route del <ipaddr> <depth>
873 * p <pipelineid> route del default
876 * p <pipelineid> route ls
879 struct cmd_route_result {
880 cmdline_fixed_string_t p_string;
882 cmdline_fixed_string_t route_string;
883 cmdline_multi_string_t multi_string;
889 __rte_unused struct cmdline *cl,
892 struct cmd_route_result *params = parsed_result;
893 struct app_params *app = data;
896 uint32_t n_tokens = RTE_DIM(tokens);
899 status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
901 printf(CMD_MSG_TOO_MANY_ARGS, "route");
906 if ((n_tokens >= 2) &&
907 (strcmp(tokens[0], "add") == 0) &&
908 strcmp(tokens[1], "default")) {
909 struct pipeline_routing_route_key key;
910 struct pipeline_routing_route_data route_data;
911 struct in_addr ipv4, nh_ipv4;
912 struct ether_addr mac_addr;
913 uint32_t depth, port_id, svlan, cvlan, i;
914 uint32_t mpls_labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
915 uint32_t n_labels = RTE_DIM(mpls_labels);
917 memset(&key, 0, sizeof(key));
918 memset(&route_data, 0, sizeof(route_data));
921 printf(CMD_MSG_NOT_ENOUGH_ARGS, "route add");
925 if (parse_ipv4_addr(tokens[1], &ipv4)) {
926 printf(CMD_MSG_INVALID_ARG, "ipaddr");
930 if (parser_read_uint32(&depth, tokens[2])) {
931 printf(CMD_MSG_INVALID_ARG, "depth");
935 if (strcmp(tokens[3], "port")) {
936 printf(CMD_MSG_ARG_NOT_FOUND, "port");
940 if (parser_read_uint32(&port_id, tokens[4])) {
941 printf(CMD_MSG_INVALID_ARG, "portid");
945 if (strcmp(tokens[5], "ether")) {
946 printf(CMD_MSG_ARG_NOT_FOUND, "ether");
950 if (parse_mac_addr(tokens[6], &mac_addr)) {
951 if (parse_ipv4_addr(tokens[6], &nh_ipv4)) {
952 printf(CMD_MSG_INVALID_ARG, "nhmacaddr or nhipaddr");
956 route_data.flags |= PIPELINE_ROUTING_ROUTE_ARP;
960 if (strcmp(tokens[7], "mpls") == 0) {
962 printf(CMD_MSG_MISMATCH_ARGS, "route add mpls");
966 if (parse_mpls_labels(tokens[8], mpls_labels, &n_labels)) {
967 printf(CMD_MSG_INVALID_ARG, "mpls labels");
971 route_data.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
972 } else if (strcmp(tokens[7], "qinq") == 0) {
973 if (n_tokens != 10) {
974 printf(CMD_MSG_MISMATCH_ARGS, "route add qinq");
978 if (parser_read_uint32(&svlan, tokens[8])) {
979 printf(CMD_MSG_INVALID_ARG, "svlan");
982 if (parser_read_uint32(&cvlan, tokens[9])) {
983 printf(CMD_MSG_INVALID_ARG, "cvlan");
987 route_data.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
989 printf(CMD_MSG_ARG_NOT_FOUND, "mpls or qinq");
994 switch (route_data.flags) {
996 route_data.port_id = port_id;
997 route_data.ethernet.macaddr = mac_addr;
1000 case PIPELINE_ROUTING_ROUTE_ARP:
1001 route_data.port_id = port_id;
1002 route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
1005 case PIPELINE_ROUTING_ROUTE_MPLS:
1006 route_data.port_id = port_id;
1007 route_data.ethernet.macaddr = mac_addr;
1008 for (i = 0; i < n_labels; i++)
1009 route_data.l2.mpls.labels[i] = mpls_labels[i];
1010 route_data.l2.mpls.n_labels = n_labels;
1013 case PIPELINE_ROUTING_ROUTE_MPLS | PIPELINE_ROUTING_ROUTE_ARP:
1014 route_data.port_id = port_id;
1015 route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
1016 for (i = 0; i < n_labels; i++)
1017 route_data.l2.mpls.labels[i] = mpls_labels[i];
1018 route_data.l2.mpls.n_labels = n_labels;
1021 case PIPELINE_ROUTING_ROUTE_QINQ:
1022 route_data.port_id = port_id;
1023 route_data.ethernet.macaddr = mac_addr;
1024 route_data.l2.qinq.svlan = svlan;
1025 route_data.l2.qinq.cvlan = cvlan;
1028 case PIPELINE_ROUTING_ROUTE_QINQ | PIPELINE_ROUTING_ROUTE_ARP:
1030 route_data.port_id = port_id;
1031 route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
1032 route_data.l2.qinq.svlan = svlan;
1033 route_data.l2.qinq.cvlan = cvlan;
1037 key.type = PIPELINE_ROUTING_ROUTE_IPV4;
1038 key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
1039 key.key.ipv4.depth = depth;
1041 status = app_pipeline_routing_add_route(app,
1046 printf(CMD_MSG_FAIL, "route add");
1051 /* route add default */
1052 if ((n_tokens >= 2) &&
1053 (strcmp(tokens[0], "add") == 0) &&
1054 (strcmp(tokens[1], "default") == 0)) {
1057 if (n_tokens != 3) {
1058 printf(CMD_MSG_MISMATCH_ARGS, "route add default");
1062 if (parser_read_uint32(&port_id, tokens[2])) {
1063 printf(CMD_MSG_INVALID_ARG, "portid");
1067 status = app_pipeline_routing_add_default_route(app,
1071 printf(CMD_MSG_FAIL, "route add default");
1074 } /* route add default */
1077 if ((n_tokens >= 2) &&
1078 (strcmp(tokens[0], "del") == 0) &&
1079 strcmp(tokens[1], "default")) {
1080 struct pipeline_routing_route_key key;
1081 struct in_addr ipv4;
1084 memset(&key, 0, sizeof(key));
1086 if (n_tokens != 3) {
1087 printf(CMD_MSG_MISMATCH_ARGS, "route del");
1091 if (parse_ipv4_addr(tokens[1], &ipv4)) {
1092 printf(CMD_MSG_INVALID_ARG, "ipaddr");
1096 if (parser_read_uint32(&depth, tokens[2])) {
1097 printf(CMD_MSG_INVALID_ARG, "depth");
1101 key.type = PIPELINE_ROUTING_ROUTE_IPV4;
1102 key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
1103 key.key.ipv4.depth = depth;
1105 status = app_pipeline_routing_delete_route(app, params->p, &key);
1107 printf(CMD_MSG_FAIL, "route del");
1112 /* route del default */
1113 if ((n_tokens >= 2) &&
1114 (strcmp(tokens[0], "del") == 0) &&
1115 (strcmp(tokens[1], "default") == 0)) {
1116 if (n_tokens != 2) {
1117 printf(CMD_MSG_MISMATCH_ARGS, "route del default");
1121 status = app_pipeline_routing_delete_default_route(app,
1124 printf(CMD_MSG_FAIL, "route del default");
1127 } /* route del default */
1130 if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
1131 if (n_tokens != 1) {
1132 printf(CMD_MSG_MISMATCH_ARGS, "route ls");
1136 status = app_pipeline_routing_route_ls(app, params->p);
1138 printf(CMD_MSG_FAIL, "route ls");
1143 printf(CMD_MSG_MISMATCH_ARGS, "route");
1146 static cmdline_parse_token_string_t cmd_route_p_string =
1147 TOKEN_STRING_INITIALIZER(struct cmd_route_result, p_string, "p");
1149 static cmdline_parse_token_num_t cmd_route_p =
1150 TOKEN_NUM_INITIALIZER(struct cmd_route_result, p, UINT32);
1152 static cmdline_parse_token_string_t cmd_route_route_string =
1153 TOKEN_STRING_INITIALIZER(struct cmd_route_result, route_string, "route");
1155 static cmdline_parse_token_string_t cmd_route_multi_string =
1156 TOKEN_STRING_INITIALIZER(struct cmd_route_result, multi_string,
1157 TOKEN_STRING_MULTI);
1159 static cmdline_parse_inst_t cmd_route = {
1160 .f = cmd_route_parsed,
1162 .help_str = "route add / add default / del / del default / ls",
1164 (void *)&cmd_route_p_string,
1165 (void *)&cmd_route_p,
1166 (void *)&cmd_route_route_string,
1167 (void *)&cmd_route_multi_string,
1176 * p <pipelineid> arp add <portid> <ipaddr> <macaddr>
1179 * p <pipelineid> arp add default <portid>
1182 * p <pipelineid> arp del <portid> <ipaddr>
1185 * p <pipelineid> arp del default
1188 * p <pipelineid> arp ls
1191 struct cmd_arp_result {
1192 cmdline_fixed_string_t p_string;
1194 cmdline_fixed_string_t arp_string;
1195 cmdline_multi_string_t multi_string;
1200 void *parsed_result,
1201 __rte_unused struct cmdline *cl,
1204 struct cmd_arp_result *params = parsed_result;
1205 struct app_params *app = data;
1208 uint32_t n_tokens = RTE_DIM(tokens);
1211 status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
1213 printf(CMD_MSG_TOO_MANY_ARGS, "arp");
1218 if ((n_tokens >= 2) &&
1219 (strcmp(tokens[0], "add") == 0) &&
1220 strcmp(tokens[1], "default")) {
1221 struct pipeline_routing_arp_key key;
1222 struct in_addr ipv4;
1223 struct ether_addr mac_addr;
1226 memset(&key, 0, sizeof(key));
1228 if (n_tokens != 4) {
1229 printf(CMD_MSG_MISMATCH_ARGS, "arp add");
1233 if (parser_read_uint32(&port_id, tokens[1])) {
1234 printf(CMD_MSG_INVALID_ARG, "portid");
1238 if (parse_ipv4_addr(tokens[2], &ipv4)) {
1239 printf(CMD_MSG_INVALID_ARG, "ipaddr");
1243 if (parse_mac_addr(tokens[3], &mac_addr)) {
1244 printf(CMD_MSG_INVALID_ARG, "macaddr");
1248 key.type = PIPELINE_ROUTING_ARP_IPV4;
1249 key.key.ipv4.port_id = port_id;
1250 key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
1252 status = app_pipeline_routing_add_arp_entry(app,
1257 printf(CMD_MSG_FAIL, "arp add");
1262 /* arp add default */
1263 if ((n_tokens >= 2) &&
1264 (strcmp(tokens[0], "add") == 0) &&
1265 (strcmp(tokens[1], "default") == 0)) {
1268 if (n_tokens != 3) {
1269 printf(CMD_MSG_MISMATCH_ARGS, "arp add default");
1273 if (parser_read_uint32(&port_id, tokens[2])) {
1274 printf(CMD_MSG_INVALID_ARG, "portid");
1278 status = app_pipeline_routing_add_default_arp_entry(app,
1282 printf(CMD_MSG_FAIL, "arp add default");
1285 } /* arp add default */
1288 if ((n_tokens >= 2) &&
1289 (strcmp(tokens[0], "del") == 0) &&
1290 strcmp(tokens[1], "default")) {
1291 struct pipeline_routing_arp_key key;
1292 struct in_addr ipv4;
1295 memset(&key, 0, sizeof(key));
1297 if (n_tokens != 3) {
1298 printf(CMD_MSG_MISMATCH_ARGS, "arp del");
1302 if (parser_read_uint32(&port_id, tokens[1])) {
1303 printf(CMD_MSG_INVALID_ARG, "portid");
1307 if (parse_ipv4_addr(tokens[2], &ipv4)) {
1308 printf(CMD_MSG_INVALID_ARG, "ipaddr");
1312 key.type = PIPELINE_ROUTING_ARP_IPV4;
1313 key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
1314 key.key.ipv4.port_id = port_id;
1316 status = app_pipeline_routing_delete_arp_entry(app,
1320 printf(CMD_MSG_FAIL, "arp del");
1325 /* arp del default */
1326 if ((n_tokens >= 2) &&
1327 (strcmp(tokens[0], "del") == 0) &&
1328 (strcmp(tokens[1], "default") == 0)) {
1329 if (n_tokens != 2) {
1330 printf(CMD_MSG_MISMATCH_ARGS, "arp del default");
1334 status = app_pipeline_routing_delete_default_arp_entry(app,
1337 printf(CMD_MSG_FAIL, "arp del default");
1340 } /* arp del default */
1343 if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
1344 if (n_tokens != 1) {
1345 printf(CMD_MSG_MISMATCH_ARGS, "arp ls");
1349 status = app_pipeline_routing_arp_ls(app, params->p);
1351 printf(CMD_MSG_FAIL, "arp ls");
1356 printf(CMD_MSG_FAIL, "arp");
1359 static cmdline_parse_token_string_t cmd_arp_p_string =
1360 TOKEN_STRING_INITIALIZER(struct cmd_arp_result, p_string, "p");
1362 static cmdline_parse_token_num_t cmd_arp_p =
1363 TOKEN_NUM_INITIALIZER(struct cmd_arp_result, p, UINT32);
1365 static cmdline_parse_token_string_t cmd_arp_arp_string =
1366 TOKEN_STRING_INITIALIZER(struct cmd_arp_result, arp_string, "arp");
1368 static cmdline_parse_token_string_t cmd_arp_multi_string =
1369 TOKEN_STRING_INITIALIZER(struct cmd_arp_result, multi_string,
1370 TOKEN_STRING_MULTI);
1372 static cmdline_parse_inst_t cmd_arp = {
1373 .f = cmd_arp_parsed,
1375 .help_str = "arp add / add default / del / del default / ls",
1377 (void *)&cmd_arp_p_string,
1379 (void *)&cmd_arp_arp_string,
1380 (void *)&cmd_arp_multi_string,
1385 static cmdline_parse_ctx_t pipeline_cmds[] = {
1386 (cmdline_parse_inst_t *)&cmd_route,
1387 (cmdline_parse_inst_t *)&cmd_arp,
1391 static struct pipeline_fe_ops pipeline_routing_fe_ops = {
1392 .f_init = pipeline_routing_init,
1393 .f_free = app_pipeline_routing_free,
1394 .cmds = pipeline_cmds,
1397 struct pipeline_type pipeline_routing = {
1399 .be_ops = &pipeline_routing_be_ops,
1400 .fe_ops = &pipeline_routing_fe_ops,