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