xref: /dpdk/lib/rib/rte_rib6.h (revision 59b993151ff57e9e8b0fdb1d4b57913243b605fa)
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