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 : : static const char
22 : : cmd_ipv4_lookup_mode_help[] = "ipv4_lookup mode <lpm|fib>";
23 : :
24 : : struct ip4_route route4 = TAILQ_HEAD_INITIALIZER(route4);
25 : :
26 : : enum ip4_lookup_mode ip4_lookup_m = IP4_LOOKUP_LPM;
27 : :
28 : : void
29 : 0 : route_ip4_list_clean(void)
30 : : {
31 : : struct route_ipv4_config *route;
32 : :
33 : 0 : while (!TAILQ_EMPTY(&route4)) {
34 : : route = TAILQ_FIRST(&route4);
35 : 0 : TAILQ_REMOVE(&route4, route, next);
36 : : }
37 : 0 : }
38 : :
39 : : static struct route_ipv4_config *
40 : 0 : find_route4_entry(struct route_ipv4_config *route)
41 : : {
42 : : struct route_ipv4_config *ipv4route;
43 : :
44 : 0 : TAILQ_FOREACH(ipv4route, &route4, next) {
45 : 0 : if (!memcmp(ipv4route, route, sizeof(*route)))
46 : 0 : return ipv4route;
47 : : }
48 : : return NULL;
49 : :
50 : : }
51 : :
52 : : static uint8_t
53 : : convert_netmask_to_depth(uint32_t netmask)
54 : : {
55 : : uint8_t zerobits = 0;
56 : :
57 : 0 : while ((netmask & 0x1) == 0) {
58 : 0 : netmask = netmask >> 1;
59 : 0 : zerobits++;
60 : : }
61 : :
62 : 0 : return (32 - zerobits);
63 : : }
64 : :
65 : : static int
66 : 0 : route4_rewirte_table_update(struct route_ipv4_config *ipv4route)
67 : : {
68 : : uint8_t depth;
69 : : int portid;
70 : : int rc;
71 : :
72 : 0 : portid = ethdev_portid_by_ip4(ipv4route->via, ipv4route->netmask);
73 : 0 : if (portid < 0) {
74 : : printf("Invalid portid found to install the route\n");
75 : 0 : return portid;
76 : : }
77 : :
78 : 0 : depth = convert_netmask_to_depth(ipv4route->netmask);
79 : :
80 : 0 : if (ip4_lookup_m == IP4_LOOKUP_FIB)
81 : 0 : rc = rte_node_ip4_fib_route_add(ipv4route->ip, depth, portid,
82 : : RTE_NODE_IP4_LOOKUP_NEXT_REWRITE);
83 : : else
84 : 0 : rc = rte_node_ip4_route_add(ipv4route->ip, depth, portid,
85 : : RTE_NODE_IP4_LOOKUP_NEXT_REWRITE);
86 : :
87 : : return rc;
88 : : }
89 : :
90 : : static int
91 : 0 : route_ip4_add(struct route_ipv4_config *route)
92 : : {
93 : : struct route_ipv4_config *ipv4route;
94 : : int rc = -EINVAL;
95 : :
96 : 0 : ipv4route = find_route4_entry(route);
97 : :
98 : 0 : if (!ipv4route) {
99 : 0 : ipv4route = malloc(sizeof(struct route_ipv4_config));
100 : 0 : if (!ipv4route)
101 : : return -ENOMEM;
102 : : } else {
103 : : return 0;
104 : : }
105 : :
106 : 0 : ipv4route->ip = route->ip;
107 : 0 : ipv4route->netmask = route->netmask;
108 : 0 : ipv4route->via = route->via;
109 : 0 : ipv4route->is_used = true;
110 : :
111 : 0 : if (!graph_status_get())
112 : 0 : goto exit;
113 : :
114 : 0 : rc = route4_rewirte_table_update(ipv4route);
115 : 0 : if (rc)
116 : 0 : goto free;
117 : :
118 : 0 : exit:
119 : 0 : TAILQ_INSERT_TAIL(&route4, ipv4route, next);
120 : 0 : return 0;
121 : : free:
122 : 0 : free(ipv4route);
123 : 0 : return rc;
124 : : }
125 : :
126 : : int
127 : 0 : route_ip4_add_to_lookup(void)
128 : : {
129 : : struct route_ipv4_config *route = NULL;
130 : : int rc = -EINVAL;
131 : :
132 : 0 : TAILQ_FOREACH(route, &route4, next) {
133 : 0 : rc = route4_rewirte_table_update(route);
134 : 0 : if (rc < 0)
135 : 0 : return rc;
136 : : }
137 : :
138 : : return 0;
139 : : }
140 : :
141 : : void
142 : 0 : cmd_help_ipv4_lookup_parsed(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl,
143 : : __rte_unused void *data)
144 : : {
145 : : size_t len;
146 : :
147 : 0 : len = strlen(conn->msg_out);
148 : 0 : conn->msg_out += len;
149 : 0 : snprintf(conn->msg_out, conn->msg_out_len_max, "\n%s\n%s\n%s\n",
150 : : "--------------------------- ipv4_lookup command help ---------------------------",
151 : : cmd_ipv4_lookup_help, cmd_ipv4_lookup_mode_help);
152 : :
153 : 0 : len = strlen(conn->msg_out);
154 : 0 : conn->msg_out_len_max -= len;
155 : 0 : }
156 : :
157 : : void
158 : 0 : cmd_ipv4_lookup_route_add_ipv4_parsed(void *parsed_result, __rte_unused struct cmdline *cl,
159 : : void *data __rte_unused)
160 : : {
161 : : struct cmd_ipv4_lookup_route_add_ipv4_result *res = parsed_result;
162 : : struct route_ipv4_config config;
163 : : int rc = -EINVAL;
164 : :
165 : 0 : config.ip = rte_be_to_cpu_32(res->ip.addr.ipv4.s_addr);
166 : 0 : config.netmask = rte_be_to_cpu_32(res->mask.addr.ipv4.s_addr);
167 : 0 : config.via = rte_be_to_cpu_32(res->via_ip.addr.ipv4.s_addr);
168 : :
169 : 0 : rc = route_ip4_add(&config);
170 : 0 : if (rc < 0)
171 : 0 : printf(MSG_CMD_FAIL, res->ipv4_lookup);
172 : 0 : }
173 : :
174 : : void
175 : 0 : cmd_ipv4_lookup_mode_parsed(void *parsed_result, __rte_unused struct cmdline *cl,
176 : : void *data __rte_unused)
177 : : {
178 : : struct cmd_ipv4_lookup_mode_result *res = parsed_result;
179 : :
180 : 0 : if (!strcmp(res->lkup_mode, "lpm"))
181 : 0 : ip4_lookup_m = IP4_LOOKUP_LPM;
182 : 0 : else if (!strcmp(res->lkup_mode, "fib"))
183 : 0 : ip4_lookup_m = IP4_LOOKUP_FIB;
184 : : else
185 : 0 : printf(MSG_CMD_FAIL, res->ipv4_lookup);
186 : 0 : }
|