1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Vladimir Medvedkin <medvedkinv@gmail.com>
3 * Copyright(c) 2019 Intel Corporation
11 * Level compressed tree implementation for IPv6 Longest Prefix Match
14 #include <rte_memcpy.h>
15 #include <rte_compat.h>
17 #define RTE_RIB6_IPV6_ADDR_SIZE 16
20 * rte_rib6_get_nxt() flags
23 /** flag to get all subroutes in a RIB tree */
25 /** flag to get first matched subroutes in a RIB tree */
26 RTE_RIB6_GET_NXT_COVER
32 /** RIB configuration structure */
33 struct rte_rib6_conf {
35 * Size of extension block inside rte_rib_node.
36 * This space could be used to store additional user
40 /* size of rte_rib_node's pool */
45 * Copy IPv6 address from one location to another
48 * pointer to the place to copy
50 * pointer from where to copy
53 rte_rib6_copy_addr(uint8_t *dst, const uint8_t *src)
55 if ((dst == NULL) || (src == NULL))
57 rte_memcpy(dst, src, RTE_RIB6_IPV6_ADDR_SIZE);
61 * Compare two IPv6 addresses
64 * pointer to the first ipv6 address
66 * pointer to the second ipv6 address
73 rte_rib6_is_equal(uint8_t *ip1, uint8_t *ip2) {
76 if ((ip1 == NULL) || (ip2 == NULL))
78 for (i = 0; i < RTE_RIB6_IPV6_ADDR_SIZE; i++) {
86 * Get 8-bit part of 128-bit IPv6 mask
91 * position of a 8-bit chunk in the 128-bit mask
94 * 8-bit chunk of the 128-bit IPv6 mask
97 get_msk_part(uint8_t depth, int byte) {
101 depth = RTE_MIN(depth, 128);
102 part = RTE_MAX((int16_t)depth - (byte * 8), 0);
103 part = (part > 8) ? 8 : part;
104 return (uint16_t)(~UINT8_MAX) >> part;
108 * Lookup an IP into the RIB structure
113 * IP to be looked up in the RIB
115 * pointer to struct rte_rib6_node on success
119 struct rte_rib6_node *
120 rte_rib6_lookup(struct rte_rib6 *rib,
121 const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE]);
124 * Lookup less specific route into the RIB structure
127 * Pointer to struct rte_rib6_node that represents target route
129 * pointer to struct rte_rib6_node that represents
130 * less specific route on success
134 struct rte_rib6_node *
135 rte_rib6_lookup_parent(struct rte_rib6_node *ent);
138 * Provides exact mach lookup of the prefix into the RIB structure
143 * net to be looked up in the RIB
147 * pointer to struct rte_rib6_node on success
151 struct rte_rib6_node *
152 rte_rib6_lookup_exact(struct rte_rib6 *rib,
153 const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE], uint8_t depth);
156 * Retrieve next more specific prefix from the RIB
157 * that is covered by ip/depth supernet in an ascending order
162 * net address of supernet prefix that covers returned more specific prefixes
164 * supernet prefix length
166 * pointer to the last returned prefix to get next prefix
168 * NULL to get first more specific prefix
170 * -RTE_RIB6_GET_NXT_ALL
171 * get all prefixes from subtrie
172 * -RTE_RIB6_GET_NXT_COVER
173 * get only first more specific prefix even if it have more specifics
175 * pointer to the next more specific prefix
176 * NULL if there is no prefixes left
179 struct rte_rib6_node *
180 rte_rib6_get_nxt(struct rte_rib6 *rib,
181 const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE],
182 uint8_t depth, struct rte_rib6_node *last, int flag);
185 * Remove prefix from the RIB
190 * net to be removed from the RIB
196 rte_rib6_remove(struct rte_rib6 *rib,
197 const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE], uint8_t depth);
200 * Insert prefix into the RIB
205 * net to be inserted to the RIB
209 * pointer to new rte_rib6_node on success
213 struct rte_rib6_node *
214 rte_rib6_insert(struct rte_rib6 *rib,
215 const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE], uint8_t depth);
218 * Get an ip from rte_rib6_node
221 * pointer to the rib6 node
223 * pointer to the ipv6 to save
226 * -1 on failure with rte_errno indicating reason for failure.
230 rte_rib6_get_ip(struct rte_rib6_node *node,
231 uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE]);
234 * Get a depth from rte_rib6_node
237 * pointer to the rib6 node
239 * pointer to the depth to save
242 * -1 on failure with rte_errno indicating reason for failure.
246 rte_rib6_get_depth(struct rte_rib6_node *node, uint8_t *depth);
249 * Get ext field from the rte_rib6_node
250 * It is caller responsibility to make sure there are necessary space
251 * for the ext field inside rib6 node.
254 * pointer to the rte_rib6_node
260 rte_rib6_get_ext(struct rte_rib6_node *node);
263 * Get nexthop from the rte_rib6_node
266 * pointer to the rib6 node
268 * pointer to the nexthop to save
271 * -1 on failure, with rte_errno indicating reason for failure.
275 rte_rib6_get_nh(struct rte_rib6_node *node, uint64_t *nh);
278 * Set nexthop into the rte_rib6_node
281 * pointer to the rib6 node
283 * nexthop value to set to the rib6 node
286 * -1 on failure, with rte_errno indicating reason for failure.
290 rte_rib6_set_nh(struct rte_rib6_node *node, uint64_t nh);
298 * NUMA socket ID for RIB table memory allocation
300 * Structure containing the configuration
302 * Pointer to RIB object on success
303 * NULL otherwise with rte_errno indicating reason for failure.
307 rte_rib6_create(const char *name, int socket_id, struct rte_rib6_conf *conf);
310 * Find an existing RIB object and return a pointer to it.
313 * Name of the rib object as passed to rte_rib_create()
315 * Pointer to RIB object on success
316 * NULL otherwise with rte_errno indicating reason for failure.
320 rte_rib6_find_existing(const char *name);
323 * Free an RIB object.
332 rte_rib6_free(struct rte_rib6 *rib);
334 #endif /* _RTE_RIB_H_ */