xref: /dpdk/app/graph/ip6_route.c (revision 2cfebc3f1046e4166e13b4f906e3ddc1c26c7eeb)
183b8e58eSRakesh Kudurumalla /* SPDX-License-Identifier: BSD-3-Clause
283b8e58eSRakesh Kudurumalla  * Copyright(c) 2023 Marvell.
383b8e58eSRakesh Kudurumalla  */
483b8e58eSRakesh Kudurumalla 
583b8e58eSRakesh Kudurumalla #include <stdio.h>
683b8e58eSRakesh Kudurumalla #include <stdlib.h>
783b8e58eSRakesh Kudurumalla #include <string.h>
883b8e58eSRakesh Kudurumalla #include <cmdline_parse.h>
983b8e58eSRakesh Kudurumalla #include <cmdline_parse_num.h>
1083b8e58eSRakesh Kudurumalla #include <cmdline_parse_string.h>
1183b8e58eSRakesh Kudurumalla #include <cmdline_socket.h>
1283b8e58eSRakesh Kudurumalla 
1383b8e58eSRakesh Kudurumalla #include <rte_node_ip6_api.h>
14*2cfebc3fSRobin Jarry #include <rte_ip6.h>
1583b8e58eSRakesh Kudurumalla 
1683b8e58eSRakesh Kudurumalla #include "module_api.h"
1783b8e58eSRakesh Kudurumalla #include "route_priv.h"
1883b8e58eSRakesh Kudurumalla 
1983b8e58eSRakesh Kudurumalla static const char
2083b8e58eSRakesh Kudurumalla cmd_ipv6_lookup_help[] = "ipv6_lookup route add ipv6 <ip> netmask <mask> via <ip>";
2183b8e58eSRakesh Kudurumalla 
2283b8e58eSRakesh Kudurumalla struct ip6_route route6 = TAILQ_HEAD_INITIALIZER(route6);
2383b8e58eSRakesh Kudurumalla 
2483b8e58eSRakesh Kudurumalla void
2583b8e58eSRakesh Kudurumalla route_ip6_list_clean(void)
2683b8e58eSRakesh Kudurumalla {
2783b8e58eSRakesh Kudurumalla 	struct route_ipv6_config *route;
2883b8e58eSRakesh Kudurumalla 
2983b8e58eSRakesh Kudurumalla 	while (!TAILQ_EMPTY(&route6)) {
3083b8e58eSRakesh Kudurumalla 		route = TAILQ_FIRST(&route6);
3183b8e58eSRakesh Kudurumalla 		TAILQ_REMOVE(&route6, route, next);
3283b8e58eSRakesh Kudurumalla 	}
3383b8e58eSRakesh Kudurumalla }
3483b8e58eSRakesh Kudurumalla 
3583b8e58eSRakesh Kudurumalla static struct route_ipv6_config *
3683b8e58eSRakesh Kudurumalla find_route6_entry(struct route_ipv6_config *route)
3783b8e58eSRakesh Kudurumalla {
3883b8e58eSRakesh Kudurumalla 	struct route_ipv6_config *ipv6route;
3983b8e58eSRakesh Kudurumalla 
4083b8e58eSRakesh Kudurumalla 	TAILQ_FOREACH(ipv6route, &route6, next) {
4183b8e58eSRakesh Kudurumalla 		if (!memcmp(ipv6route, route, sizeof(*route)))
4283b8e58eSRakesh Kudurumalla 			return ipv6route;
4383b8e58eSRakesh Kudurumalla 	}
4483b8e58eSRakesh Kudurumalla 	return NULL;
4583b8e58eSRakesh Kudurumalla }
4683b8e58eSRakesh Kudurumalla 
4783b8e58eSRakesh Kudurumalla static int
4883b8e58eSRakesh Kudurumalla route6_rewirte_table_update(struct route_ipv6_config *ipv6route)
4983b8e58eSRakesh Kudurumalla {
5083b8e58eSRakesh Kudurumalla 	uint8_t depth;
5183b8e58eSRakesh Kudurumalla 	int portid;
5283b8e58eSRakesh Kudurumalla 
53*2cfebc3fSRobin Jarry 	portid = ethdev_portid_by_ip6(&ipv6route->gateway, &ipv6route->mask);
5483b8e58eSRakesh Kudurumalla 	if (portid < 0) {
5583b8e58eSRakesh Kudurumalla 		printf("Invalid portid found to install the route\n");
5683b8e58eSRakesh Kudurumalla 		return portid;
5783b8e58eSRakesh Kudurumalla 	}
58*2cfebc3fSRobin Jarry 	depth = rte_ipv6_mask_depth(&ipv6route->mask);
5983b8e58eSRakesh Kudurumalla 
60*2cfebc3fSRobin Jarry 	return rte_node_ip6_route_add(&ipv6route->ip, depth, portid,
6183b8e58eSRakesh Kudurumalla 			RTE_NODE_IP6_LOOKUP_NEXT_REWRITE);
6283b8e58eSRakesh Kudurumalla 
6383b8e58eSRakesh Kudurumalla }
6483b8e58eSRakesh Kudurumalla 
6583b8e58eSRakesh Kudurumalla static int
6683b8e58eSRakesh Kudurumalla route_ip6_add(struct route_ipv6_config *route)
6783b8e58eSRakesh Kudurumalla {
6883b8e58eSRakesh Kudurumalla 	struct route_ipv6_config *ipv6route;
6983b8e58eSRakesh Kudurumalla 	int rc = -EINVAL;
7083b8e58eSRakesh Kudurumalla 
7183b8e58eSRakesh Kudurumalla 	ipv6route = find_route6_entry(route);
7283b8e58eSRakesh Kudurumalla 	if (!ipv6route) {
7383b8e58eSRakesh Kudurumalla 		ipv6route = malloc(sizeof(struct route_ipv6_config));
7483b8e58eSRakesh Kudurumalla 		if (!ipv6route)
7583b8e58eSRakesh Kudurumalla 			return -ENOMEM;
7683b8e58eSRakesh Kudurumalla 	} else {
7783b8e58eSRakesh Kudurumalla 		return 0;
7883b8e58eSRakesh Kudurumalla 	}
7983b8e58eSRakesh Kudurumalla 
80*2cfebc3fSRobin Jarry 	ipv6route->ip = route->ip;
81*2cfebc3fSRobin Jarry 	ipv6route->mask = route->mask;
82*2cfebc3fSRobin Jarry 	ipv6route->gateway = route->gateway;
8383b8e58eSRakesh Kudurumalla 	ipv6route->is_used = true;
8483b8e58eSRakesh Kudurumalla 
855c59002aSRakesh Kudurumalla 	if (!graph_status_get())
865c59002aSRakesh Kudurumalla 		goto exit;
875c59002aSRakesh Kudurumalla 
8883b8e58eSRakesh Kudurumalla 	rc = route6_rewirte_table_update(ipv6route);
8983b8e58eSRakesh Kudurumalla 	if (rc)
9083b8e58eSRakesh Kudurumalla 		goto free;
9183b8e58eSRakesh Kudurumalla 
925c59002aSRakesh Kudurumalla exit:
9383b8e58eSRakesh Kudurumalla 	TAILQ_INSERT_TAIL(&route6, ipv6route, next);
9483b8e58eSRakesh Kudurumalla 	return 0;
9583b8e58eSRakesh Kudurumalla free:
9683b8e58eSRakesh Kudurumalla 	free(ipv6route);
9783b8e58eSRakesh Kudurumalla 	return rc;
9883b8e58eSRakesh Kudurumalla }
9983b8e58eSRakesh Kudurumalla 
10083b8e58eSRakesh Kudurumalla int
10183b8e58eSRakesh Kudurumalla route_ip6_add_to_lookup(void)
10283b8e58eSRakesh Kudurumalla {
10383b8e58eSRakesh Kudurumalla 	struct route_ipv6_config *route = NULL;
10483b8e58eSRakesh Kudurumalla 	int rc = -EINVAL;
10583b8e58eSRakesh Kudurumalla 
10683b8e58eSRakesh Kudurumalla 	TAILQ_FOREACH(route, &route6, next) {
10783b8e58eSRakesh Kudurumalla 		rc = route6_rewirte_table_update(route);
10883b8e58eSRakesh Kudurumalla 		if (rc < 0)
10983b8e58eSRakesh Kudurumalla 			return rc;
11083b8e58eSRakesh Kudurumalla 	}
11183b8e58eSRakesh Kudurumalla 
11283b8e58eSRakesh Kudurumalla 	return 0;
11383b8e58eSRakesh Kudurumalla }
11483b8e58eSRakesh Kudurumalla 
1150f32dac4SSunil Kumar Kori void
1160f32dac4SSunil Kumar Kori cmd_help_ipv6_lookup_parsed(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl,
11783b8e58eSRakesh Kudurumalla 			    __rte_unused void *data)
11883b8e58eSRakesh Kudurumalla {
11983b8e58eSRakesh Kudurumalla 	size_t len;
12083b8e58eSRakesh Kudurumalla 
12183b8e58eSRakesh Kudurumalla 	len = strlen(conn->msg_out);
12283b8e58eSRakesh Kudurumalla 	conn->msg_out += len;
12383b8e58eSRakesh Kudurumalla 	snprintf(conn->msg_out, conn->msg_out_len_max, "\n%s\n%s\n",
12483b8e58eSRakesh Kudurumalla 		 "--------------------------- ipv6_lookup command help ---------------------------",
12583b8e58eSRakesh Kudurumalla 		 cmd_ipv6_lookup_help);
12683b8e58eSRakesh Kudurumalla 
12783b8e58eSRakesh Kudurumalla 	len = strlen(conn->msg_out);
12883b8e58eSRakesh Kudurumalla 	conn->msg_out_len_max -= len;
12983b8e58eSRakesh Kudurumalla }
13083b8e58eSRakesh Kudurumalla 
1310f32dac4SSunil Kumar Kori void
1320f32dac4SSunil Kumar Kori cmd_ipv6_lookup_route_add_ipv6_parsed(void *parsed_result, __rte_unused struct cmdline *cl,
1330f32dac4SSunil Kumar Kori 				      void *data __rte_unused)
13483b8e58eSRakesh Kudurumalla {
1350f32dac4SSunil Kumar Kori 	struct cmd_ipv6_lookup_route_add_ipv6_result *res = parsed_result;
136*2cfebc3fSRobin Jarry 	struct route_ipv6_config config = {
137*2cfebc3fSRobin Jarry 		.ip = res->ip.addr.ipv6,
138*2cfebc3fSRobin Jarry 		.mask = res->mask.addr.ipv6,
139*2cfebc3fSRobin Jarry 		.gateway = res->via_ip.addr.ipv6,
140*2cfebc3fSRobin Jarry 	};
141*2cfebc3fSRobin Jarry 	int rc;
14283b8e58eSRakesh Kudurumalla 
14383b8e58eSRakesh Kudurumalla 	rc = route_ip6_add(&config);
14483b8e58eSRakesh Kudurumalla 	if (rc)
1450f32dac4SSunil Kumar Kori 		printf(MSG_CMD_FAIL, res->ipv6_lookup);
14683b8e58eSRakesh Kudurumalla }
147