net/virtio: fix incorrect cast of void *
[dpdk.git] / 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  * @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
26 extern "C" {
27 #endif
28
29 #define RTE_RIB6_IPV6_ADDR_SIZE 16
30
31 /**
32  * rte_rib6_get_nxt() flags
33  */
34 enum {
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
41 struct rte_rib6;
42 struct rte_rib6_node;
43
44 /** RIB configuration structure */
45 struct 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  */
64 static inline void
65 rte_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  */
84 static inline int
85 rte_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  */
108 static inline uint8_t
109 get_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
131 struct rte_rib6_node *
132 rte_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
146 struct rte_rib6_node *
147 rte_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
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);
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
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);
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
207 void
208 rte_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
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);
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
241 int
242 rte_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
257 int
258 rte_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
271 void *
272 rte_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
286 int
287 rte_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
301 int
302 rte_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
318 struct rte_rib6 *
319 rte_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
332 struct rte_rib6 *
333 rte_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
344 void
345 rte_rib6_free(struct rte_rib6 *rib);
346
347 #ifdef __cplusplus
348 }
349 #endif
350
351 #endif /* _RTE_RIB6_H_ */