1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Vladimir Medvedkin <[email protected]>
3 * Copyright(c) 2019 Intel Corporation
4 */
5
6 #ifndef _RTE_RIB_H_
7 #define _RTE_RIB_H_
8
9 /**
10 * @file
11 *
12 * RTE RIB 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 IPv4 Longest Prefix Match
19 */
20
21 #include <rte_compat.h>
22
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26
27 /**
28 * rte_rib_get_nxt() flags
29 */
30 enum {
31 /** flag to get all subroutes in a RIB tree */
32 RTE_RIB_GET_NXT_ALL,
33 /** flag to get first matched subroutes in a RIB tree */
34 RTE_RIB_GET_NXT_COVER
35 };
36
37 struct rte_rib;
38 struct rte_rib_node;
39
40 /** RIB configuration structure */
41 struct rte_rib_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 * Get an IPv4 mask from prefix length
54 * It is caller responsibility to make sure depth is not bigger than 32
55 *
56 * @param depth
57 * prefix length
58 * @return
59 * IPv4 mask
60 */
61 static inline uint32_t
rte_rib_depth_to_mask(uint8_t depth)62 rte_rib_depth_to_mask(uint8_t depth)
63 {
64 return (uint32_t)(UINT64_MAX << (32 - depth));
65 }
66
67 /**
68 * Lookup an IP into the RIB structure
69 *
70 * @param rib
71 * RIB object handle
72 * @param ip
73 * IP to be looked up in the RIB
74 * @return
75 * pointer to struct rte_rib_node on success
76 * NULL otherwise
77 */
78 __rte_experimental
79 struct rte_rib_node *
80 rte_rib_lookup(struct rte_rib *rib, uint32_t ip);
81
82 /**
83 * Lookup less specific route into the RIB structure
84 *
85 * @param ent
86 * Pointer to struct rte_rib_node that represents target route
87 * @return
88 * pointer to struct rte_rib_node that represents
89 * less specific route on success
90 * NULL otherwise
91 */
92 __rte_experimental
93 struct rte_rib_node *
94 rte_rib_lookup_parent(struct rte_rib_node *ent);
95
96 /**
97 * Lookup prefix into the RIB structure
98 *
99 * @param rib
100 * RIB object handle
101 * @param ip
102 * net to be looked up in the RIB
103 * @param depth
104 * prefix length
105 * @return
106 * pointer to struct rte_rib_node on success
107 * NULL otherwise
108 */
109 __rte_experimental
110 struct rte_rib_node *
111 rte_rib_lookup_exact(struct rte_rib *rib, uint32_t ip, uint8_t depth);
112
113 /**
114 * Retrieve next more specific prefix from the RIB
115 * that is covered by ip/depth supernet in an ascending order
116 *
117 * @param rib
118 * RIB object handle
119 * @param ip
120 * net address of supernet prefix that covers returned more specific prefixes
121 * @param depth
122 * supernet prefix length
123 * @param last
124 * pointer to the last returned prefix to get next prefix
125 * or
126 * NULL to get first more specific prefix
127 * @param flag
128 * -RTE_RIB_GET_NXT_ALL
129 * get all prefixes from subtrie
130 * -RTE_RIB_GET_NXT_COVER
131 * get only first more specific prefix even if it have more specifics
132 * @return
133 * pointer to the next more specific prefix
134 * NULL if there is no prefixes left
135 */
136 __rte_experimental
137 struct rte_rib_node *
138 rte_rib_get_nxt(struct rte_rib *rib, uint32_t ip, uint8_t depth,
139 struct rte_rib_node *last, int flag);
140
141 /**
142 * Remove prefix from the RIB
143 *
144 * @param rib
145 * RIB object handle
146 * @param ip
147 * net to be removed from the RIB
148 * @param depth
149 * prefix length
150 */
151 __rte_experimental
152 void
153 rte_rib_remove(struct rte_rib *rib, uint32_t ip, uint8_t depth);
154
155 /**
156 * Insert prefix into the RIB
157 *
158 * @param rib
159 * RIB object handle
160 * @param ip
161 * net to be inserted to the RIB
162 * @param depth
163 * prefix length
164 * @return
165 * pointer to new rte_rib_node on success
166 * NULL otherwise
167 */
168 __rte_experimental
169 struct rte_rib_node *
170 rte_rib_insert(struct rte_rib *rib, uint32_t ip, uint8_t depth);
171
172 /**
173 * Get an ip from rte_rib_node
174 *
175 * @param node
176 * pointer to the rib node
177 * @param ip
178 * pointer to the ip to save
179 * @return
180 * 0 on success.
181 * -1 on failure with rte_errno indicating reason for failure.
182 */
183 __rte_experimental
184 int
185 rte_rib_get_ip(const struct rte_rib_node *node, uint32_t *ip);
186
187 /**
188 * Get a depth from rte_rib_node
189 *
190 * @param node
191 * pointer to the rib node
192 * @param depth
193 * pointer to the depth to save
194 * @return
195 * 0 on success.
196 * -1 on failure with rte_errno indicating reason for failure.
197 */
198 __rte_experimental
199 int
200 rte_rib_get_depth(const struct rte_rib_node *node, uint8_t *depth);
201
202 /**
203 * Get ext field from the rib node
204 * It is caller responsibility to make sure there are necessary space
205 * for the ext field inside rib node.
206 *
207 * @param node
208 * pointer to the rib node
209 * @return
210 * pointer to the ext
211 */
212 __rte_experimental
213 void *
214 rte_rib_get_ext(struct rte_rib_node *node);
215
216 /**
217 * Get nexthop from the rib node
218 *
219 * @param node
220 * pointer to the rib node
221 * @param nh
222 * pointer to the nexthop to save
223 * @return
224 * 0 on success.
225 * -1 on failure with rte_errno indicating reason for failure.
226 */
227 __rte_experimental
228 int
229 rte_rib_get_nh(const struct rte_rib_node *node, uint64_t *nh);
230
231 /**
232 * Set nexthop into the rib node
233 *
234 * @param node
235 * pointer to the rib node
236 * @param nh
237 * nexthop value to set to the rib node
238 * @return
239 * 0 on success.
240 * -1 on failure with rte_errno indicating reason for failure.
241 */
242 __rte_experimental
243 int
244 rte_rib_set_nh(struct rte_rib_node *node, uint64_t nh);
245
246 /**
247 * Create RIB
248 *
249 * @param name
250 * RIB name
251 * @param socket_id
252 * NUMA socket ID for RIB table memory allocation
253 * @param conf
254 * Structure containing the configuration
255 * @return
256 * Handle to RIB object on success
257 * NULL otherwise with rte_errno indicating reason for failure.
258 */
259 __rte_experimental
260 struct rte_rib *
261 rte_rib_create(const char *name, int socket_id,
262 const struct rte_rib_conf *conf);
263
264 /**
265 * Find an existing RIB object and return a pointer to it.
266 *
267 * @param name
268 * Name of the rib object as passed to rte_rib_create()
269 * @return
270 * Pointer to RIB object on success
271 * NULL otherwise with rte_errno indicating reason for failure.
272 */
273 __rte_experimental
274 struct rte_rib *
275 rte_rib_find_existing(const char *name);
276
277 /**
278 * Free an RIB object.
279 *
280 * @param rib
281 * RIB object handle
282 * @return
283 * None
284 */
285 __rte_experimental
286 void
287 rte_rib_free(struct rte_rib *rib);
288
289 #ifdef __cplusplus
290 }
291 #endif
292
293 #endif /* _RTE_RIB_H_ */
294