Branch data Line data Source code
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 : :
9 : : #include <cmdline_parse.h>
10 : : #include <cmdline_parse_num.h>
11 : : #include <cmdline_parse_string.h>
12 : : #include <cmdline_socket.h>
13 : : #include <rte_node_ip4_api.h>
14 : :
15 : : #include "module_api.h"
16 : : #include "route_priv.h"
17 : :
18 : : static const char
19 : : cmd_ipv4_lookup_help[] = "ipv4_lookup route add ipv4 <ip> netmask <mask> via <ip>";
20 : :
21 : : struct ip4_route route4 = TAILQ_HEAD_INITIALIZER(route4);
22 : :
23 : :
24 : : void
25 : 0 : route_ip4_list_clean(void)
26 : : {
27 : : struct route_ipv4_config *route;
28 : :
29 : 0 : while (!TAILQ_EMPTY(&route4)) {
30 : : route = TAILQ_FIRST(&route4);
31 : 0 : TAILQ_REMOVE(&route4, route, next);
32 : : }
33 : 0 : }
34 : :
35 : : static struct route_ipv4_config *
36 : 0 : find_route4_entry(struct route_ipv4_config *route)
37 : : {
38 : : struct route_ipv4_config *ipv4route;
39 : :
40 : 0 : TAILQ_FOREACH(ipv4route, &route4, next) {
41 : 0 : if (!memcmp(ipv4route, route, sizeof(*route)))
42 : 0 : return ipv4route;
43 : : }
44 : : return NULL;
45 : :
46 : : }
47 : :
48 : : static uint8_t
49 : : convert_netmask_to_depth(uint32_t netmask)
50 : : {
51 : : uint8_t zerobits = 0;
52 : :
53 : 0 : while ((netmask & 0x1) == 0) {
54 : 0 : netmask = netmask >> 1;
55 : 0 : zerobits++;
56 : : }
57 : :
58 : 0 : return (32 - zerobits);
59 : : }
60 : :
61 : : static int
62 : 0 : route4_rewirte_table_update(struct route_ipv4_config *ipv4route)
63 : : {
64 : : uint8_t depth;
65 : : int portid;
66 : :
67 : 0 : portid = ethdev_portid_by_ip4(ipv4route->via, ipv4route->netmask);
68 : 0 : if (portid < 0) {
69 : : printf("Invalid portid found to install the route\n");
70 : 0 : return portid;
71 : : }
72 : :
73 : 0 : depth = convert_netmask_to_depth(ipv4route->netmask);
74 : :
75 : 0 : return rte_node_ip4_route_add(ipv4route->ip, depth, portid,
76 : : RTE_NODE_IP4_LOOKUP_NEXT_REWRITE);
77 : : }
78 : :
79 : : static int
80 : 0 : route_ip4_add(struct route_ipv4_config *route)
81 : : {
82 : : struct route_ipv4_config *ipv4route;
83 : : int rc = -EINVAL;
84 : :
85 : 0 : ipv4route = find_route4_entry(route);
86 : :
87 : 0 : if (!ipv4route) {
88 : 0 : ipv4route = malloc(sizeof(struct route_ipv4_config));
89 : 0 : if (!ipv4route)
90 : : return -ENOMEM;
91 : : } else {
92 : : return 0;
93 : : }
94 : :
95 : 0 : ipv4route->ip = route->ip;
96 : 0 : ipv4route->netmask = route->netmask;
97 : 0 : ipv4route->via = route->via;
98 : 0 : ipv4route->is_used = true;
99 : :
100 : 0 : if (!graph_status_get())
101 : 0 : goto exit;
102 : :
103 : 0 : rc = route4_rewirte_table_update(ipv4route);
104 : 0 : if (rc)
105 : 0 : goto free;
106 : :
107 : 0 : exit:
108 : 0 : TAILQ_INSERT_TAIL(&route4, ipv4route, next);
109 : 0 : return 0;
110 : : free:
111 : 0 : free(ipv4route);
112 : 0 : return rc;
113 : : }
114 : :
115 : : int
116 : 0 : route_ip4_add_to_lookup(void)
117 : : {
118 : : struct route_ipv4_config *route = NULL;
119 : : int rc = -EINVAL;
120 : :
121 : 0 : TAILQ_FOREACH(route, &route4, next) {
122 : 0 : rc = route4_rewirte_table_update(route);
123 : 0 : if (rc < 0)
124 : 0 : return rc;
125 : : }
126 : :
127 : : return 0;
128 : : }
129 : :
130 : : static void
131 : 0 : cli_ipv4_lookup_help(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl,
132 : : __rte_unused void *data)
133 : : {
134 : : size_t len;
135 : :
136 : 0 : len = strlen(conn->msg_out);
137 : 0 : conn->msg_out += len;
138 : 0 : snprintf(conn->msg_out, conn->msg_out_len_max, "\n%s\n%s\n",
139 : : "--------------------------- ipv4_lookup command help ---------------------------",
140 : : cmd_ipv4_lookup_help);
141 : :
142 : 0 : len = strlen(conn->msg_out);
143 : 0 : conn->msg_out_len_max -= len;
144 : 0 : }
145 : :
146 : : static void
147 : 0 : cli_ipv4_lookup(void *parsed_result, __rte_unused struct cmdline *cl, void *data __rte_unused)
148 : : {
149 : : struct ip4_lookup_cmd_tokens *res = parsed_result;
150 : : struct route_ipv4_config config;
151 : : int rc = -EINVAL;
152 : :
153 : 0 : if (parser_ip4_read(&config.ip, res->ip)) {
154 : : printf(MSG_ARG_INVALID, "ipv4");
155 : 0 : return;
156 : : }
157 : :
158 : 0 : if (parser_ip4_read(&config.netmask, res->mask)) {
159 : : printf(MSG_ARG_INVALID, "netmask");
160 : 0 : return;
161 : : }
162 : :
163 : 0 : if (parser_ip4_read(&config.via, res->via_ip)) {
164 : : printf(MSG_ARG_INVALID, "via ip");
165 : 0 : return;
166 : : }
167 : :
168 : 0 : rc = route_ip4_add(&config);
169 : 0 : if (rc < 0)
170 : 0 : printf(MSG_CMD_FAIL, res->cmd);
171 : : }
172 : :
173 : : cmdline_parse_token_string_t ip4_lookup_cmd =
174 : : TOKEN_STRING_INITIALIZER(struct ip4_lookup_cmd_tokens, cmd, "ipv4_lookup");
175 : : cmdline_parse_token_string_t ip4_lookup_route =
176 : : TOKEN_STRING_INITIALIZER(struct ip4_lookup_cmd_tokens, route, "route");
177 : : cmdline_parse_token_string_t ip4_lookup_add =
178 : : TOKEN_STRING_INITIALIZER(struct ip4_lookup_cmd_tokens, add, "add");
179 : : cmdline_parse_token_string_t ip4_lookup_ip4 =
180 : : TOKEN_STRING_INITIALIZER(struct ip4_lookup_cmd_tokens, ip4, "ipv4");
181 : : cmdline_parse_token_string_t ip4_lookup_ip =
182 : : TOKEN_STRING_INITIALIZER(struct ip4_lookup_cmd_tokens, ip, NULL);
183 : : cmdline_parse_token_string_t ip4_lookup_netmask =
184 : : TOKEN_STRING_INITIALIZER(struct ip4_lookup_cmd_tokens, netmask, "netmask");
185 : : cmdline_parse_token_string_t ip4_lookup_mask =
186 : : TOKEN_STRING_INITIALIZER(struct ip4_lookup_cmd_tokens, mask, NULL);
187 : : cmdline_parse_token_string_t ip4_lookup_via =
188 : : TOKEN_STRING_INITIALIZER(struct ip4_lookup_cmd_tokens, via, "via");
189 : : cmdline_parse_token_string_t ip4_lookup_via_ip =
190 : : TOKEN_STRING_INITIALIZER(struct ip4_lookup_cmd_tokens, via_ip, NULL);
191 : :
192 : : cmdline_parse_inst_t ipv4_lookup_cmd_ctx = {
193 : : .f = cli_ipv4_lookup,
194 : : .data = NULL,
195 : : .help_str = cmd_ipv4_lookup_help,
196 : : .tokens = {
197 : : (void *)&ip4_lookup_cmd,
198 : : (void *)&ip4_lookup_route,
199 : : (void *)&ip4_lookup_add,
200 : : (void *)&ip4_lookup_ip4,
201 : : (void *)&ip4_lookup_ip,
202 : : (void *)&ip4_lookup_netmask,
203 : : (void *)&ip4_lookup_mask,
204 : : (void *)&ip4_lookup_via,
205 : : (void *)&ip4_lookup_via_ip,
206 : : NULL,
207 : : },
208 : : };
209 : :
210 : : cmdline_parse_token_string_t ipv4_lookup_help_cmd =
211 : : TOKEN_STRING_INITIALIZER(struct ipv4_lookup_help_cmd_tokens, cmd, "help");
212 : : cmdline_parse_token_string_t ipv4_lookup_help_module =
213 : : TOKEN_STRING_INITIALIZER(struct ipv4_lookup_help_cmd_tokens, module, "ipv4_lookup");
214 : :
215 : : cmdline_parse_inst_t ipv4_lookup_help_cmd_ctx = {
216 : : .f = cli_ipv4_lookup_help,
217 : : .data = NULL,
218 : : .help_str = "",
219 : : .tokens = {
220 : : (void *)&ipv4_lookup_help_cmd,
221 : : (void *)&ipv4_lookup_help_module,
222 : : NULL,
223 : : },
224 : : };
|