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