]> git.proxmox.com Git - mirror_frr.git/blob - lib/table.h
bgpd: Show FQDN in `show [ip] bgp` output
[mirror_frr.git] / lib / table.h
1 /*
2 * Routing Table
3 * Copyright (C) 1998 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #ifndef _ZEBRA_TABLE_H
23 #define _ZEBRA_TABLE_H
24
25 #include "memory.h"
26 #include "hash.h"
27 #include "prefix.h"
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33 DECLARE_MTYPE(ROUTE_TABLE)
34 DECLARE_MTYPE(ROUTE_NODE)
35
36 /*
37 * Forward declarations.
38 */
39 struct route_node;
40 struct route_table;
41
42 /*
43 * route_table_delegate_t
44 *
45 * Function vector that can be used by a client to customize the
46 * behavior of one or more route tables.
47 */
48 typedef struct route_table_delegate_t_ route_table_delegate_t;
49
50 typedef struct route_node *(*route_table_create_node_func_t)(
51 route_table_delegate_t *, struct route_table *);
52
53 typedef void (*route_table_destroy_node_func_t)(route_table_delegate_t *,
54 struct route_table *,
55 struct route_node *);
56
57 struct route_table_delegate_t_ {
58 route_table_create_node_func_t create_node;
59 route_table_destroy_node_func_t destroy_node;
60 };
61
62 /* Routing table top structure. */
63 struct route_table {
64 struct route_node *top;
65 struct hash *hash;
66
67 /*
68 * Delegate that performs certain functions for this table.
69 */
70 route_table_delegate_t *delegate;
71 void (*cleanup)(struct route_table *, struct route_node *);
72
73 unsigned long count;
74
75 /*
76 * User data.
77 */
78 void *info;
79 };
80
81 /*
82 * node->link is really internal to the table code and should not be
83 * accessed by outside code. We don't have any writers (yay), though some
84 * readers are left to be fixed.
85 *
86 * rationale: we need to add a hash table in parallel, to speed up
87 * exact-match lookups.
88 *
89 * same really applies for node->parent, though that's less of an issue.
90 * table->link should be - and is - NEVER written by outside code
91 */
92 #ifdef FRR_COMPILING_TABLE_C
93 #define table_rdonly(x) x
94 #define table_internal(x) x
95 #else
96 #define table_rdonly(x) const x
97 #define table_internal(x) \
98 const x __attribute__( \
99 (deprecated("this should only be accessed by lib/table.c")))
100 /* table_internal is for node->link and node->lock, once we have done
101 * something about remaining accesses */
102 #endif
103
104 /* so... the problem with this is that "const" doesn't mean "readonly".
105 * It in fact may allow the compiler to optimize based on the assumption
106 * that the value doesn't change. Hence, since the only purpose of this
107 * is to aid in development, don't put the "const" in release builds.
108 *
109 * (I haven't seen this actually break, but GCC and LLVM are getting ever
110 * more aggressive in optimizing...)
111 */
112 #ifndef DEV_BUILD
113 #undef table_rdonly
114 #define table_rdonly(x) x
115 #endif
116
117 /*
118 * Macro that defines all fields in a route node.
119 */
120 #define ROUTE_NODE_FIELDS \
121 /* Actual prefix of this radix. */ \
122 struct prefix p; \
123 \
124 /* Tree link. */ \
125 struct route_table *table_rdonly(table); \
126 struct route_node *table_rdonly(parent); \
127 struct route_node *table_rdonly(link[2]); \
128 \
129 /* Lock of this radix */ \
130 unsigned int table_rdonly(lock); \
131 \
132 /* Each node of route. */ \
133 void *info; \
134
135
136 /* Each routing entry. */
137 struct route_node {
138 ROUTE_NODE_FIELDS
139
140 #define l_left link[0]
141 #define l_right link[1]
142 };
143
144 typedef struct route_table_iter_t_ route_table_iter_t;
145
146 typedef enum {
147 RT_ITER_STATE_INIT,
148 RT_ITER_STATE_ITERATING,
149 RT_ITER_STATE_PAUSED,
150 RT_ITER_STATE_DONE
151 } route_table_iter_state_t;
152
153 /*
154 * route_table_iter_t
155 *
156 * Structure that holds state for iterating over a route table.
157 */
158 struct route_table_iter_t_ {
159
160 route_table_iter_state_t state;
161
162 /*
163 * Routing table that we are iterating over. The caller must ensure
164 * that that table outlives the iterator.
165 */
166 struct route_table *table;
167
168 /*
169 * The node that the iterator is currently on.
170 */
171 struct route_node *current;
172
173 /*
174 * The last prefix that the iterator processed before it was paused.
175 */
176 struct prefix pause_prefix;
177 };
178
179 /* Prototypes. */
180 extern struct route_table *route_table_init(void);
181
182 extern struct route_table *
183 route_table_init_with_delegate(route_table_delegate_t *delegate);
184
185 extern route_table_delegate_t *route_table_get_default_delegate(void);
186
187 static inline void *route_table_get_info(struct route_table *table)
188 {
189 return table->info;
190 }
191
192 static inline void route_table_set_info(struct route_table *table, void *d)
193 {
194 table->info = d;
195 }
196
197 extern void route_table_finish(struct route_table *table);
198 extern struct route_node *route_top(struct route_table *table);
199 extern struct route_node *route_next(struct route_node *node);
200 extern struct route_node *route_next_until(struct route_node *node,
201 const struct route_node *limit);
202 extern struct route_node *route_node_get(struct route_table *const table,
203 union prefixconstptr pu);
204 extern struct route_node *route_node_lookup(const struct route_table *table,
205 union prefixconstptr pu);
206 extern struct route_node *
207 route_node_lookup_maynull(const struct route_table *table,
208 union prefixconstptr pu);
209 extern struct route_node *route_node_match(const struct route_table *table,
210 union prefixconstptr pu);
211 extern struct route_node *route_node_match_ipv4(const struct route_table *table,
212 const struct in_addr *addr);
213 extern struct route_node *route_node_match_ipv6(const struct route_table *table,
214 const struct in6_addr *addr);
215
216 extern unsigned long route_table_count(const struct route_table *table);
217
218 extern struct route_node *route_node_create(route_table_delegate_t *delegate,
219 struct route_table *table);
220 extern void route_node_delete(struct route_node *node);
221 extern void route_node_destroy(route_table_delegate_t *delegate,
222 struct route_table *table,
223 struct route_node *node);
224
225 extern struct route_node *route_table_get_next(const struct route_table *table,
226 union prefixconstptr pu);
227 extern int route_table_prefix_iter_cmp(const struct prefix *p1,
228 const struct prefix *p2);
229
230 /*
231 * Iterator functions.
232 */
233 extern void route_table_iter_init(route_table_iter_t *iter,
234 struct route_table *table);
235 extern void route_table_iter_pause(route_table_iter_t *iter);
236 extern void route_table_iter_cleanup(route_table_iter_t *iter);
237
238 /*
239 * Inline functions.
240 */
241
242 /* Lock node. */
243 static inline struct route_node *route_lock_node(struct route_node *node)
244 {
245 (*(unsigned *)&node->lock)++;
246 return node;
247 }
248
249 /* Unlock node. */
250 static inline void route_unlock_node(struct route_node *node)
251 {
252 assert(node->lock > 0);
253 (*(unsigned *)&node->lock)--;
254
255 if (node->lock == 0)
256 route_node_delete(node);
257 }
258
259 /*
260 * route_table_iter_next
261 *
262 * Get the next node in the tree.
263 */
264 static inline struct route_node *route_table_iter_next(route_table_iter_t *iter)
265 {
266 struct route_node *node;
267
268 switch (iter->state) {
269
270 case RT_ITER_STATE_INIT:
271
272 /*
273 * We're just starting the iteration.
274 */
275 node = route_top(iter->table);
276 break;
277
278 case RT_ITER_STATE_ITERATING:
279 node = route_next(iter->current);
280 break;
281
282 case RT_ITER_STATE_PAUSED:
283
284 /*
285 * Start with the node following pause_prefix.
286 */
287 node = route_table_get_next(iter->table, &iter->pause_prefix);
288 break;
289
290 case RT_ITER_STATE_DONE:
291 return NULL;
292
293 default:
294 assert(0);
295 }
296
297 iter->current = node;
298 if (node)
299 iter->state = RT_ITER_STATE_ITERATING;
300 else
301 iter->state = RT_ITER_STATE_DONE;
302
303 return node;
304 }
305
306 /*
307 * route_table_iter_is_done
308 *
309 * Returns TRUE if the iteration is complete.
310 */
311 static inline int route_table_iter_is_done(route_table_iter_t *iter)
312 {
313 return iter->state == RT_ITER_STATE_DONE;
314 }
315
316 /*
317 * route_table_iter_started
318 *
319 * Returns TRUE if this iterator has started iterating over the tree.
320 */
321 static inline int route_table_iter_started(route_table_iter_t *iter)
322 {
323 return iter->state != RT_ITER_STATE_INIT;
324 }
325
326 #ifdef __cplusplus
327 }
328 #endif
329
330 #endif /* _ZEBRA_TABLE_H */