1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Vladimir Medvedkin <medvedkinv@gmail.com>
3 * Copyright(c) 2019 Intel Corporation
16 * All functions in this file may be changed or removed without prior notice.
18 * Level compressed tree implementation for IPv6 Longest Prefix Match
21 #include <rte_memcpy.h>
22 #include <rte_compat.h>
23 #include <rte_common.h>
29 #define RTE_RIB6_IPV6_ADDR_SIZE 16
32 * rte_rib6_get_nxt() flags
35 /** flag to get all subroutes in a RIB tree */
37 /** flag to get first matched subroutes in a RIB tree */
38 RTE_RIB6_GET_NXT_COVER
44 /** RIB configuration structure */
45 struct rte_rib6_conf {
47 * Size of extension block inside rte_rib_node.
48 * This space could be used to store additional user
52 /* size of rte_rib_node's pool */
57 * Copy IPv6 address from one location to another
60 * pointer to the place to copy
62 * pointer from where to copy
65 rte_rib6_copy_addr(uint8_t *dst, const uint8_t *src)
67 if ((dst == NULL) || (src == NULL))
69 rte_memcpy(dst, src, RTE_RIB6_IPV6_ADDR_SIZE);
73 * Compare two IPv6 addresses
76 * pointer to the first ipv6 address
78 * pointer to the second ipv6 address
85 rte_rib6_is_equal(const uint8_t *ip1, const uint8_t *ip2) {
88 if ((ip1 == NULL) || (ip2 == NULL))
90 for (i = 0; i < RTE_RIB6_IPV6_ADDR_SIZE; i++) {
98 * Get 8-bit part of 128-bit IPv6 mask
103 * position of a 8-bit chunk in the 128-bit mask
106 * 8-bit chunk of the 128-bit IPv6 mask
108 static inline uint8_t
109 get_msk_part(uint8_t depth, int byte) {
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;
120 * Lookup an IP into the RIB structure
125 * IP to be looked up in the RIB
127 * pointer to struct rte_rib6_node on success
131 struct rte_rib6_node *
132 rte_rib6_lookup(struct rte_rib6 *rib,
133 const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE]);
136 * Lookup less specific route into the RIB structure
139 * Pointer to struct rte_rib6_node that represents target route
141 * pointer to struct rte_rib6_node that represents
142 * less specific route on success
146 struct rte_rib6_node *
147 rte_rib6_lookup_parent(struct rte_rib6_node *ent);
150 * Provides exact mach lookup of the prefix into the RIB structure
155 * net to be looked up in the RIB
159 * pointer to struct rte_rib6_node on success
163 struct rte_rib6_node *
164 rte_rib6_lookup_exact(struct rte_rib6 *rib,
165 const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE], uint8_t depth);
168 * Retrieve next more specific prefix from the RIB
169 * that is covered by ip/depth supernet in an ascending order
174 * net address of supernet prefix that covers returned more specific prefixes
176 * supernet prefix length
178 * pointer to the last returned prefix to get next prefix
180 * NULL to get first more specific prefix
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
187 * pointer to the next more specific prefix
188 * NULL if there is no prefixes left
191 struct rte_rib6_node *
192 rte_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);
197 * Remove prefix from the RIB
202 * net to be removed from the RIB
208 rte_rib6_remove(struct rte_rib6 *rib,
209 const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE], uint8_t depth);
212 * Insert prefix into the RIB
217 * net to be inserted to the RIB
221 * pointer to new rte_rib6_node on success
225 struct rte_rib6_node *
226 rte_rib6_insert(struct rte_rib6 *rib,
227 const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE], uint8_t depth);
230 * Get an ip from rte_rib6_node
233 * pointer to the rib6 node
235 * pointer to the ipv6 to save
238 * -1 on failure with rte_errno indicating reason for failure.
242 rte_rib6_get_ip(const struct rte_rib6_node *node,
243 uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE]);
246 * Get a depth from rte_rib6_node
249 * pointer to the rib6 node
251 * pointer to the depth to save
254 * -1 on failure with rte_errno indicating reason for failure.
258 rte_rib6_get_depth(const struct rte_rib6_node *node, uint8_t *depth);
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.
266 * pointer to the rte_rib6_node
272 rte_rib6_get_ext(struct rte_rib6_node *node);
275 * Get nexthop from the rte_rib6_node
278 * pointer to the rib6 node
280 * pointer to the nexthop to save
283 * -1 on failure, with rte_errno indicating reason for failure.
287 rte_rib6_get_nh(const struct rte_rib6_node *node, uint64_t *nh);
290 * Set nexthop into the rte_rib6_node
293 * pointer to the rib6 node
295 * nexthop value to set to the rib6 node
298 * -1 on failure, with rte_errno indicating reason for failure.
302 rte_rib6_set_nh(struct rte_rib6_node *node, uint64_t nh);
310 * NUMA socket ID for RIB table memory allocation
312 * Structure containing the configuration
314 * Pointer to RIB object on success
315 * NULL otherwise with rte_errno indicating reason for failure.
319 rte_rib6_create(const char *name, int socket_id,
320 const struct rte_rib6_conf *conf);
323 * Find an existing RIB object and return a pointer to it.
326 * Name of the rib object as passed to rte_rib_create()
328 * Pointer to RIB object on success
329 * NULL otherwise with rte_errno indicating reason for failure.
333 rte_rib6_find_existing(const char *name);
336 * Free an RIB object.
345 rte_rib6_free(struct rte_rib6 *rib);
351 #endif /* _RTE_RIB6_H_ */