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