1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Vladimir Medvedkin <medvedkinv@gmail.com> 3 * Copyright(c) 2019 Intel Corporation 4 */ 5 6 #ifndef _RTE_RIB6_H_ 7 #define _RTE_RIB6_H_ 8 9 /** 10 * @file 11 * 12 * RTE rib6 library. 13 * 14 * Level compressed tree implementation for IPv6 Longest Prefix Match 15 */ 16 17 #include <rte_memcpy.h> 18 #include <rte_common.h> 19 #include <rte_ip6.h> 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 #define RTE_RIB6_IPV6_ADDR_SIZE (RTE_DEPRECATED(RTE_RIB6_IPV6_ADDR_SIZE) RTE_IPV6_ADDR_SIZE) 26 27 /** 28 * rte_rib6_get_nxt() flags 29 */ 30 enum { 31 /** flag to get all subroutes in a RIB tree */ 32 RTE_RIB6_GET_NXT_ALL, 33 /** flag to get first matched subroutes in a RIB tree */ 34 RTE_RIB6_GET_NXT_COVER 35 }; 36 37 struct rte_rib6; 38 struct rte_rib6_node; 39 40 /** RIB configuration structure */ 41 struct rte_rib6_conf { 42 /** 43 * Size of extension block inside rte_rib6_node. 44 * This space could be used to store additional user 45 * defined data. 46 */ 47 size_t ext_sz; 48 /* size of rte_rib6_node's pool */ 49 int max_nodes; 50 }; 51 52 /** 53 * Copy IPv6 address from one location to another 54 * 55 * @param dst 56 * pointer to the place to copy 57 * @param src 58 * pointer from where to copy 59 */ 60 static inline void rte_rib6_copy_addr(uint8_t *dst, const uint8_t *src) 61 __rte_deprecated_msg("use direct struct assignment"); 62 63 static inline void 64 rte_rib6_copy_addr(uint8_t *dst, const uint8_t *src) 65 { 66 if ((dst == NULL) || (src == NULL)) 67 return; 68 rte_memcpy(dst, src, RTE_IPV6_ADDR_SIZE); 69 } 70 71 /** 72 * Compare two IPv6 addresses 73 * 74 * @param ip1 75 * pointer to the first ipv6 address 76 * @param ip2 77 * pointer to the second ipv6 address 78 * 79 * @return 80 * 1 if equal 81 * 0 otherwise 82 */ 83 static inline int rte_rib6_is_equal(const uint8_t *ip1, const uint8_t *ip2) 84 __rte_deprecated_msg("use rte_ipv6_addr_eq"); 85 86 static inline int 87 rte_rib6_is_equal(const uint8_t *ip1, const uint8_t *ip2) { 88 int i; 89 90 if ((ip1 == NULL) || (ip2 == NULL)) 91 return 0; 92 for (i = 0; i < RTE_IPV6_ADDR_SIZE; i++) { 93 if (ip1[i] != ip2[i]) 94 return 0; 95 } 96 return 1; 97 } 98 99 /** 100 * Get 8-bit part of 128-bit IPv6 mask 101 * 102 * @param depth 103 * ipv6 prefix length 104 * @param byte 105 * position of a 8-bit chunk in the 128-bit mask 106 * 107 * @return 108 * 8-bit chunk of the 128-bit IPv6 mask 109 */ 110 static inline uint8_t get_msk_part(uint8_t depth, int byte) __rte_deprecated; 111 112 static inline uint8_t 113 get_msk_part(uint8_t depth, int byte) { 114 uint8_t part; 115 116 byte &= 0xf; 117 depth = RTE_MIN(depth, 128); 118 part = RTE_MAX((int16_t)depth - (byte * 8), 0); 119 part = (part > 8) ? 8 : part; 120 return (uint16_t)(~UINT8_MAX) >> part; 121 } 122 123 /** 124 * Lookup an IP into the RIB structure 125 * 126 * @param rib 127 * RIB object handle 128 * @param ip 129 * IP to be looked up in the RIB 130 * @return 131 * pointer to struct rte_rib6_node on success 132 * NULL otherwise 133 */ 134 struct rte_rib6_node * 135 rte_rib6_lookup(struct rte_rib6 *rib, 136 const struct rte_ipv6_addr *ip); 137 138 /** 139 * Lookup less specific route into the RIB structure 140 * 141 * @param ent 142 * Pointer to struct rte_rib6_node that represents target route 143 * @return 144 * pointer to struct rte_rib6_node that represents 145 * less specific route on success 146 * NULL otherwise 147 */ 148 struct rte_rib6_node * 149 rte_rib6_lookup_parent(struct rte_rib6_node *ent); 150 151 /** 152 * Provides exact mach lookup of the prefix into the RIB structure 153 * 154 * @param rib 155 * RIB object handle 156 * @param ip 157 * net to be looked up in the RIB 158 * @param depth 159 * prefix length 160 * @return 161 * pointer to struct rte_rib6_node on success 162 * NULL otherwise 163 */ 164 struct rte_rib6_node * 165 rte_rib6_lookup_exact(struct rte_rib6 *rib, 166 const struct rte_ipv6_addr *ip, uint8_t depth); 167 168 /** 169 * Retrieve next more specific prefix from the RIB 170 * that is covered by ip/depth supernet in an ascending order 171 * 172 * @param rib 173 * RIB object handle 174 * @param ip 175 * net address of supernet prefix that covers returned more specific prefixes 176 * @param depth 177 * supernet prefix length 178 * @param last 179 * pointer to the last returned prefix to get next prefix 180 * or 181 * NULL to get first more specific prefix 182 * @param flag 183 * -RTE_RIB6_GET_NXT_ALL 184 * get all prefixes from subtrie 185 * -RTE_RIB6_GET_NXT_COVER 186 * get only first more specific prefix even if it have more specifics 187 * @return 188 * pointer to the next more specific prefix 189 * NULL if there is no prefixes left 190 */ 191 struct rte_rib6_node * 192 rte_rib6_get_nxt(struct rte_rib6 *rib, 193 const struct rte_ipv6_addr *ip, 194 uint8_t depth, struct rte_rib6_node *last, int flag); 195 196 /** 197 * Remove prefix from the RIB 198 * 199 * @param rib 200 * RIB object handle 201 * @param ip 202 * net to be removed from the RIB 203 * @param depth 204 * prefix length 205 */ 206 void 207 rte_rib6_remove(struct rte_rib6 *rib, 208 const struct rte_ipv6_addr *ip, uint8_t depth); 209 210 /** 211 * Insert prefix into the RIB 212 * 213 * @param rib 214 * RIB object handle 215 * @param ip 216 * net to be inserted to the RIB 217 * @param depth 218 * prefix length 219 * @return 220 * pointer to new rte_rib6_node on success 221 * NULL otherwise 222 */ 223 struct rte_rib6_node * 224 rte_rib6_insert(struct rte_rib6 *rib, 225 const struct rte_ipv6_addr *ip, uint8_t depth); 226 227 /** 228 * Get an ip from rte_rib6_node 229 * 230 * @param node 231 * pointer to the rib6 node 232 * @param ip 233 * pointer to the ipv6 to save 234 * @return 235 * 0 on success 236 * -1 on failure with rte_errno indicating reason for failure. 237 */ 238 int 239 rte_rib6_get_ip(const struct rte_rib6_node *node, 240 struct rte_ipv6_addr *ip); 241 242 /** 243 * Get a depth from rte_rib6_node 244 * 245 * @param node 246 * pointer to the rib6 node 247 * @param depth 248 * pointer to the depth to save 249 * @return 250 * 0 on success 251 * -1 on failure with rte_errno indicating reason for failure. 252 */ 253 int 254 rte_rib6_get_depth(const struct rte_rib6_node *node, uint8_t *depth); 255 256 /** 257 * Get ext field from the rte_rib6_node 258 * It is caller responsibility to make sure there are necessary space 259 * for the ext field inside rib6 node. 260 * 261 * @param node 262 * pointer to the rte_rib6_node 263 * @return 264 * pointer to the ext 265 */ 266 void * 267 rte_rib6_get_ext(struct rte_rib6_node *node); 268 269 /** 270 * Get nexthop from the rte_rib6_node 271 * 272 * @param node 273 * pointer to the rib6 node 274 * @param nh 275 * pointer to the nexthop to save 276 * @return 277 * 0 on success 278 * -1 on failure, with rte_errno indicating reason for failure. 279 */ 280 int 281 rte_rib6_get_nh(const struct rte_rib6_node *node, uint64_t *nh); 282 283 /** 284 * Set nexthop into the rte_rib6_node 285 * 286 * @param node 287 * pointer to the rib6 node 288 * @param nh 289 * nexthop value to set to the rib6 node 290 * @return 291 * 0 on success 292 * -1 on failure, with rte_errno indicating reason for failure. 293 */ 294 int 295 rte_rib6_set_nh(struct rte_rib6_node *node, uint64_t nh); 296 297 /** 298 * Create RIB 299 * 300 * @param name 301 * RIB name 302 * @param socket_id 303 * NUMA socket ID for RIB table memory allocation 304 * @param conf 305 * Structure containing the configuration 306 * @return 307 * Pointer to RIB object on success 308 * NULL otherwise with rte_errno indicating reason for failure. 309 */ 310 struct rte_rib6 * 311 rte_rib6_create(const char *name, int socket_id, 312 const struct rte_rib6_conf *conf); 313 314 /** 315 * Find an existing RIB object and return a pointer to it. 316 * 317 * @param name 318 * Name of the rib object as passed to rte_rib6_create() 319 * @return 320 * Pointer to RIB object on success 321 * NULL otherwise with rte_errno indicating reason for failure. 322 */ 323 struct rte_rib6 * 324 rte_rib6_find_existing(const char *name); 325 326 /** 327 * Free an RIB object. 328 * 329 * @param rib 330 * RIB object handle created with rte_rib6_create(). 331 * If rib is NULL, no operation is performed. 332 */ 333 void 334 rte_rib6_free(struct rte_rib6 *rib); 335 336 #ifdef __cplusplus 337 } 338 #endif 339 340 #endif /* _RTE_RIB6_H_ */ 341