]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_table.h
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / bgpd / bgp_table.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP routing table
3 * Copyright (C) 1998, 2001 Kunihiro Ishiguro
4 */
5
6 #ifndef _QUAGGA_BGP_TABLE_H
7 #define _QUAGGA_BGP_TABLE_H
8
9 /* XXX BEGIN TEMPORARY COMPAT */
10 #define bgp_dest bgp_node
11 /* XXX END TEMPORARY COMPAT */
12
13 #include "mpls.h"
14 #include "table.h"
15 #include "queue.h"
16 #include "linklist.h"
17 #include "bgpd.h"
18 #include "bgp_advertise.h"
19
20 struct bgp_table {
21 /* table belongs to this instance */
22 struct bgp *bgp;
23
24 /* afi/safi of this table */
25 afi_t afi;
26 safi_t safi;
27
28 int lock;
29
30 /* soft_reconfig_table in progress */
31 bool soft_reconfig_init;
32 struct event *soft_reconfig_thread;
33
34 /* list of peers on which soft_reconfig_table has to run */
35 struct list *soft_reconfig_peers;
36
37 struct route_table *route_table;
38 uint64_t version;
39 };
40
41 enum bgp_path_selection_reason {
42 bgp_path_selection_none,
43 bgp_path_selection_first,
44 bgp_path_selection_evpn_sticky_mac,
45 bgp_path_selection_evpn_seq,
46 bgp_path_selection_evpn_local_path,
47 bgp_path_selection_evpn_non_proxy,
48 bgp_path_selection_evpn_lower_ip,
49 bgp_path_selection_weight,
50 bgp_path_selection_local_pref,
51 bgp_path_selection_accept_own,
52 bgp_path_selection_local_route,
53 bgp_path_selection_aigp,
54 bgp_path_selection_confed_as_path,
55 bgp_path_selection_as_path,
56 bgp_path_selection_origin,
57 bgp_path_selection_med,
58 bgp_path_selection_peer,
59 bgp_path_selection_confed,
60 bgp_path_selection_igp_metric,
61 bgp_path_selection_older,
62 bgp_path_selection_router_id,
63 bgp_path_selection_cluster_length,
64 bgp_path_selection_stale,
65 bgp_path_selection_local_configured,
66 bgp_path_selection_neighbor_ip,
67 bgp_path_selection_default,
68 };
69
70 struct bgp_node {
71 /*
72 * CAUTION
73 *
74 * These fields must be the very first fields in this structure.
75 *
76 * @see bgp_node_to_rnode
77 * @see bgp_node_from_rnode
78 */
79 ROUTE_NODE_FIELDS
80
81 struct bgp_adj_out_rb adj_out;
82
83 struct bgp_adj_in *adj_in;
84
85 struct bgp_dest *pdest;
86
87 STAILQ_ENTRY(bgp_dest) pq;
88
89 uint64_t version;
90
91 mpls_label_t local_label;
92
93 uint16_t flags;
94 #define BGP_NODE_PROCESS_SCHEDULED (1 << 0)
95 #define BGP_NODE_USER_CLEAR (1 << 1)
96 #define BGP_NODE_LABEL_CHANGED (1 << 2)
97 #define BGP_NODE_REGISTERED_FOR_LABEL (1 << 3)
98 #define BGP_NODE_SELECT_DEFER (1 << 4)
99 #define BGP_NODE_FIB_INSTALL_PENDING (1 << 5)
100 #define BGP_NODE_FIB_INSTALLED (1 << 6)
101 #define BGP_NODE_LABEL_REQUESTED (1 << 7)
102 #define BGP_NODE_SOFT_RECONFIG (1 << 8)
103
104 struct bgp_addpath_node_data tx_addpath;
105
106 enum bgp_path_selection_reason reason;
107 };
108
109 extern void bgp_delete_listnode(struct bgp_dest *dest);
110 /*
111 * bgp_table_iter_t
112 *
113 * Structure that holds state for iterating over a bgp table.
114 */
115 typedef struct bgp_table_iter_t_ {
116 struct bgp_table *table;
117 route_table_iter_t rt_iter;
118 } bgp_table_iter_t;
119
120 extern struct bgp_table *bgp_table_init(struct bgp *bgp, afi_t, safi_t);
121 extern void bgp_table_lock(struct bgp_table *);
122 extern void bgp_table_unlock(struct bgp_table *);
123 extern void bgp_table_finish(struct bgp_table **);
124 extern void bgp_dest_unlock_node(struct bgp_dest *dest);
125 extern struct bgp_dest *bgp_dest_lock_node(struct bgp_dest *dest);
126 extern const char *bgp_dest_get_prefix_str(struct bgp_dest *dest);
127
128
129 /*
130 * bgp_dest_from_rnode
131 *
132 * Returns the bgp_dest structure corresponding to a route_node.
133 */
134 static inline struct bgp_dest *bgp_dest_from_rnode(struct route_node *rnode)
135 {
136 return (struct bgp_dest *)rnode;
137 }
138
139 /*
140 * bgp_dest_to_rnode
141 *
142 * Returns the route_node structure corresponding to a bgp_dest.
143 */
144 static inline struct route_node *bgp_dest_to_rnode(const struct bgp_dest *dest)
145 {
146 return (struct route_node *)dest;
147 }
148
149 /*
150 * bgp_dest_table
151 *
152 * Returns the bgp_table that the given dest is in.
153 */
154 static inline struct bgp_table *bgp_dest_table(struct bgp_dest *dest)
155 {
156 return route_table_get_info(bgp_dest_to_rnode(dest)->table);
157 }
158
159 /*
160 * bgp_dest_parent_nolock
161 *
162 * Gets the parent dest of the given node without locking it.
163 */
164 static inline struct bgp_dest *bgp_dest_parent_nolock(struct bgp_dest *dest)
165 {
166 struct route_node *rn = bgp_dest_to_rnode(dest)->parent;
167
168 return bgp_dest_from_rnode(rn);
169 }
170
171 /*
172 * bgp_table_top_nolock
173 *
174 * Gets the top dest in the table without locking it.
175 *
176 * @see bgp_table_top
177 */
178 static inline struct bgp_dest *
179 bgp_table_top_nolock(const struct bgp_table *const table)
180 {
181 return bgp_dest_from_rnode(table->route_table->top);
182 }
183
184 /*
185 * bgp_table_top
186 */
187 static inline struct bgp_dest *
188 bgp_table_top(const struct bgp_table *const table)
189 {
190 return bgp_dest_from_rnode(route_top(table->route_table));
191 }
192
193 /*
194 * bgp_route_next
195 */
196 static inline struct bgp_dest *bgp_route_next(struct bgp_dest *dest)
197 {
198 return bgp_dest_from_rnode(route_next(bgp_dest_to_rnode(dest)));
199 }
200
201 /*
202 * bgp_route_next_until
203 */
204 static inline struct bgp_dest *bgp_route_next_until(struct bgp_dest *dest,
205 struct bgp_dest *limit)
206 {
207 struct route_node *rnode;
208
209 rnode = route_next_until(bgp_dest_to_rnode(dest),
210 bgp_dest_to_rnode(limit));
211
212 return bgp_dest_from_rnode(rnode);
213 }
214
215 /*
216 * bgp_node_get
217 */
218 static inline struct bgp_dest *bgp_node_get(struct bgp_table *const table,
219 const struct prefix *p)
220 {
221 return bgp_dest_from_rnode(route_node_get(table->route_table, p));
222 }
223
224 /*
225 * bgp_node_lookup
226 */
227 static inline struct bgp_dest *
228 bgp_node_lookup(const struct bgp_table *const table, const struct prefix *p)
229 {
230 struct route_node *rn = route_node_lookup(table->route_table, p);
231
232 return bgp_dest_from_rnode(rn);
233 }
234
235 /*
236 * bgp_node_match
237 */
238 static inline struct bgp_dest *bgp_node_match(const struct bgp_table *table,
239 const struct prefix *p)
240 {
241 struct route_node *rn = route_node_match(table->route_table, p);
242
243 return bgp_dest_from_rnode(rn);
244 }
245
246 static inline unsigned long bgp_table_count(const struct bgp_table *const table)
247 {
248 return route_table_count(table->route_table);
249 }
250
251 /*
252 * bgp_table_get_next
253 */
254 static inline struct bgp_dest *bgp_table_get_next(const struct bgp_table *table,
255 const struct prefix *p)
256 {
257 return bgp_dest_from_rnode(route_table_get_next(table->route_table, p));
258 }
259
260 /* This would benefit from a real atomic operation...
261 * until then. */
262 static inline uint64_t bgp_table_next_version(struct bgp_table *table)
263 {
264 return ++table->version;
265 }
266
267 static inline uint64_t bgp_table_version(struct bgp_table *table)
268 {
269 return table->version;
270 }
271
272 /* Find the subtree of the prefix p
273 *
274 * This will return the first node that belongs the the subtree of p. Including
275 * p itself, if it is in the tree.
276 *
277 * If the subtree is not present in the table, NULL is returned.
278 */
279 struct bgp_dest *bgp_table_subtree_lookup(const struct bgp_table *table,
280 const struct prefix *p);
281
282 static inline struct bgp_aggregate *
283 bgp_dest_get_bgp_aggregate_info(struct bgp_dest *dest)
284 {
285 return dest ? dest->info : NULL;
286 }
287
288 static inline void
289 bgp_dest_set_bgp_aggregate_info(struct bgp_dest *dest,
290 struct bgp_aggregate *aggregate)
291 {
292 dest->info = aggregate;
293 }
294
295 static inline struct bgp_distance *
296 bgp_dest_get_bgp_distance_info(struct bgp_dest *dest)
297 {
298 return dest ? dest->info : NULL;
299 }
300
301 static inline void bgp_dest_set_bgp_distance_info(struct bgp_dest *dest,
302 struct bgp_distance *distance)
303 {
304 dest->info = distance;
305 }
306
307 static inline struct bgp_static *
308 bgp_dest_get_bgp_static_info(struct bgp_dest *dest)
309 {
310 return dest ? dest->info : NULL;
311 }
312
313 static inline void bgp_dest_set_bgp_static_info(struct bgp_dest *dest,
314 struct bgp_static *bgp_static)
315 {
316 dest->info = bgp_static;
317 }
318
319 static inline struct bgp_connected_ref *
320 bgp_dest_get_bgp_connected_ref_info(struct bgp_dest *dest)
321 {
322 return dest ? dest->info : NULL;
323 }
324
325 static inline void
326 bgp_dest_set_bgp_connected_ref_info(struct bgp_dest *dest,
327 struct bgp_connected_ref *bc)
328 {
329 dest->info = bc;
330 }
331
332 static inline struct bgp_nexthop_cache *
333 bgp_dest_get_bgp_nexthop_info(struct bgp_dest *dest)
334 {
335 return dest ? dest->info : NULL;
336 }
337
338 static inline void bgp_dest_set_bgp_nexthop_info(struct bgp_dest *dest,
339 struct bgp_nexthop_cache *bnc)
340 {
341 dest->info = bnc;
342 }
343
344 static inline struct bgp_path_info *
345 bgp_dest_get_bgp_path_info(struct bgp_dest *dest)
346 {
347 return dest ? dest->info : NULL;
348 }
349
350 static inline void bgp_dest_set_bgp_path_info(struct bgp_dest *dest,
351 struct bgp_path_info *bi)
352 {
353 dest->info = bi;
354 }
355
356 static inline struct bgp_table *
357 bgp_dest_get_bgp_table_info(struct bgp_dest *dest)
358 {
359 return dest->info;
360 }
361
362 static inline void bgp_dest_set_bgp_table_info(struct bgp_dest *dest,
363 struct bgp_table *table)
364 {
365 dest->info = table;
366 }
367
368 static inline bool bgp_dest_has_bgp_path_info_data(struct bgp_dest *dest)
369 {
370 return !!dest->info;
371 }
372
373 static inline const struct prefix *bgp_dest_get_prefix(const struct bgp_dest *dest)
374 {
375 return &dest->p;
376 }
377
378 static inline unsigned int bgp_dest_get_lock_count(const struct bgp_dest *dest)
379 {
380 return dest->lock;
381 }
382
383 #ifdef _FRR_ATTRIBUTE_PRINTFRR
384 #pragma FRR printfrr_ext "%pRN" (struct bgp_node *)
385 #pragma FRR printfrr_ext "%pBD" (struct bgp_dest *)
386 #endif
387
388 #endif /* _QUAGGA_BGP_TABLE_H */