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