]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_table.h
bgpd: nexthop tracking with labels for vrf-vpn leaking
[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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef _QUAGGA_BGP_TABLE_H
22 #define _QUAGGA_BGP_TABLE_H
23
24 #include "mpls.h"
25 #include "table.h"
26 #include "queue.h"
27
28 struct bgp_table {
29 /* table belongs to this instance */
30 struct bgp *bgp;
31
32 /* afi/safi of this table */
33 afi_t afi;
34 safi_t safi;
35
36 int lock;
37
38 struct route_table *route_table;
39 uint64_t version;
40 };
41
42 struct bgp_node {
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 STAILQ_ENTRY(bgp_node) pq;
60
61 mpls_label_t local_label;
62
63 uint64_t version;
64 uint8_t flags;
65 #define BGP_NODE_PROCESS_SCHEDULED (1 << 0)
66 #define BGP_NODE_USER_CLEAR (1 << 1)
67 #define BGP_NODE_LABEL_CHANGED (1 << 2)
68 #define BGP_NODE_REGISTERED_FOR_LABEL (1 << 3)
69 };
70
71 /*
72 * bgp_table_iter_t
73 *
74 * Structure that holds state for iterating over a bgp table.
75 */
76 typedef struct bgp_table_iter_t_ {
77 struct bgp_table *table;
78 route_table_iter_t rt_iter;
79 } bgp_table_iter_t;
80
81 extern struct bgp_table *bgp_table_init(struct bgp *bgp, afi_t, safi_t);
82 extern void bgp_table_lock(struct bgp_table *);
83 extern void bgp_table_unlock(struct bgp_table *);
84 extern void bgp_table_finish(struct bgp_table **);
85
86
87 /*
88 * bgp_node_from_rnode
89 *
90 * Returns the bgp_node structure corresponding to a route_node.
91 */
92 static inline struct bgp_node *bgp_node_from_rnode(struct route_node *rnode)
93 {
94 return (struct bgp_node *)rnode;
95 }
96
97 /*
98 * bgp_node_to_rnode
99 *
100 * Returns the route_node structure corresponding to a bgp_node.
101 */
102 static inline struct route_node *bgp_node_to_rnode(struct bgp_node *node)
103 {
104 return (struct route_node *)node;
105 }
106
107 /*
108 * bgp_node_table
109 *
110 * Returns the bgp_table that the given node is in.
111 */
112 static inline struct bgp_table *bgp_node_table(struct bgp_node *node)
113 {
114 return bgp_node_to_rnode(node)->table->info;
115 }
116
117 /*
118 * bgp_node_parent_nolock
119 *
120 * Gets the parent node of the given node without locking it.
121 */
122 static inline struct bgp_node *bgp_node_parent_nolock(struct bgp_node *node)
123 {
124 return bgp_node_from_rnode(node->parent);
125 }
126
127 /*
128 * bgp_unlock_node
129 */
130 static inline void 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 *bgp_route_next(struct bgp_node *node)
161 {
162 return bgp_node_from_rnode(route_next(bgp_node_to_rnode(node)));
163 }
164
165 /*
166 * bgp_route_next_until
167 */
168 static inline struct bgp_node *bgp_route_next_until(struct bgp_node *node,
169 struct bgp_node *limit)
170 {
171 struct route_node *rnode;
172
173 rnode = route_next_until(bgp_node_to_rnode(node),
174 bgp_node_to_rnode(limit));
175 return bgp_node_from_rnode(rnode);
176 }
177
178 /*
179 * bgp_node_get
180 */
181 static inline struct bgp_node *bgp_node_get(struct bgp_table *const table,
182 struct prefix *p)
183 {
184 return bgp_node_from_rnode(route_node_get(table->route_table, p));
185 }
186
187 /*
188 * bgp_node_lookup
189 */
190 static inline struct bgp_node *
191 bgp_node_lookup(const struct bgp_table *const table, struct prefix *p)
192 {
193 return bgp_node_from_rnode(route_node_lookup(table->route_table, p));
194 }
195
196 /*
197 * bgp_lock_node
198 */
199 static inline struct bgp_node *bgp_lock_node(struct bgp_node *node)
200 {
201 return bgp_node_from_rnode(route_lock_node(bgp_node_to_rnode(node)));
202 }
203
204 /*
205 * bgp_node_match
206 */
207 static inline struct bgp_node *bgp_node_match(const struct bgp_table *table,
208 struct prefix *p)
209 {
210 return bgp_node_from_rnode(route_node_match(table->route_table, p));
211 }
212
213 /*
214 * bgp_node_match_ipv4
215 */
216 static inline struct bgp_node *
217 bgp_node_match_ipv4(const struct bgp_table *table, struct in_addr *addr)
218 {
219 return bgp_node_from_rnode(
220 route_node_match_ipv4(table->route_table, addr));
221 }
222
223 /*
224 * bgp_node_match_ipv6
225 */
226 static inline struct bgp_node *
227 bgp_node_match_ipv6(const struct bgp_table *table, struct in6_addr *addr)
228 {
229 return bgp_node_from_rnode(
230 route_node_match_ipv6(table->route_table, addr));
231 }
232
233 static inline unsigned long bgp_table_count(const struct bgp_table *const table)
234 {
235 return route_table_count(table->route_table);
236 }
237
238 /*
239 * bgp_table_get_next
240 */
241 static inline struct bgp_node *bgp_table_get_next(const struct bgp_table *table,
242 struct prefix *p)
243 {
244 return bgp_node_from_rnode(route_table_get_next(table->route_table, p));
245 }
246
247 /*
248 * bgp_table_iter_init
249 */
250 static inline void bgp_table_iter_init(bgp_table_iter_t *iter,
251 struct bgp_table *table)
252 {
253 bgp_table_lock(table);
254 iter->table = table;
255 route_table_iter_init(&iter->rt_iter, table->route_table);
256 }
257
258 /*
259 * bgp_table_iter_next
260 */
261 static inline struct bgp_node *bgp_table_iter_next(bgp_table_iter_t *iter)
262 {
263 return bgp_node_from_rnode(route_table_iter_next(&iter->rt_iter));
264 }
265
266 /*
267 * bgp_table_iter_cleanup
268 */
269 static inline void bgp_table_iter_cleanup(bgp_table_iter_t *iter)
270 {
271 route_table_iter_cleanup(&iter->rt_iter);
272 bgp_table_unlock(iter->table);
273 iter->table = NULL;
274 }
275
276 /*
277 * bgp_table_iter_pause
278 */
279 static inline void bgp_table_iter_pause(bgp_table_iter_t *iter)
280 {
281 route_table_iter_pause(&iter->rt_iter);
282 }
283
284 /*
285 * bgp_table_iter_is_done
286 */
287 static inline int bgp_table_iter_is_done(bgp_table_iter_t *iter)
288 {
289 return route_table_iter_is_done(&iter->rt_iter);
290 }
291
292 /*
293 * bgp_table_iter_started
294 */
295 static inline int bgp_table_iter_started(bgp_table_iter_t *iter)
296 {
297 return route_table_iter_started(&iter->rt_iter);
298 }
299
300 /* This would benefit from a real atomic operation...
301 * until then. */
302 static inline uint64_t bgp_table_next_version(struct bgp_table *table)
303 {
304 return ++table->version;
305 }
306
307 static inline uint64_t bgp_table_version(struct bgp_table *table)
308 {
309 return table->version;
310 }
311
312 #endif /* _QUAGGA_BGP_TABLE_H */