xref: /dpdk/app/graph/ip6_route.c (revision 2cfebc3f1046e4166e13b4f906e3ddc1c26c7eeb)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2023 Marvell.
3  */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <cmdline_parse.h>
9 #include <cmdline_parse_num.h>
10 #include <cmdline_parse_string.h>
11 #include <cmdline_socket.h>
12 
13 #include <rte_node_ip6_api.h>
14 #include <rte_ip6.h>
15 
16 #include "module_api.h"
17 #include "route_priv.h"
18 
19 static const char
20 cmd_ipv6_lookup_help[] = "ipv6_lookup route add ipv6 <ip> netmask <mask> via <ip>";
21 
22 struct ip6_route route6 = TAILQ_HEAD_INITIALIZER(route6);
23 
24 void
25 route_ip6_list_clean(void)
26 {
27 	struct route_ipv6_config *route;
28 
29 	while (!TAILQ_EMPTY(&route6)) {
30 		route = TAILQ_FIRST(&route6);
31 		TAILQ_REMOVE(&route6, route, next);
32 	}
33 }
34 
35 static struct route_ipv6_config *
36 find_route6_entry(struct route_ipv6_config *route)
37 {
38 	struct route_ipv6_config *ipv6route;
39 
40 	TAILQ_FOREACH(ipv6route, &route6, next) {
41 		if (!memcmp(ipv6route, route, sizeof(*route)))
42 			return ipv6route;
43 	}
44 	return NULL;
45 }
46 
47 static int
48 route6_rewirte_table_update(struct route_ipv6_config *ipv6route)
49 {
50 	uint8_t depth;
51 	int portid;
52 
53 	portid = ethdev_portid_by_ip6(&ipv6route->gateway, &ipv6route->mask);
54 	if (portid < 0) {
55 		printf("Invalid portid found to install the route\n");
56 		return portid;
57 	}
58 	depth = rte_ipv6_mask_depth(&ipv6route->mask);
59 
60 	return rte_node_ip6_route_add(&ipv6route->ip, depth, portid,
61 			RTE_NODE_IP6_LOOKUP_NEXT_REWRITE);
62 
63 }
64 
65 static int
66 route_ip6_add(struct route_ipv6_config *route)
67 {
68 	struct route_ipv6_config *ipv6route;
69 	int rc = -EINVAL;
70 
71 	ipv6route = find_route6_entry(route);
72 	if (!ipv6route) {
73 		ipv6route = malloc(sizeof(struct route_ipv6_config));
74 		if (!ipv6route)
75 			return -ENOMEM;
76 	} else {
77 		return 0;
78 	}
79 
80 	ipv6route->ip = route->ip;
81 	ipv6route->mask = route->mask;
82 	ipv6route->gateway = route->gateway;
83 	ipv6route->is_used = true;
84 
85 	if (!graph_status_get())
86 		goto exit;
87 
88 	rc = route6_rewirte_table_update(ipv6route);
89 	if (rc)
90 		goto free;
91 
92 exit:
93 	TAILQ_INSERT_TAIL(&route6, ipv6route, next);
94 	return 0;
95 free:
96 	free(ipv6route);
97 	return rc;
98 }
99 
100 int
101 route_ip6_add_to_lookup(void)
102 {
103 	struct route_ipv6_config *route = NULL;
104 	int rc = -EINVAL;
105 
106 	TAILQ_FOREACH(route, &route6, next) {
107 		rc = route6_rewirte_table_update(route);
108 		if (rc < 0)
109 			return rc;
110 	}
111 
112 	return 0;
113 }
114 
115 void
116 cmd_help_ipv6_lookup_parsed(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl,
117 			    __rte_unused void *data)
118 {
119 	size_t len;
120 
121 	len = strlen(conn->msg_out);
122 	conn->msg_out += len;
123 	snprintf(conn->msg_out, conn->msg_out_len_max, "\n%s\n%s\n",
124 		 "--------------------------- ipv6_lookup command help ---------------------------",
125 		 cmd_ipv6_lookup_help);
126 
127 	len = strlen(conn->msg_out);
128 	conn->msg_out_len_max -= len;
129 }
130 
131 void
132 cmd_ipv6_lookup_route_add_ipv6_parsed(void *parsed_result, __rte_unused struct cmdline *cl,
133 				      void *data __rte_unused)
134 {
135 	struct cmd_ipv6_lookup_route_add_ipv6_result *res = parsed_result;
136 	struct route_ipv6_config config = {
137 		.ip = res->ip.addr.ipv6,
138 		.mask = res->mask.addr.ipv6,
139 		.gateway = res->via_ip.addr.ipv6,
140 	};
141 	int rc;
142 
143 	rc = route_ip6_add(&config);
144 	if (rc)
145 		printf(MSG_CMD_FAIL, res->ipv6_lookup);
146 }
147