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