xref: /dpdk/app/graph/ip4_route.c (revision 0f32dac4bbf74761972249090523f4581ca13126)
1aff63b6dSSunil Kumar Kori /* SPDX-License-Identifier: BSD-3-Clause
2aff63b6dSSunil Kumar Kori  * Copyright(c) 2023 Marvell.
3aff63b6dSSunil Kumar Kori  */
4aff63b6dSSunil Kumar Kori 
5aff63b6dSSunil Kumar Kori #include <stdio.h>
6aff63b6dSSunil Kumar Kori #include <stdlib.h>
7aff63b6dSSunil Kumar Kori #include <string.h>
8aff63b6dSSunil Kumar Kori 
9aff63b6dSSunil Kumar Kori #include <cmdline_parse.h>
10aff63b6dSSunil Kumar Kori #include <cmdline_parse_num.h>
11aff63b6dSSunil Kumar Kori #include <cmdline_parse_string.h>
12aff63b6dSSunil Kumar Kori #include <cmdline_socket.h>
13aff63b6dSSunil Kumar Kori #include <rte_node_ip4_api.h>
14aff63b6dSSunil Kumar Kori 
15aff63b6dSSunil Kumar Kori #include "module_api.h"
16aff63b6dSSunil Kumar Kori #include "route_priv.h"
17aff63b6dSSunil Kumar Kori 
18aff63b6dSSunil Kumar Kori static const char
19aff63b6dSSunil Kumar Kori cmd_ipv4_lookup_help[] = "ipv4_lookup route add ipv4 <ip> netmask <mask> via <ip>";
20aff63b6dSSunil Kumar Kori 
21aff63b6dSSunil Kumar Kori struct ip4_route route4 = TAILQ_HEAD_INITIALIZER(route4);
22aff63b6dSSunil Kumar Kori 
23aff63b6dSSunil Kumar Kori void
route_ip4_list_clean(void)24aff63b6dSSunil Kumar Kori route_ip4_list_clean(void)
25aff63b6dSSunil Kumar Kori {
26aff63b6dSSunil Kumar Kori 	struct route_ipv4_config *route;
27aff63b6dSSunil Kumar Kori 
28aff63b6dSSunil Kumar Kori 	while (!TAILQ_EMPTY(&route4)) {
29aff63b6dSSunil Kumar Kori 		route = TAILQ_FIRST(&route4);
30aff63b6dSSunil Kumar Kori 		TAILQ_REMOVE(&route4, route, next);
31aff63b6dSSunil Kumar Kori 	}
32aff63b6dSSunil Kumar Kori }
33aff63b6dSSunil Kumar Kori 
34aff63b6dSSunil Kumar Kori static struct route_ipv4_config *
find_route4_entry(struct route_ipv4_config * route)35aff63b6dSSunil Kumar Kori find_route4_entry(struct route_ipv4_config *route)
36aff63b6dSSunil Kumar Kori {
37aff63b6dSSunil Kumar Kori 	struct route_ipv4_config *ipv4route;
38aff63b6dSSunil Kumar Kori 
39aff63b6dSSunil Kumar Kori 	TAILQ_FOREACH(ipv4route, &route4, next) {
40aff63b6dSSunil Kumar Kori 		if (!memcmp(ipv4route, route, sizeof(*route)))
41aff63b6dSSunil Kumar Kori 			return ipv4route;
42aff63b6dSSunil Kumar Kori 	}
43aff63b6dSSunil Kumar Kori 	return NULL;
44aff63b6dSSunil Kumar Kori 
45aff63b6dSSunil Kumar Kori }
46aff63b6dSSunil Kumar Kori 
47aff63b6dSSunil Kumar Kori static uint8_t
convert_netmask_to_depth(uint32_t netmask)48aff63b6dSSunil Kumar Kori convert_netmask_to_depth(uint32_t netmask)
49aff63b6dSSunil Kumar Kori {
50aff63b6dSSunil Kumar Kori 	uint8_t zerobits = 0;
51aff63b6dSSunil Kumar Kori 
52aff63b6dSSunil Kumar Kori 	while ((netmask & 0x1) == 0) {
53aff63b6dSSunil Kumar Kori 		netmask = netmask >> 1;
54aff63b6dSSunil Kumar Kori 		zerobits++;
55aff63b6dSSunil Kumar Kori 	}
56aff63b6dSSunil Kumar Kori 
57aff63b6dSSunil Kumar Kori 	return (32 - zerobits);
58aff63b6dSSunil Kumar Kori }
59aff63b6dSSunil Kumar Kori 
60aff63b6dSSunil Kumar Kori static int
route4_rewirte_table_update(struct route_ipv4_config * ipv4route)61aff63b6dSSunil Kumar Kori route4_rewirte_table_update(struct route_ipv4_config *ipv4route)
62aff63b6dSSunil Kumar Kori {
63aff63b6dSSunil Kumar Kori 	uint8_t depth;
64aff63b6dSSunil Kumar Kori 	int portid;
65aff63b6dSSunil Kumar Kori 
66aff63b6dSSunil Kumar Kori 	portid = ethdev_portid_by_ip4(ipv4route->via, ipv4route->netmask);
67aff63b6dSSunil Kumar Kori 	if (portid < 0) {
68aff63b6dSSunil Kumar Kori 		printf("Invalid portid found to install the route\n");
69aff63b6dSSunil Kumar Kori 		return portid;
70aff63b6dSSunil Kumar Kori 	}
71aff63b6dSSunil Kumar Kori 
72aff63b6dSSunil Kumar Kori 	depth = convert_netmask_to_depth(ipv4route->netmask);
73aff63b6dSSunil Kumar Kori 
74aff63b6dSSunil Kumar Kori 	return rte_node_ip4_route_add(ipv4route->ip, depth, portid,
75aff63b6dSSunil Kumar Kori 			RTE_NODE_IP4_LOOKUP_NEXT_REWRITE);
76aff63b6dSSunil Kumar Kori }
77aff63b6dSSunil Kumar Kori 
78aff63b6dSSunil Kumar Kori static int
route_ip4_add(struct route_ipv4_config * route)79aff63b6dSSunil Kumar Kori route_ip4_add(struct route_ipv4_config *route)
80aff63b6dSSunil Kumar Kori {
81aff63b6dSSunil Kumar Kori 	struct route_ipv4_config *ipv4route;
82aff63b6dSSunil Kumar Kori 	int rc = -EINVAL;
83aff63b6dSSunil Kumar Kori 
84aff63b6dSSunil Kumar Kori 	ipv4route = find_route4_entry(route);
85aff63b6dSSunil Kumar Kori 
86aff63b6dSSunil Kumar Kori 	if (!ipv4route) {
87aff63b6dSSunil Kumar Kori 		ipv4route = malloc(sizeof(struct route_ipv4_config));
88aff63b6dSSunil Kumar Kori 		if (!ipv4route)
89aff63b6dSSunil Kumar Kori 			return -ENOMEM;
90aff63b6dSSunil Kumar Kori 	} else {
91aff63b6dSSunil Kumar Kori 		return 0;
92aff63b6dSSunil Kumar Kori 	}
93aff63b6dSSunil Kumar Kori 
94aff63b6dSSunil Kumar Kori 	ipv4route->ip = route->ip;
95aff63b6dSSunil Kumar Kori 	ipv4route->netmask = route->netmask;
96aff63b6dSSunil Kumar Kori 	ipv4route->via = route->via;
97aff63b6dSSunil Kumar Kori 	ipv4route->is_used = true;
98aff63b6dSSunil Kumar Kori 
995c59002aSRakesh Kudurumalla 	if (!graph_status_get())
1005c59002aSRakesh Kudurumalla 		goto exit;
1015c59002aSRakesh Kudurumalla 
102aff63b6dSSunil Kumar Kori 	rc = route4_rewirte_table_update(ipv4route);
103aff63b6dSSunil Kumar Kori 	if (rc)
104aff63b6dSSunil Kumar Kori 		goto free;
105aff63b6dSSunil Kumar Kori 
1065c59002aSRakesh Kudurumalla exit:
107aff63b6dSSunil Kumar Kori 	TAILQ_INSERT_TAIL(&route4, ipv4route, next);
108aff63b6dSSunil Kumar Kori 	return 0;
109aff63b6dSSunil Kumar Kori free:
110aff63b6dSSunil Kumar Kori 	free(ipv4route);
111aff63b6dSSunil Kumar Kori 	return rc;
112aff63b6dSSunil Kumar Kori }
113aff63b6dSSunil Kumar Kori 
114aff63b6dSSunil Kumar Kori int
route_ip4_add_to_lookup(void)115aff63b6dSSunil Kumar Kori route_ip4_add_to_lookup(void)
116aff63b6dSSunil Kumar Kori {
117aff63b6dSSunil Kumar Kori 	struct route_ipv4_config *route = NULL;
118aff63b6dSSunil Kumar Kori 	int rc = -EINVAL;
119aff63b6dSSunil Kumar Kori 
120aff63b6dSSunil Kumar Kori 	TAILQ_FOREACH(route, &route4, next) {
121aff63b6dSSunil Kumar Kori 		rc = route4_rewirte_table_update(route);
122aff63b6dSSunil Kumar Kori 		if (rc < 0)
123aff63b6dSSunil Kumar Kori 			return rc;
124aff63b6dSSunil Kumar Kori 	}
125aff63b6dSSunil Kumar Kori 
126aff63b6dSSunil Kumar Kori 	return 0;
127aff63b6dSSunil Kumar Kori }
128aff63b6dSSunil Kumar Kori 
129*0f32dac4SSunil Kumar Kori void
cmd_help_ipv4_lookup_parsed(__rte_unused void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)130*0f32dac4SSunil Kumar Kori cmd_help_ipv4_lookup_parsed(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl,
131aff63b6dSSunil Kumar Kori 			    __rte_unused void *data)
132aff63b6dSSunil Kumar Kori {
133aff63b6dSSunil Kumar Kori 	size_t len;
134aff63b6dSSunil Kumar Kori 
135aff63b6dSSunil Kumar Kori 	len = strlen(conn->msg_out);
136aff63b6dSSunil Kumar Kori 	conn->msg_out += len;
137aff63b6dSSunil Kumar Kori 	snprintf(conn->msg_out, conn->msg_out_len_max, "\n%s\n%s\n",
138aff63b6dSSunil Kumar Kori 		 "--------------------------- ipv4_lookup command help ---------------------------",
139aff63b6dSSunil Kumar Kori 		 cmd_ipv4_lookup_help);
140aff63b6dSSunil Kumar Kori 
141aff63b6dSSunil Kumar Kori 	len = strlen(conn->msg_out);
142aff63b6dSSunil Kumar Kori 	conn->msg_out_len_max -= len;
143aff63b6dSSunil Kumar Kori }
144aff63b6dSSunil Kumar Kori 
145*0f32dac4SSunil Kumar Kori void
cmd_ipv4_lookup_route_add_ipv4_parsed(void * parsed_result,__rte_unused struct cmdline * cl,void * data __rte_unused)146*0f32dac4SSunil Kumar Kori cmd_ipv4_lookup_route_add_ipv4_parsed(void *parsed_result, __rte_unused struct cmdline *cl,
147*0f32dac4SSunil Kumar Kori 				      void *data __rte_unused)
148aff63b6dSSunil Kumar Kori {
149*0f32dac4SSunil Kumar Kori 	struct cmd_ipv4_lookup_route_add_ipv4_result *res = parsed_result;
150aff63b6dSSunil Kumar Kori 	struct route_ipv4_config config;
151aff63b6dSSunil Kumar Kori 	int rc = -EINVAL;
152aff63b6dSSunil Kumar Kori 
153*0f32dac4SSunil Kumar Kori 	config.ip = rte_be_to_cpu_32(res->ip.addr.ipv4.s_addr);
154*0f32dac4SSunil Kumar Kori 	config.netmask = rte_be_to_cpu_32(res->mask.addr.ipv4.s_addr);
155*0f32dac4SSunil Kumar Kori 	config.via = rte_be_to_cpu_32(res->via_ip.addr.ipv4.s_addr);
156aff63b6dSSunil Kumar Kori 
157aff63b6dSSunil Kumar Kori 	rc = route_ip4_add(&config);
158aff63b6dSSunil Kumar Kori 	if (rc < 0)
159*0f32dac4SSunil Kumar Kori 		printf(MSG_CMD_FAIL, res->ipv4_lookup);
160aff63b6dSSunil Kumar Kori }
161