build/windows: remove separate list of libs
[dpdk.git] / lib / rib / rte_rib6.h
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_compat.h>
19 #include <rte_common.h>
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 #define RTE_RIB6_IPV6_ADDR_SIZE 16
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_rib_node.
44          * This space could be used to store additional user
45          * defined data.
46          */
47         size_t  ext_sz;
48         /* size of rte_rib_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
61 rte_rib6_copy_addr(uint8_t *dst, const uint8_t *src)
62 {
63         if ((dst == NULL) || (src == NULL))
64                 return;
65         rte_memcpy(dst, src, RTE_RIB6_IPV6_ADDR_SIZE);
66 }
67
68 /**
69  * Compare two IPv6 addresses
70  *
71  * @param ip1
72  *  pointer to the first ipv6 address
73  * @param ip2
74  *  pointer to the second ipv6 address
75  *
76  * @return
77  *  1 if equal
78  *  0 otherwise
79  */
80 static inline int
81 rte_rib6_is_equal(const uint8_t *ip1, const uint8_t *ip2) {
82         int i;
83
84         if ((ip1 == NULL) || (ip2 == NULL))
85                 return 0;
86         for (i = 0; i < RTE_RIB6_IPV6_ADDR_SIZE; i++) {
87                 if (ip1[i] != ip2[i])
88                         return 0;
89         }
90         return 1;
91 }
92
93 /**
94  * Get 8-bit part of 128-bit IPv6 mask
95  *
96  * @param depth
97  *  ipv6 prefix length
98  * @param byte
99  *  position of a 8-bit chunk in the 128-bit mask
100  *
101  * @return
102  *  8-bit chunk of the 128-bit IPv6 mask
103  */
104 static inline uint8_t
105 get_msk_part(uint8_t depth, int byte) {
106         uint8_t part;
107
108         byte &= 0xf;
109         depth = RTE_MIN(depth, 128);
110         part = RTE_MAX((int16_t)depth - (byte * 8), 0);
111         part = (part > 8) ? 8 : part;
112         return (uint16_t)(~UINT8_MAX) >> part;
113 }
114
115 /**
116  * Lookup an IP into the RIB structure
117  *
118  * @param rib
119  *  RIB object handle
120  * @param ip
121  *  IP to be looked up in the RIB
122  * @return
123  *  pointer to struct rte_rib6_node on success
124  *  NULL otherwise
125  */
126 struct rte_rib6_node *
127 rte_rib6_lookup(struct rte_rib6 *rib,
128         const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE]);
129
130 /**
131  * Lookup less specific route into the RIB structure
132  *
133  * @param ent
134  *  Pointer to struct rte_rib6_node that represents target route
135  * @return
136  *  pointer to struct rte_rib6_node that represents
137  *   less specific route on success
138  *  NULL otherwise
139  */
140 struct rte_rib6_node *
141 rte_rib6_lookup_parent(struct rte_rib6_node *ent);
142
143 /**
144  * Provides exact mach lookup of the prefix into the RIB structure
145  *
146  * @param rib
147  *  RIB object handle
148  * @param ip
149  *  net to be looked up in the RIB
150  * @param depth
151  *  prefix length
152  * @return
153  *  pointer to struct rte_rib6_node on success
154  *  NULL otherwise
155  */
156 struct rte_rib6_node *
157 rte_rib6_lookup_exact(struct rte_rib6 *rib,
158         const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE], uint8_t depth);
159
160 /**
161  * Retrieve next more specific prefix from the RIB
162  * that is covered by ip/depth supernet in an ascending order
163  *
164  * @param rib
165  *  RIB object handle
166  * @param ip
167  *  net address of supernet prefix that covers returned more specific prefixes
168  * @param depth
169  *  supernet prefix length
170  * @param last
171  *   pointer to the last returned prefix to get next prefix
172  *   or
173  *   NULL to get first more specific prefix
174  * @param flag
175  *  -RTE_RIB6_GET_NXT_ALL
176  *   get all prefixes from subtrie
177  *  -RTE_RIB6_GET_NXT_COVER
178  *   get only first more specific prefix even if it have more specifics
179  * @return
180  *  pointer to the next more specific prefix
181  *  NULL if there is no prefixes left
182  */
183 struct rte_rib6_node *
184 rte_rib6_get_nxt(struct rte_rib6 *rib,
185         const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE],
186         uint8_t depth, struct rte_rib6_node *last, int flag);
187
188 /**
189  * Remove prefix from the RIB
190  *
191  * @param rib
192  *  RIB object handle
193  * @param ip
194  *  net to be removed from the RIB
195  * @param depth
196  *  prefix length
197  */
198 void
199 rte_rib6_remove(struct rte_rib6 *rib,
200         const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE], uint8_t depth);
201
202 /**
203  * Insert prefix into the RIB
204  *
205  * @param rib
206  *  RIB object handle
207  * @param ip
208  *  net to be inserted to the RIB
209  * @param depth
210  *  prefix length
211  * @return
212  *  pointer to new rte_rib6_node on success
213  *  NULL otherwise
214  */
215 struct rte_rib6_node *
216 rte_rib6_insert(struct rte_rib6 *rib,
217         const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE], uint8_t depth);
218
219 /**
220  * Get an ip from rte_rib6_node
221  *
222  * @param node
223  *  pointer to the rib6 node
224  * @param ip
225  *  pointer to the ipv6 to save
226  * @return
227  *  0 on success
228  *  -1 on failure with rte_errno indicating reason for failure.
229  */
230 int
231 rte_rib6_get_ip(const struct rte_rib6_node *node,
232                 uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE]);
233
234 /**
235  * Get a depth from rte_rib6_node
236  *
237  * @param node
238  *  pointer to the rib6 node
239  * @param depth
240  *  pointer to the depth to save
241  * @return
242  *  0 on success
243  *  -1 on failure with rte_errno indicating reason for failure.
244  */
245 int
246 rte_rib6_get_depth(const struct rte_rib6_node *node, uint8_t *depth);
247
248 /**
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.
252  *
253  * @param node
254  *  pointer to the rte_rib6_node
255  * @return
256  *  pointer to the ext
257  */
258 void *
259 rte_rib6_get_ext(struct rte_rib6_node *node);
260
261 /**
262  * Get nexthop from the rte_rib6_node
263  *
264  * @param node
265  *  pointer to the rib6 node
266  * @param nh
267  *  pointer to the nexthop to save
268  * @return
269  *  0 on success
270  *  -1 on failure, with rte_errno indicating reason for failure.
271  */
272 int
273 rte_rib6_get_nh(const struct rte_rib6_node *node, uint64_t *nh);
274
275 /**
276  * Set nexthop into the rte_rib6_node
277  *
278  * @param node
279  *  pointer to the rib6 node
280  * @param nh
281  *  nexthop value to set to the rib6 node
282  * @return
283  *  0 on success
284  *  -1 on failure, with rte_errno indicating reason for failure.
285  */
286 int
287 rte_rib6_set_nh(struct rte_rib6_node *node, uint64_t nh);
288
289 /**
290  * Create RIB
291  *
292  * @param name
293  *  RIB name
294  * @param socket_id
295  *  NUMA socket ID for RIB table memory allocation
296  * @param conf
297  *  Structure containing the configuration
298  * @return
299  *  Pointer to RIB object on success
300  *  NULL otherwise with rte_errno indicating reason for failure.
301  */
302 struct rte_rib6 *
303 rte_rib6_create(const char *name, int socket_id,
304                 const struct rte_rib6_conf *conf);
305
306 /**
307  * Find an existing RIB object and return a pointer to it.
308  *
309  * @param name
310  *  Name of the rib object as passed to rte_rib_create()
311  * @return
312  *  Pointer to RIB object on success
313  *  NULL otherwise with rte_errno indicating reason for failure.
314  */
315 struct rte_rib6 *
316 rte_rib6_find_existing(const char *name);
317
318 /**
319  * Free an RIB object.
320  *
321  * @param rib
322  *   RIB object handle
323  * @return
324  *   None
325  */
326 void
327 rte_rib6_free(struct rte_rib6 *rib);
328
329 #ifdef __cplusplus
330 }
331 #endif
332
333 #endif /* _RTE_RIB6_H_ */