]>
Commit | Line | Data |
---|---|---|
65efcfce LB |
1 | /* |
2 | * | |
3 | * Copyright 2009-2016, LabN Consulting, L.L.C. | |
4 | * | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License | |
8 | * as published by the Free Software Foundation; either version 2 | |
9 | * of the License, or (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, write to the Free Software | |
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
19 | * | |
20 | */ | |
21 | ||
22 | /* | |
23 | * Internal definitions for RFAPI. Not for use by other code | |
24 | */ | |
25 | ||
26 | #ifndef _QUAGGA_BGP_RFAPI_PRIVATE_H | |
27 | #define _QUAGGA_BGP_RFAPI_PRIVATE_H | |
28 | ||
f8b6f499 LB |
29 | #include "lib/linklist.h" |
30 | #include "lib/skiplist.h" | |
31 | #include "lib/workqueue.h" | |
65efcfce | 32 | |
f8b6f499 | 33 | #include "bgpd/bgp_attr.h" |
4f280b15 | 34 | #include "bgpd/bgp_route.h" |
65efcfce LB |
35 | |
36 | #include "rfapi.h" | |
37 | ||
65efcfce LB |
38 | /* |
39 | * Lists of rfapi_adb. Each rfapi_adb is referenced twice: | |
40 | * | |
41 | * 1. each is referenced in by_lifetime | |
42 | * 2. each is referenced by exactly one of: ipN_by_prefix, ip0_by_ether | |
43 | */ | |
44 | struct rfapi_advertised_prefixes | |
45 | { | |
46 | struct skiplist *ipN_by_prefix; /* all except 0/32, 0/128 */ | |
47 | struct skiplist *ip0_by_ether; /* ip prefix 0/32, 0/128 */ | |
48 | struct skiplist *by_lifetime; /* all */ | |
49 | }; | |
50 | ||
65efcfce LB |
51 | struct rfapi_descriptor |
52 | { | |
53 | struct route_node *un_node; /* backref to un table */ | |
54 | ||
55 | struct rfapi_descriptor *next; /* next vn_addr */ | |
56 | ||
57 | /* supplied by client */ | |
58 | struct bgp *bgp; /* from rfp_start_val */ | |
59 | struct rfapi_ip_addr vn_addr; | |
60 | struct rfapi_ip_addr un_addr; | |
61 | rfapi_response_cb_t *response_cb; /* override per-bgp response_cb */ | |
62 | void *cookie; /* for callbacks */ | |
63 | struct rfapi_tunneltype_option default_tunneltype_option; | |
64 | ||
65 | /* supplied by matched configuration */ | |
66 | struct prefix_rd rd; | |
67 | struct ecommunity *rt_export_list; | |
68 | uint32_t response_lifetime; | |
69 | ||
70 | /* list of prefixes currently being advertised by this nve */ | |
71 | struct rfapi_advertised_prefixes advertised; | |
72 | ||
73 | time_t open_time; | |
74 | ||
75 | uint32_t max_prefix_lifetime; | |
76 | uint32_t min_prefix_lifetime; | |
77 | ||
78 | /* reference to this nve's import table */ | |
79 | struct rfapi_import_table *import_table; | |
80 | ||
81 | uint32_t monitor_count; | |
82 | struct route_table *mon; /* rfapi_monitors */ | |
83 | struct skiplist *mon_eth; /* ethernet monitors */ | |
84 | ||
85 | /* | |
86 | * rib RIB as seen by NVE | |
87 | * rib_pending RIB containing nodes with updated info chains | |
88 | * rsp_times last time we sent response containing pfx | |
89 | */ | |
90 | uint32_t rib_prefix_count; /* pfxes with routes */ | |
91 | struct route_table *rib[AFI_MAX]; | |
92 | struct route_table *rib_pending[AFI_MAX]; | |
93 | struct work_queue *updated_responses_queue; | |
94 | struct route_table *rsp_times[AFI_MAX]; | |
95 | ||
96 | uint32_t rsp_counter; /* dedup initial rsp */ | |
97 | time_t rsp_time; /* dedup initial rsp */ | |
98 | time_t ftd_last_allowed_time; /* FTD filter */ | |
99 | ||
100 | unsigned int stat_count_nh_reachable; | |
101 | unsigned int stat_count_nh_removal; | |
102 | ||
103 | /* | |
104 | * points to the original nve group structure that matched | |
105 | * when this nve_descriptor was created. We use this pointer | |
106 | * in rfapi_close() to find the nve group structure and | |
107 | * delete its reference back to us. | |
108 | * | |
109 | * If the nve group structure is deleted (via configuration | |
110 | * change) while this nve_descriptor exists, this rfg pointer | |
111 | * will be set to NULL. | |
112 | */ | |
113 | struct rfapi_nve_group_cfg *rfg; | |
114 | ||
115 | /* | |
116 | * This ~7kB structure is here to permit multiple routes for | |
117 | * a prefix to be injected to BGP. There are at least two | |
118 | * situations where such conditions obtain: | |
119 | * | |
120 | * When an VNC route is exported to BGP on behalf of the set of | |
121 | * NVEs that belong to the export NVE group, it is replicated | |
122 | * so that there is one route per NVE (and the route's nexthop | |
123 | * is the NVE's VN address). | |
124 | * | |
125 | * Each of these routes being injected to BGP must have a distinct | |
126 | * peer pointer (otherwise, if they have the same peer pointer, each | |
127 | * route will be considered an implicit waithdraw of the previous | |
128 | * route injected from that peer, and the new route will replace | |
129 | * rather than augment the old one(s)). | |
130 | */ | |
131 | struct peer *peer; | |
132 | ||
133 | uint32_t flags; | |
134 | #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP 0x00000001 | |
135 | #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6 0x00000002 | |
0aa9c36c | 136 | #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN 0x00000004 |
65efcfce LB |
137 | #define RFAPI_HD_FLAG_PROVISIONAL 0x00000008 |
138 | #define RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY 0x00000010 | |
5ff06872 | 139 | #define RFAPI_HD_FLAG_IS_VRF 0x00000012 |
65efcfce LB |
140 | }; |
141 | ||
142 | #define RFAPI_QUEUED_FLAG(afi) ( \ | |
143 | ((afi) == AFI_IP)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP: \ | |
144 | (((afi) == AFI_IP6)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6: \ | |
0aa9c36c | 145 | (((afi) == AFI_L2VPN)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN: \ |
65efcfce LB |
146 | (assert(0), 0) ))) |
147 | ||
148 | ||
149 | struct rfapi_global_stats | |
150 | { | |
151 | time_t last_reset; | |
152 | unsigned int max_descriptors; | |
153 | ||
154 | unsigned int count_unknown_nves; | |
155 | ||
156 | unsigned int count_queries; | |
157 | unsigned int count_queries_failed; | |
158 | ||
159 | unsigned int max_responses; /* semantics? */ | |
160 | ||
161 | unsigned int count_registrations; | |
162 | unsigned int count_registrations_failed; | |
163 | ||
164 | unsigned int count_updated_response_updates; | |
165 | unsigned int count_updated_response_deletes; | |
166 | }; | |
167 | ||
168 | /* | |
169 | * There is one of these per BGP instance. | |
170 | * | |
171 | * Radix tree is indexed by un address; follow chain and | |
172 | * check vn address to get exact match. | |
173 | */ | |
174 | struct rfapi | |
175 | { | |
176 | struct route_table un[AFI_MAX]; | |
177 | struct rfapi_import_table *imports; /* IPv4, IPv6 */ | |
178 | struct list descriptors;/* debug & resolve-nve imports */ | |
179 | ||
180 | struct rfapi_global_stats stat; | |
181 | ||
182 | /* | |
183 | * callbacks into RFP, set at startup time (bgp_rfapi_new() gets | |
184 | * values from rfp_start()) or via rfapi_rfp_set_cb_methods() | |
185 | * (otherwise NULL). Note that the response_cb method can also | |
186 | * be overridden per-rfd (currently used only for debug/test scenarios) | |
187 | */ | |
188 | struct rfapi_rfp_cb_methods rfp_methods; | |
189 | ||
190 | /* | |
191 | * Import tables for Ethernet over IPSEC | |
192 | * | |
193 | * The skiplist keys are LNIs. Values are pointers | |
194 | * to struct rfapi_import_table. | |
195 | */ | |
196 | struct skiplist *import_mac; /* L2 */ | |
197 | ||
198 | /* | |
199 | * when exporting plain routes ("registered-nve" mode) to | |
200 | * bgp unicast or zebra, we need to keep track of information | |
201 | * related to expiring the routes according to the VNC lifetime | |
202 | */ | |
203 | struct route_table *rt_export_bgp[AFI_MAX]; | |
204 | struct route_table *rt_export_zebra[AFI_MAX]; | |
205 | ||
206 | /* | |
207 | * For VNC->BGP unicast exports in CE mode, we need a | |
208 | * routing table that collects all of the VPN routes | |
209 | * in a single tree. The VPN rib is split up according | |
210 | * to RD first, so we can't use that. This is an import | |
211 | * table that matches all RTs. | |
212 | */ | |
213 | struct rfapi_import_table *it_ce; | |
214 | ||
215 | /* | |
216 | * when importing bgp-direct routes in resolve-nve mode, | |
217 | * this list maps unicast route nexthops to their bgp_infos | |
218 | * in the unicast table | |
219 | */ | |
220 | struct skiplist *resolve_nve_nexthop; | |
221 | ||
222 | /* | |
223 | * Descriptors for which rfapi_close() was called during a callback. | |
224 | * They will be closed after the callback finishes. | |
225 | */ | |
226 | struct work_queue *deferred_close_q; | |
227 | ||
228 | /* | |
229 | * For "show vnc responses" | |
230 | */ | |
231 | uint32_t response_immediate_count; | |
232 | uint32_t response_updated_count; | |
233 | uint32_t monitor_count; | |
234 | ||
235 | uint32_t rib_prefix_count_total; | |
236 | uint32_t rib_prefix_count_total_max; | |
237 | ||
238 | uint32_t flags; | |
239 | #define RFAPI_INCALLBACK 0x00000001 | |
240 | void *rfp; /* from rfp_start */ | |
241 | }; | |
242 | ||
243 | #define RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfapi) do { \ | |
244 | ++(rfd)->rib_prefix_count; \ | |
245 | ++(rfapi)->rib_prefix_count_total; \ | |
246 | if ((rfapi)->rib_prefix_count_total > (rfapi)->rib_prefix_count_total_max) \ | |
247 | ++(rfapi)->rib_prefix_count_total_max; \ | |
248 | } while (0) | |
249 | ||
250 | #define RFAPI_RIB_PREFIX_COUNT_DECR(rfd, rfapi) do { \ | |
251 | --(rfd)->rib_prefix_count; \ | |
252 | --(rfapi)->rib_prefix_count_total; \ | |
253 | } while (0) | |
254 | ||
255 | #define RFAPI_0_PREFIX(prefix) ( \ | |
256 | (((prefix)->family == AF_INET)? (prefix)->u.prefix4.s_addr == 0: \ | |
257 | (((prefix)->family == AF_INET6)? \ | |
258 | (IN6_IS_ADDR_UNSPECIFIED(&(prefix)->u.prefix6)) : 0)) \ | |
259 | ) | |
260 | ||
261 | #define RFAPI_0_ETHERADDR(ea) ( \ | |
262 | ((ea)->octet[0] | (ea)->octet[1] | (ea)->octet[2] | \ | |
263 | (ea)->octet[3] | (ea)->octet[4] | (ea)->octet[5]) == 0) | |
264 | ||
265 | #define RFAPI_HOST_PREFIX(prefix) ( \ | |
266 | ((prefix)->family == AF_INET)? ((prefix)->prefixlen == 32): \ | |
267 | (((prefix)->family == AF_INET6)? ((prefix)->prefixlen == 128): 0) ) | |
268 | ||
269 | extern void | |
270 | rfapiQprefix2Rprefix ( | |
271 | struct prefix *qprefix, | |
272 | struct rfapi_ip_prefix *rprefix); | |
273 | ||
274 | extern int | |
275 | rfapi_find_rfd ( | |
276 | struct bgp *bgp, | |
277 | struct rfapi_ip_addr *vn_addr, | |
278 | struct rfapi_ip_addr *un_addr, | |
279 | struct rfapi_descriptor **rfd); | |
280 | ||
281 | extern void | |
282 | add_vnc_route ( | |
283 | struct rfapi_descriptor *rfd, /* cookie + UN addr for VPN */ | |
284 | struct bgp *bgp, | |
285 | int safi, | |
286 | struct prefix *p, | |
287 | struct prefix_rd *prd, | |
288 | struct rfapi_ip_addr *nexthop, | |
289 | uint32_t *local_pref, /* host byte order */ | |
290 | uint32_t *lifetime, /* host byte order */ | |
291 | struct bgp_tea_options *rfp_options, | |
292 | struct rfapi_un_option *options_un, | |
293 | struct rfapi_vn_option *options_vn, | |
294 | struct ecommunity *rt_export_list, | |
295 | uint32_t *med, | |
296 | uint32_t *label, | |
297 | uint8_t type, | |
298 | uint8_t sub_type, | |
299 | int flags); | |
300 | #define RFAPI_AHR_NO_TUNNEL_SUBTLV 0x00000001 | |
301 | #define RFAPI_AHR_RFPOPT_IS_VNCTLV 0x00000002 /* hack! */ | |
302 | #if 0 /* unused? */ | |
303 | # define RFAPI_AHR_SET_PFX_TO_NEXTHOP 0x00000004 | |
304 | #endif | |
305 | ||
306 | extern void | |
307 | del_vnc_route ( | |
308 | struct rfapi_descriptor *rfd, | |
309 | struct peer *peer, | |
310 | struct bgp *bgp, | |
311 | safi_t safi, | |
312 | struct prefix *p, | |
313 | struct prefix_rd *prd, | |
314 | uint8_t type, | |
315 | uint8_t sub_type, | |
316 | struct rfapi_nexthop *lnh, | |
317 | int kill); | |
318 | ||
319 | extern int | |
320 | rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p); | |
321 | ||
322 | extern int | |
323 | rfapiGetVncLifetime (struct attr *attr, uint32_t * lifetime); | |
324 | ||
325 | extern int | |
326 | rfapiGetTunnelType (struct attr *attr, bgp_encap_types *type); | |
327 | ||
328 | extern int | |
329 | rfapiGetVncTunnelUnAddr (struct attr *attr, struct prefix *p); | |
330 | ||
331 | extern int | |
332 | rfapi_reopen (struct rfapi_descriptor *rfd, struct bgp *bgp); | |
333 | ||
334 | extern void | |
335 | vnc_import_bgp_add_rfp_host_route_mode_resolve_nve ( | |
336 | struct bgp *bgp, | |
337 | struct rfapi_descriptor *rfd, | |
338 | struct prefix *prefix); | |
339 | ||
340 | extern void | |
341 | vnc_import_bgp_del_rfp_host_route_mode_resolve_nve ( | |
342 | struct bgp *bgp, | |
343 | struct rfapi_descriptor *rfd, | |
344 | struct prefix *prefix); | |
345 | ||
346 | extern void | |
347 | rfapiFreeBgpTeaOptionChain (struct bgp_tea_options *p); | |
348 | ||
349 | extern struct rfapi_vn_option * | |
350 | rfapiVnOptionsDup (struct rfapi_vn_option *orig); | |
351 | ||
352 | extern struct rfapi_un_option * | |
353 | rfapiUnOptionsDup (struct rfapi_un_option *orig); | |
354 | ||
355 | extern struct bgp_tea_options * | |
356 | rfapiOptionsDup (struct bgp_tea_options *orig); | |
357 | ||
358 | extern int | |
359 | rfapi_ip_addr_cmp (struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2); | |
360 | ||
361 | extern uint32_t | |
362 | rfp_cost_to_localpref (uint8_t cost); | |
363 | ||
364 | extern int | |
365 | rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn); | |
366 | ||
65efcfce LB |
367 | extern struct rfapi_nexthop * |
368 | rfapi_nexthop_new (struct rfapi_nexthop *copyme); | |
369 | ||
370 | extern void | |
371 | rfapi_nexthop_free (void *goner); | |
372 | ||
373 | extern struct rfapi_vn_option * | |
374 | rfapi_vn_options_dup (struct rfapi_vn_option *existing); | |
375 | ||
376 | extern void | |
377 | rfapi_un_options_free (struct rfapi_un_option *goner); | |
378 | ||
379 | extern void | |
380 | rfapi_vn_options_free (struct rfapi_vn_option *goner); | |
381 | ||
382 | /*------------------------------------------ | |
383 | * rfapi_extract_l2o | |
384 | * | |
385 | * Find Layer 2 options in an option chain | |
386 | * | |
387 | * input: | |
388 | * pHop option chain | |
389 | * | |
390 | * output: | |
391 | * l2o layer 2 options extracted | |
392 | * | |
393 | * return value: | |
394 | * 0 OK | |
395 | * 1 no options found | |
396 | * | |
397 | --------------------------------------------*/ | |
398 | extern int | |
399 | rfapi_extract_l2o ( | |
400 | struct bgp_tea_options *pHop, /* chain of options */ | |
401 | struct rfapi_l2address_option *l2o); /* return extracted value */ | |
402 | ||
403 | /* | |
404 | * compaitibility to old quagga_time call | |
405 | * time_t value in terms of stabilised absolute time. | |
406 | * replacement for POSIX time() | |
407 | */ | |
408 | extern time_t rfapi_time (time_t *t); | |
409 | ||
410 | DECLARE_MGROUP(RFAPI) | |
411 | DECLARE_MTYPE(RFAPI_CFG) | |
412 | DECLARE_MTYPE(RFAPI_GROUP_CFG) | |
413 | DECLARE_MTYPE(RFAPI_L2_CFG) | |
414 | DECLARE_MTYPE(RFAPI_RFP_GROUP_CFG) | |
415 | DECLARE_MTYPE(RFAPI) | |
416 | DECLARE_MTYPE(RFAPI_DESC) | |
417 | DECLARE_MTYPE(RFAPI_IMPORTTABLE) | |
418 | DECLARE_MTYPE(RFAPI_MONITOR) | |
419 | DECLARE_MTYPE(RFAPI_MONITOR_ENCAP) | |
420 | DECLARE_MTYPE(RFAPI_NEXTHOP) | |
421 | DECLARE_MTYPE(RFAPI_VN_OPTION) | |
422 | DECLARE_MTYPE(RFAPI_UN_OPTION) | |
423 | DECLARE_MTYPE(RFAPI_WITHDRAW) | |
424 | DECLARE_MTYPE(RFAPI_RFG_NAME) | |
425 | DECLARE_MTYPE(RFAPI_ADB) | |
426 | DECLARE_MTYPE(RFAPI_ETI) | |
427 | DECLARE_MTYPE(RFAPI_NVE_ADDR) | |
428 | DECLARE_MTYPE(RFAPI_PREFIX_BAG) | |
429 | DECLARE_MTYPE(RFAPI_IT_EXTRA) | |
430 | DECLARE_MTYPE(RFAPI_INFO) | |
431 | DECLARE_MTYPE(RFAPI_ADDR) | |
432 | DECLARE_MTYPE(RFAPI_UPDATED_RESPONSE_QUEUE) | |
433 | DECLARE_MTYPE(RFAPI_RECENT_DELETE) | |
434 | DECLARE_MTYPE(RFAPI_L2ADDR_OPT) | |
435 | DECLARE_MTYPE(RFAPI_AP) | |
436 | DECLARE_MTYPE(RFAPI_MONITOR_ETH) | |
437 | ||
5ff06872 LB |
438 | |
439 | /* | |
440 | * Caller must supply an already-allocated rfd with the "caller" | |
441 | * fields already set (vn_addr, un_addr, callback, cookie) | |
442 | * The advertised_prefixes[] array elements should be NULL to | |
443 | * have this function set them to newly-allocated radix trees. | |
444 | */ | |
445 | extern int | |
446 | rfapi_init_and_open( | |
447 | struct bgp *bgp, | |
448 | struct rfapi_descriptor *rfd, | |
449 | struct rfapi_nve_group_cfg *rfg); | |
450 | ||
65efcfce | 451 | #endif /* _QUAGGA_BGP_RFAPI_PRIVATE_H */ |