]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_table.h
bgpd: Fix route node unlock when clearing adj-out
[mirror_frr.git] / bgpd / bgp_table.h
1 /* BGP routing table
2 Copyright (C) 1998, 2001 Kunihiro Ishiguro
3
4 This file is part of GNU Zebra.
5
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21 #ifndef _QUAGGA_BGP_TABLE_H
22 #define _QUAGGA_BGP_TABLE_H
23
24 #include "table.h"
25
26 struct bgp_table
27 {
28 /* afi/safi of this table */
29 afi_t afi;
30 safi_t safi;
31
32 int lock;
33
34 /* The owner of this 'bgp_table' structure. */
35 struct peer *owner;
36
37 struct route_table *route_table;
38 uint64_t version;
39 };
40
41 struct bgp_node
42 {
43 /*
44 * CAUTION
45 *
46 * These fields must be the very first fields in this structure.
47 *
48 * @see bgp_node_to_rnode
49 * @see bgp_node_from_rnode
50 */
51 ROUTE_NODE_FIELDS
52
53 struct bgp_adj_out *adj_out;
54
55 struct bgp_adj_in *adj_in;
56
57 struct bgp_node *prn;
58
59 uint64_t version;
60 u_char flags;
61 #define BGP_NODE_PROCESS_SCHEDULED (1 << 0)
62 #define BGP_NODE_USER_CLEAR (1 << 1)
63 };
64
65 /*
66 * bgp_table_iter_t
67 *
68 * Structure that holds state for iterating over a bgp table.
69 */
70 typedef struct bgp_table_iter_t_
71 {
72 struct bgp_table *table;
73 route_table_iter_t rt_iter;
74 } bgp_table_iter_t;
75
76 extern struct bgp_table *bgp_table_init (afi_t, safi_t);
77 extern void bgp_table_lock (struct bgp_table *);
78 extern void bgp_table_unlock (struct bgp_table *);
79 extern void bgp_table_finish (struct bgp_table **);
80
81
82 /*
83 * bgp_node_from_rnode
84 *
85 * Returns the bgp_node structure corresponding to a route_node.
86 */
87 static inline struct bgp_node *
88 bgp_node_from_rnode (struct route_node *rnode)
89 {
90 return (struct bgp_node *) rnode;
91 }
92
93 /*
94 * bgp_node_to_rnode
95 *
96 * Returns the route_node structure corresponding to a bgp_node.
97 */
98 static inline struct route_node *
99 bgp_node_to_rnode (struct bgp_node *node)
100 {
101 return (struct route_node *) node;
102 }
103
104 /*
105 * bgp_node_table
106 *
107 * Returns the bgp_table that the given node is in.
108 */
109 static inline struct bgp_table *
110 bgp_node_table (struct bgp_node *node)
111 {
112 return bgp_node_to_rnode (node)->table->info;
113 }
114
115 /*
116 * bgp_node_parent_nolock
117 *
118 * Gets the parent node of the given node without locking it.
119 */
120 static inline struct bgp_node *
121 bgp_node_parent_nolock (struct bgp_node *node)
122 {
123 return bgp_node_from_rnode (node->parent);
124 }
125
126 /*
127 * bgp_unlock_node
128 */
129 static inline void
130 bgp_unlock_node (struct bgp_node *node)
131 {
132 route_unlock_node (bgp_node_to_rnode (node));
133 }
134
135 /*
136 * bgp_table_top_nolock
137 *
138 * Gets the top node in the table without locking it.
139 *
140 * @see bgp_table_top
141 */
142 static inline struct bgp_node *
143 bgp_table_top_nolock (const struct bgp_table *const table)
144 {
145 return bgp_node_from_rnode (table->route_table->top);
146 }
147
148 /*
149 * bgp_table_top
150 */
151 static inline struct bgp_node *
152 bgp_table_top (const struct bgp_table *const table)
153 {
154 return bgp_node_from_rnode (route_top (table->route_table));
155 }
156
157 /*
158 * bgp_route_next
159 */
160 static inline struct bgp_node *
161 bgp_route_next (struct bgp_node *node)
162 {
163 return bgp_node_from_rnode (route_next (bgp_node_to_rnode (node)));
164 }
165
166 /*
167 * bgp_route_next_until
168 */
169 static inline struct bgp_node *
170 bgp_route_next_until (struct bgp_node *node, struct bgp_node *limit)
171 {
172 struct route_node *rnode;
173
174 rnode = route_next_until (bgp_node_to_rnode (node),
175 bgp_node_to_rnode (limit));
176 return bgp_node_from_rnode (rnode);
177 }
178
179 /*
180 * bgp_node_get
181 */
182 static inline struct bgp_node *
183 bgp_node_get (struct bgp_table *const table, struct prefix *p)
184 {
185 return bgp_node_from_rnode (route_node_get (table->route_table, p));
186 }
187
188 /*
189 * bgp_node_lookup
190 */
191 static inline struct bgp_node *
192 bgp_node_lookup (const struct bgp_table *const table, struct prefix *p)
193 {
194 return bgp_node_from_rnode (route_node_lookup (table->route_table, p));
195 }
196
197 /*
198 * bgp_lock_node
199 */
200 static inline struct bgp_node *
201 bgp_lock_node (struct bgp_node *node)
202 {
203 return bgp_node_from_rnode (route_lock_node (bgp_node_to_rnode (node)));
204 }
205
206 /*
207 * bgp_node_match
208 */
209 static inline struct bgp_node *
210 bgp_node_match (const struct bgp_table *table, struct prefix *p)
211 {
212 return bgp_node_from_rnode (route_node_match (table->route_table, p));
213 }
214
215 /*
216 * bgp_node_match_ipv4
217 */
218 static inline struct bgp_node *
219 bgp_node_match_ipv4 (const struct bgp_table *table, struct in_addr *addr)
220 {
221 return bgp_node_from_rnode (route_node_match_ipv4 (table->route_table,
222 addr));
223 }
224
225 #ifdef HAVE_IPV6
226
227 /*
228 * bgp_node_match_ipv6
229 */
230 static inline struct bgp_node *
231 bgp_node_match_ipv6 (const struct bgp_table *table, struct in6_addr *addr)
232 {
233 return bgp_node_from_rnode (route_node_match_ipv6 (table->route_table,
234 addr));
235 }
236
237 #endif /* HAVE_IPV6 */
238
239 static inline unsigned long
240 bgp_table_count (const struct bgp_table *const table)
241 {
242 return route_table_count (table->route_table);
243 }
244
245 /*
246 * bgp_table_get_next
247 */
248 static inline struct bgp_node *
249 bgp_table_get_next (const struct bgp_table *table, struct prefix *p)
250 {
251 return bgp_node_from_rnode (route_table_get_next (table->route_table, p));
252 }
253
254 /*
255 * bgp_table_iter_init
256 */
257 static inline void
258 bgp_table_iter_init (bgp_table_iter_t * iter, struct bgp_table *table)
259 {
260 bgp_table_lock (table);
261 iter->table = table;
262 route_table_iter_init (&iter->rt_iter, table->route_table);
263 }
264
265 /*
266 * bgp_table_iter_next
267 */
268 static inline struct bgp_node *
269 bgp_table_iter_next (bgp_table_iter_t * iter)
270 {
271 return bgp_node_from_rnode (route_table_iter_next (&iter->rt_iter));
272 }
273
274 /*
275 * bgp_table_iter_cleanup
276 */
277 static inline void
278 bgp_table_iter_cleanup (bgp_table_iter_t * iter)
279 {
280 route_table_iter_cleanup (&iter->rt_iter);
281 bgp_table_unlock (iter->table);
282 iter->table = NULL;
283 }
284
285 /*
286 * bgp_table_iter_pause
287 */
288 static inline void
289 bgp_table_iter_pause (bgp_table_iter_t * iter)
290 {
291 route_table_iter_pause (&iter->rt_iter);
292 }
293
294 /*
295 * bgp_table_iter_is_done
296 */
297 static inline int
298 bgp_table_iter_is_done (bgp_table_iter_t * iter)
299 {
300 return route_table_iter_is_done (&iter->rt_iter);
301 }
302
303 /*
304 * bgp_table_iter_started
305 */
306 static inline int
307 bgp_table_iter_started (bgp_table_iter_t * iter)
308 {
309 return route_table_iter_started (&iter->rt_iter);
310 }
311
312 /* This would benefit from a real atomic operation...
313 * until then. */
314 static inline uint64_t
315 bgp_table_next_version (struct bgp_table *table)
316 {
317 return ++table->version;
318 }
319
320 static inline uint64_t
321 bgp_table_version (struct bgp_table *table)
322 {
323 return table->version;
324 }
325
326 #endif /* _QUAGGA_BGP_TABLE_H */