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