]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_table.h
Merge pull request #2646 from AnuradhaKaruppiah/evpn-fixes
[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 #include "linklist.h"
28
29 struct bgp_table {
30 /* table belongs to this instance */
31 struct bgp *bgp;
32
33 /* afi/safi of this table */
34 afi_t afi;
35 safi_t safi;
36
37 int lock;
38
39 struct route_table *route_table;
40 uint64_t version;
41 };
42
43 struct bgp_node {
44 /*
45 * CAUTION
46 *
47 * These fields must be the very first fields in this structure.
48 *
49 * @see bgp_node_to_rnode
50 * @see bgp_node_from_rnode
51 */
52 ROUTE_NODE_FIELDS
53
54 struct bgp_adj_out *adj_out;
55
56 struct bgp_adj_in *adj_in;
57
58 struct bgp_node *prn;
59
60 STAILQ_ENTRY(bgp_node) pq;
61
62 mpls_label_t local_label;
63
64 uint64_t version;
65 uint8_t flags;
66 #define BGP_NODE_PROCESS_SCHEDULED (1 << 0)
67 #define BGP_NODE_USER_CLEAR (1 << 1)
68 #define BGP_NODE_LABEL_CHANGED (1 << 2)
69 #define BGP_NODE_REGISTERED_FOR_LABEL (1 << 3)
70 };
71
72 /*
73 * bgp_table_iter_t
74 *
75 * Structure that holds state for iterating over a bgp table.
76 */
77 typedef struct bgp_table_iter_t_ {
78 struct bgp_table *table;
79 route_table_iter_t rt_iter;
80 } bgp_table_iter_t;
81
82 extern struct bgp_table *bgp_table_init(struct bgp *bgp, afi_t, safi_t);
83 extern void bgp_table_lock(struct bgp_table *);
84 extern void bgp_table_unlock(struct bgp_table *);
85 extern void bgp_table_finish(struct bgp_table **);
86
87
88 /*
89 * bgp_node_from_rnode
90 *
91 * Returns the bgp_node structure corresponding to a route_node.
92 */
93 static inline struct bgp_node *bgp_node_from_rnode(struct route_node *rnode)
94 {
95 return (struct bgp_node *)rnode;
96 }
97
98 /*
99 * bgp_node_to_rnode
100 *
101 * Returns the route_node structure corresponding to a bgp_node.
102 */
103 static inline struct route_node *bgp_node_to_rnode(struct bgp_node *node)
104 {
105 return (struct route_node *)node;
106 }
107
108 /*
109 * bgp_node_table
110 *
111 * Returns the bgp_table that the given node is in.
112 */
113 static inline struct bgp_table *bgp_node_table(struct bgp_node *node)
114 {
115 return bgp_node_to_rnode(node)->table->info;
116 }
117
118 /*
119 * bgp_node_parent_nolock
120 *
121 * Gets the parent node of the given node without locking it.
122 */
123 static inline struct bgp_node *bgp_node_parent_nolock(struct bgp_node *node)
124 {
125 return bgp_node_from_rnode(node->parent);
126 }
127
128 /*
129 * bgp_unlock_node
130 */
131 static inline void bgp_unlock_node(struct bgp_node *node)
132 {
133 route_unlock_node(bgp_node_to_rnode(node));
134 }
135
136 /*
137 * bgp_table_top_nolock
138 *
139 * Gets the top node in the table without locking it.
140 *
141 * @see bgp_table_top
142 */
143 static inline struct bgp_node *
144 bgp_table_top_nolock(const struct bgp_table *const table)
145 {
146 return bgp_node_from_rnode(table->route_table->top);
147 }
148
149 /*
150 * bgp_table_top
151 */
152 static inline struct bgp_node *
153 bgp_table_top(const struct bgp_table *const table)
154 {
155 return bgp_node_from_rnode(route_top(table->route_table));
156 }
157
158 /*
159 * bgp_route_next
160 */
161 static inline struct bgp_node *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 *bgp_route_next_until(struct bgp_node *node,
170 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 *bgp_node_get(struct bgp_table *const table,
183 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 *bgp_lock_node(struct bgp_node *node)
201 {
202 return bgp_node_from_rnode(route_lock_node(bgp_node_to_rnode(node)));
203 }
204
205 /*
206 * bgp_node_match
207 */
208 static inline struct bgp_node *bgp_node_match(const struct bgp_table *table,
209 struct prefix *p)
210 {
211 return bgp_node_from_rnode(route_node_match(table->route_table, p));
212 }
213
214 /*
215 * bgp_node_match_ipv4
216 */
217 static inline struct bgp_node *
218 bgp_node_match_ipv4(const struct bgp_table *table, struct in_addr *addr)
219 {
220 return bgp_node_from_rnode(
221 route_node_match_ipv4(table->route_table, addr));
222 }
223
224 /*
225 * bgp_node_match_ipv6
226 */
227 static inline struct bgp_node *
228 bgp_node_match_ipv6(const struct bgp_table *table, struct in6_addr *addr)
229 {
230 return bgp_node_from_rnode(
231 route_node_match_ipv6(table->route_table, addr));
232 }
233
234 static inline unsigned long bgp_table_count(const struct bgp_table *const table)
235 {
236 return route_table_count(table->route_table);
237 }
238
239 /*
240 * bgp_table_get_next
241 */
242 static inline struct bgp_node *bgp_table_get_next(const struct bgp_table *table,
243 struct prefix *p)
244 {
245 return bgp_node_from_rnode(route_table_get_next(table->route_table, p));
246 }
247
248 /*
249 * bgp_table_iter_init
250 */
251 static inline void bgp_table_iter_init(bgp_table_iter_t *iter,
252 struct bgp_table *table)
253 {
254 bgp_table_lock(table);
255 iter->table = table;
256 route_table_iter_init(&iter->rt_iter, table->route_table);
257 }
258
259 /*
260 * bgp_table_iter_next
261 */
262 static inline struct bgp_node *bgp_table_iter_next(bgp_table_iter_t *iter)
263 {
264 return bgp_node_from_rnode(route_table_iter_next(&iter->rt_iter));
265 }
266
267 /*
268 * bgp_table_iter_cleanup
269 */
270 static inline void bgp_table_iter_cleanup(bgp_table_iter_t *iter)
271 {
272 route_table_iter_cleanup(&iter->rt_iter);
273 bgp_table_unlock(iter->table);
274 iter->table = NULL;
275 }
276
277 /*
278 * bgp_table_iter_pause
279 */
280 static inline void bgp_table_iter_pause(bgp_table_iter_t *iter)
281 {
282 route_table_iter_pause(&iter->rt_iter);
283 }
284
285 /*
286 * bgp_table_iter_is_done
287 */
288 static inline int bgp_table_iter_is_done(bgp_table_iter_t *iter)
289 {
290 return route_table_iter_is_done(&iter->rt_iter);
291 }
292
293 /*
294 * bgp_table_iter_started
295 */
296 static inline int bgp_table_iter_started(bgp_table_iter_t *iter)
297 {
298 return route_table_iter_started(&iter->rt_iter);
299 }
300
301 /* This would benefit from a real atomic operation...
302 * until then. */
303 static inline uint64_t bgp_table_next_version(struct bgp_table *table)
304 {
305 return ++table->version;
306 }
307
308 static inline uint64_t bgp_table_version(struct bgp_table *table)
309 {
310 return table->version;
311 }
312
313 void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p,
314 uint8_t maxlen, struct list *matches);
315
316 #endif /* _QUAGGA_BGP_TABLE_H */