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 : : #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 : : static const char
23 : : cmd_ipv6_lookup_mode_help[] = "ipv6_lookup mode <lpm|fib>";
24 : :
25 : : struct ip6_route route6 = TAILQ_HEAD_INITIALIZER(route6);
26 : :
27 : : enum ip6_lookup_mode ip6_lookup_m = IP6_LOOKUP_LPM;
28 : :
29 : : void
30 : 0 : route_ip6_list_clean(void)
31 : : {
32 : : struct route_ipv6_config *route;
33 : :
34 : 0 : while (!TAILQ_EMPTY(&route6)) {
35 : : route = TAILQ_FIRST(&route6);
36 : 0 : TAILQ_REMOVE(&route6, route, next);
37 : : }
38 : 0 : }
39 : :
40 : : static struct route_ipv6_config *
41 : 0 : find_route6_entry(struct route_ipv6_config *route)
42 : : {
43 : : struct route_ipv6_config *ipv6route;
44 : :
45 : 0 : TAILQ_FOREACH(ipv6route, &route6, next) {
46 : 0 : if (!memcmp(ipv6route, route, sizeof(*route)))
47 : 0 : return ipv6route;
48 : : }
49 : : return NULL;
50 : : }
51 : :
52 : : static int
53 : 0 : route6_rewirte_table_update(struct route_ipv6_config *ipv6route)
54 : : {
55 : : uint8_t depth;
56 : : int portid;
57 : : int rc;
58 : :
59 : 0 : portid = ethdev_portid_by_ip6(&ipv6route->gateway, &ipv6route->mask);
60 : 0 : if (portid < 0) {
61 : : printf("Invalid portid found to install the route\n");
62 : 0 : return portid;
63 : : }
64 : : depth = rte_ipv6_mask_depth(&ipv6route->mask);
65 : :
66 : 0 : if (ip6_lookup_m == IP6_LOOKUP_FIB)
67 : 0 : rc = rte_node_ip6_fib_route_add(&ipv6route->ip, depth, portid,
68 : : RTE_NODE_IP6_LOOKUP_NEXT_REWRITE);
69 : : else
70 : 0 : rc = rte_node_ip6_route_add(&ipv6route->ip, depth, portid,
71 : : RTE_NODE_IP6_LOOKUP_NEXT_REWRITE);
72 : :
73 : : return rc;
74 : : }
75 : :
76 : : static int
77 : 0 : route_ip6_add(struct route_ipv6_config *route)
78 : : {
79 : : struct route_ipv6_config *ipv6route;
80 : : int rc = -EINVAL;
81 : :
82 : 0 : ipv6route = find_route6_entry(route);
83 : 0 : if (!ipv6route) {
84 : 0 : ipv6route = malloc(sizeof(struct route_ipv6_config));
85 : 0 : if (!ipv6route)
86 : : return -ENOMEM;
87 : : } else {
88 : : return 0;
89 : : }
90 : :
91 : 0 : ipv6route->ip = route->ip;
92 : 0 : ipv6route->mask = route->mask;
93 : 0 : ipv6route->gateway = route->gateway;
94 : 0 : ipv6route->is_used = true;
95 : :
96 : 0 : if (!graph_status_get())
97 : 0 : goto exit;
98 : :
99 : 0 : rc = route6_rewirte_table_update(ipv6route);
100 : 0 : if (rc)
101 : 0 : goto free;
102 : :
103 : 0 : exit:
104 : 0 : TAILQ_INSERT_TAIL(&route6, ipv6route, next);
105 : 0 : return 0;
106 : : free:
107 : 0 : free(ipv6route);
108 : 0 : return rc;
109 : : }
110 : :
111 : : int
112 : 0 : route_ip6_add_to_lookup(void)
113 : : {
114 : : struct route_ipv6_config *route = NULL;
115 : : int rc = -EINVAL;
116 : :
117 : 0 : TAILQ_FOREACH(route, &route6, next) {
118 : 0 : rc = route6_rewirte_table_update(route);
119 : 0 : if (rc < 0)
120 : 0 : return rc;
121 : : }
122 : :
123 : : return 0;
124 : : }
125 : :
126 : : void
127 : 0 : cmd_help_ipv6_lookup_parsed(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl,
128 : : __rte_unused void *data)
129 : : {
130 : : size_t len;
131 : :
132 : 0 : len = strlen(conn->msg_out);
133 : 0 : conn->msg_out += len;
134 : 0 : snprintf(conn->msg_out, conn->msg_out_len_max, "\n%s\n%s\n%s\n",
135 : : "--------------------------- ipv6_lookup command help ---------------------------",
136 : : cmd_ipv6_lookup_help, cmd_ipv6_lookup_mode_help);
137 : :
138 : 0 : len = strlen(conn->msg_out);
139 : 0 : conn->msg_out_len_max -= len;
140 : 0 : }
141 : :
142 : : void
143 : 0 : cmd_ipv6_lookup_route_add_ipv6_parsed(void *parsed_result, __rte_unused struct cmdline *cl,
144 : : void *data __rte_unused)
145 : : {
146 : : struct cmd_ipv6_lookup_route_add_ipv6_result *res = parsed_result;
147 : 0 : struct route_ipv6_config config = {
148 : : .ip = res->ip.addr.ipv6,
149 : : .mask = res->mask.addr.ipv6,
150 : : .gateway = res->via_ip.addr.ipv6,
151 : : };
152 : : int rc;
153 : :
154 : 0 : rc = route_ip6_add(&config);
155 : 0 : if (rc)
156 : 0 : printf(MSG_CMD_FAIL, res->ipv6_lookup);
157 : 0 : }
158 : :
159 : : void
160 : 0 : cmd_ipv6_lookup_mode_parsed(void *parsed_result, __rte_unused struct cmdline *cl,
161 : : void *data __rte_unused)
162 : : {
163 : : struct cmd_ipv6_lookup_mode_result *res = parsed_result;
164 : :
165 : 0 : if (!strcmp(res->lkup_mode, "lpm"))
166 : 0 : ip6_lookup_m = IP6_LOOKUP_LPM;
167 : 0 : else if (!strcmp(res->lkup_mode, "fib"))
168 : 0 : ip6_lookup_m = IP6_LOOKUP_FIB;
169 : : else
170 : 0 : printf(MSG_CMD_FAIL, res->ipv6_lookup);
171 : 0 : }
|