]>
Commit | Line | Data |
---|---|---|
d62a17ae | 1 | /* |
65efcfce LB |
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 | * | |
896014f4 DL |
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 | |
65efcfce LB |
19 | */ |
20 | ||
d62a17ae | 21 | /* |
65efcfce LB |
22 | * Internal definitions for RFAPI. Not for use by other code |
23 | */ | |
24 | ||
25 | #ifndef _QUAGGA_BGP_RFAPI_PRIVATE_H | |
26 | #define _QUAGGA_BGP_RFAPI_PRIVATE_H | |
27 | ||
f8b6f499 LB |
28 | #include "lib/linklist.h" |
29 | #include "lib/skiplist.h" | |
30 | #include "lib/workqueue.h" | |
65efcfce | 31 | |
f8b6f499 | 32 | #include "bgpd/bgp_attr.h" |
4f280b15 | 33 | #include "bgpd/bgp_route.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 | */ | |
d62a17ae | 43 | struct rfapi_advertised_prefixes { |
44 | struct skiplist *ipN_by_prefix; /* all except 0/32, 0/128 */ | |
45 | struct skiplist *ip0_by_ether; /* ip prefix 0/32, 0/128 */ | |
46 | struct skiplist *by_lifetime; /* all */ | |
65efcfce LB |
47 | }; |
48 | ||
d62a17ae | 49 | struct rfapi_descriptor { |
fe08ba7e | 50 | struct agg_node *un_node; /* backref to un table */ |
d62a17ae | 51 | |
52 | struct rfapi_descriptor *next; /* next vn_addr */ | |
53 | ||
54 | /* supplied by client */ | |
55 | struct bgp *bgp; /* from rfp_start_val */ | |
56 | struct rfapi_ip_addr vn_addr; | |
57 | struct rfapi_ip_addr un_addr; | |
58 | rfapi_response_cb_t *response_cb; /* override per-bgp response_cb */ | |
59 | void *cookie; /* for callbacks */ | |
60 | struct rfapi_tunneltype_option default_tunneltype_option; | |
61 | ||
62 | /* supplied by matched configuration */ | |
63 | struct prefix_rd rd; | |
64 | struct ecommunity *rt_export_list; | |
65 | uint32_t response_lifetime; | |
66 | ||
67 | /* list of prefixes currently being advertised by this nve */ | |
68 | struct rfapi_advertised_prefixes advertised; | |
69 | ||
70 | time_t open_time; | |
71 | ||
72 | uint32_t max_prefix_lifetime; | |
73 | uint32_t min_prefix_lifetime; | |
74 | ||
75 | /* reference to this nve's import table */ | |
76 | struct rfapi_import_table *import_table; | |
77 | ||
78 | uint32_t monitor_count; | |
fe08ba7e | 79 | struct agg_table *mon; /* rfapi_monitors */ |
d62a17ae | 80 | struct skiplist *mon_eth; /* ethernet monitors */ |
81 | ||
82 | /* | |
83 | * rib RIB as seen by NVE | |
84 | * rib_pending RIB containing nodes with updated info chains | |
85 | * rsp_times last time we sent response containing pfx | |
86 | */ | |
87 | uint32_t rib_prefix_count; /* pfxes with routes */ | |
fe08ba7e DS |
88 | struct agg_table *rib[AFI_MAX]; |
89 | struct agg_table *rib_pending[AFI_MAX]; | |
d62a17ae | 90 | struct work_queue *updated_responses_queue; |
fe08ba7e | 91 | struct agg_table *rsp_times[AFI_MAX]; |
d62a17ae | 92 | |
93 | uint32_t rsp_counter; /* dedup initial rsp */ | |
94 | time_t rsp_time; /* dedup initial rsp */ | |
95 | time_t ftd_last_allowed_time; /* FTD filter */ | |
96 | ||
97 | unsigned int stat_count_nh_reachable; | |
98 | unsigned int stat_count_nh_removal; | |
99 | ||
100 | /* | |
101 | * points to the original nve group structure that matched | |
102 | * when this nve_descriptor was created. We use this pointer | |
103 | * in rfapi_close() to find the nve group structure and | |
104 | * delete its reference back to us. | |
105 | * | |
106 | * If the nve group structure is deleted (via configuration | |
107 | * change) while this nve_descriptor exists, this rfg pointer | |
108 | * will be set to NULL. | |
109 | */ | |
110 | struct rfapi_nve_group_cfg *rfg; | |
111 | ||
112 | /* | |
113 | * This ~7kB structure is here to permit multiple routes for | |
114 | * a prefix to be injected to BGP. There are at least two | |
115 | * situations where such conditions obtain: | |
116 | * | |
117 | * When an VNC route is exported to BGP on behalf of the set of | |
118 | * NVEs that belong to the export NVE group, it is replicated | |
119 | * so that there is one route per NVE (and the route's nexthop | |
120 | * is the NVE's VN address). | |
121 | * | |
122 | * Each of these routes being injected to BGP must have a distinct | |
123 | * peer pointer (otherwise, if they have the same peer pointer, each | |
124 | * route will be considered an implicit waithdraw of the previous | |
125 | * route injected from that peer, and the new route will replace | |
126 | * rather than augment the old one(s)). | |
127 | */ | |
128 | struct peer *peer; | |
129 | ||
130 | uint32_t flags; | |
65efcfce LB |
131 | #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP 0x00000001 |
132 | #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6 0x00000002 | |
0aa9c36c | 133 | #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN 0x00000004 |
65efcfce LB |
134 | #define RFAPI_HD_FLAG_PROVISIONAL 0x00000008 |
135 | #define RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY 0x00000010 | |
5ff06872 | 136 | #define RFAPI_HD_FLAG_IS_VRF 0x00000012 |
65efcfce LB |
137 | }; |
138 | ||
d62a17ae | 139 | #define RFAPI_QUEUED_FLAG(afi) \ |
140 | (((afi) == AFI_IP) \ | |
141 | ? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP \ | |
142 | : (((afi) == AFI_IP6) \ | |
143 | ? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6 \ | |
144 | : (((afi) == AFI_L2VPN) \ | |
145 | ? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN \ | |
146 | : (assert(0), 0)))) | |
65efcfce LB |
147 | |
148 | ||
d62a17ae | 149 | struct rfapi_global_stats { |
150 | time_t last_reset; | |
151 | unsigned int max_descriptors; | |
65efcfce | 152 | |
d62a17ae | 153 | unsigned int count_unknown_nves; |
65efcfce | 154 | |
d62a17ae | 155 | unsigned int count_queries; |
156 | unsigned int count_queries_failed; | |
65efcfce | 157 | |
d62a17ae | 158 | unsigned int max_responses; /* semantics? */ |
65efcfce | 159 | |
d62a17ae | 160 | unsigned int count_registrations; |
161 | unsigned int count_registrations_failed; | |
65efcfce | 162 | |
d62a17ae | 163 | unsigned int count_updated_response_updates; |
164 | unsigned int count_updated_response_deletes; | |
65efcfce LB |
165 | }; |
166 | ||
167 | /* | |
168 | * There is one of these per BGP instance. | |
169 | * | |
170 | * Radix tree is indexed by un address; follow chain and | |
171 | * check vn address to get exact match. | |
172 | */ | |
d62a17ae | 173 | struct rfapi { |
fe08ba7e | 174 | struct agg_table *un[AFI_MAX]; |
d62a17ae | 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 | */ | |
fe08ba7e DS |
201 | struct agg_table *rt_export_bgp[AFI_MAX]; |
202 | struct agg_table *rt_export_zebra[AFI_MAX]; | |
d62a17ae | 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, | |
4b7e6066 | 215 | * this list maps unicast route nexthops to their bgp_path_infos |
d62a17ae | 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; | |
65efcfce | 237 | #define RFAPI_INCALLBACK 0x00000001 |
d62a17ae | 238 | void *rfp; /* from rfp_start */ |
65efcfce LB |
239 | }; |
240 | ||
d62a17ae | 241 | #define RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfapi) \ |
242 | do { \ | |
243 | ++(rfd)->rib_prefix_count; \ | |
244 | ++(rfapi)->rib_prefix_count_total; \ | |
245 | if ((rfapi)->rib_prefix_count_total \ | |
246 | > (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) \ | |
251 | do { \ | |
252 | --(rfd)->rib_prefix_count; \ | |
253 | --(rfapi)->rib_prefix_count_total; \ | |
254 | } while (0) | |
255 | ||
256 | #define RFAPI_0_PREFIX(prefix) \ | |
257 | ((((prefix)->family == AF_INET) \ | |
3a6290bd | 258 | ? (prefix)->u.prefix4.s_addr == INADDR_ANY \ |
d62a17ae | 259 | : (((prefix)->family == AF_INET6) \ |
260 | ? (IN6_IS_ADDR_UNSPECIFIED(&(prefix)->u.prefix6)) \ | |
261 | : 0))) | |
262 | ||
263 | #define RFAPI_0_ETHERADDR(ea) \ | |
264 | (((ea)->octet[0] | (ea)->octet[1] | (ea)->octet[2] | (ea)->octet[3] \ | |
265 | | (ea)->octet[4] | (ea)->octet[5]) \ | |
266 | == 0) | |
267 | ||
268 | #define RFAPI_HOST_PREFIX(prefix) \ | |
269 | (((prefix)->family == AF_INET) \ | |
12256b84 | 270 | ? ((prefix)->prefixlen == IPV4_MAX_BITLEN) \ |
d62a17ae | 271 | : (((prefix)->family == AF_INET6) \ |
13ccce6e | 272 | ? ((prefix)->prefixlen == IPV6_MAX_BITLEN) \ |
d62a17ae | 273 | : 0)) |
274 | ||
d62a17ae | 275 | extern int rfapi_find_rfd(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, |
276 | struct rfapi_ip_addr *un_addr, | |
277 | struct rfapi_descriptor **rfd); | |
65efcfce LB |
278 | |
279 | extern void | |
d62a17ae | 280 | add_vnc_route(struct rfapi_descriptor *rfd, /* cookie + UN addr for VPN */ |
5a1ae2c2 | 281 | struct bgp *bgp, int safi, const struct prefix *p, |
d62a17ae | 282 | struct prefix_rd *prd, struct rfapi_ip_addr *nexthop, |
283 | uint32_t *local_pref, /* host byte order */ | |
284 | uint32_t *lifetime, /* host byte order */ | |
285 | struct bgp_tea_options *rfp_options, | |
286 | struct rfapi_un_option *options_un, | |
287 | struct rfapi_vn_option *options_vn, | |
288 | struct ecommunity *rt_export_list, uint32_t *med, uint32_t *label, | |
289 | uint8_t type, uint8_t sub_type, int flags); | |
65efcfce LB |
290 | #define RFAPI_AHR_NO_TUNNEL_SUBTLV 0x00000001 |
291 | #define RFAPI_AHR_RFPOPT_IS_VNCTLV 0x00000002 /* hack! */ | |
65efcfce | 292 | |
d62a17ae | 293 | extern void del_vnc_route(struct rfapi_descriptor *rfd, struct peer *peer, |
5a1ae2c2 | 294 | struct bgp *bgp, safi_t safi, const struct prefix *p, |
d62a17ae | 295 | struct prefix_rd *prd, uint8_t type, uint8_t sub_type, |
296 | struct rfapi_nexthop *lnh, int kill); | |
65efcfce | 297 | |
d62a17ae | 298 | extern int rfapiCliGetPrefixAddr(struct vty *vty, const char *str, |
299 | struct prefix *p); | |
65efcfce | 300 | |
d62a17ae | 301 | extern int rfapiGetVncLifetime(struct attr *attr, uint32_t *lifetime); |
65efcfce | 302 | |
d62a17ae | 303 | extern int rfapiGetVncTunnelUnAddr(struct attr *attr, struct prefix *p); |
65efcfce | 304 | |
d62a17ae | 305 | extern int rfapi_reopen(struct rfapi_descriptor *rfd, struct bgp *bgp); |
65efcfce | 306 | |
d62a17ae | 307 | extern void vnc_import_bgp_add_rfp_host_route_mode_resolve_nve( |
308 | struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *prefix); | |
65efcfce | 309 | |
d62a17ae | 310 | extern void vnc_import_bgp_del_rfp_host_route_mode_resolve_nve( |
311 | struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *prefix); | |
65efcfce | 312 | |
d62a17ae | 313 | extern void rfapiFreeBgpTeaOptionChain(struct bgp_tea_options *p); |
65efcfce | 314 | |
d62a17ae | 315 | extern struct rfapi_vn_option *rfapiVnOptionsDup(struct rfapi_vn_option *orig); |
65efcfce | 316 | |
d62a17ae | 317 | extern struct rfapi_un_option *rfapiUnOptionsDup(struct rfapi_un_option *orig); |
65efcfce | 318 | |
d62a17ae | 319 | extern struct bgp_tea_options *rfapiOptionsDup(struct bgp_tea_options *orig); |
65efcfce | 320 | |
d62a17ae | 321 | extern int rfapi_ip_addr_cmp(struct rfapi_ip_addr *a1, |
322 | struct rfapi_ip_addr *a2); | |
65efcfce | 323 | |
d62a17ae | 324 | extern uint32_t rfp_cost_to_localpref(uint8_t cost); |
65efcfce | 325 | |
d62a17ae | 326 | extern int rfapi_set_autord_from_vn(struct prefix_rd *rd, |
327 | struct rfapi_ip_addr *vn); | |
65efcfce | 328 | |
d62a17ae | 329 | extern struct rfapi_nexthop *rfapi_nexthop_new(struct rfapi_nexthop *copyme); |
65efcfce | 330 | |
d62a17ae | 331 | extern void rfapi_nexthop_free(void *goner); |
65efcfce LB |
332 | |
333 | extern struct rfapi_vn_option * | |
d62a17ae | 334 | rfapi_vn_options_dup(struct rfapi_vn_option *existing); |
65efcfce | 335 | |
d62a17ae | 336 | extern void rfapi_un_options_free(struct rfapi_un_option *goner); |
65efcfce | 337 | |
d62a17ae | 338 | extern void rfapi_vn_options_free(struct rfapi_vn_option *goner); |
65efcfce | 339 | |
996c9314 LB |
340 | extern void vnc_add_vrf_opener(struct bgp *bgp, |
341 | struct rfapi_nve_group_cfg *rfg); | |
d477c01d | 342 | extern void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg *rfg); |
65efcfce LB |
343 | /*------------------------------------------ |
344 | * rfapi_extract_l2o | |
345 | * | |
d62a17ae | 346 | * Find Layer 2 options in an option chain |
65efcfce | 347 | * |
d62a17ae | 348 | * input: |
65efcfce LB |
349 | * pHop option chain |
350 | * | |
351 | * output: | |
352 | * l2o layer 2 options extracted | |
353 | * | |
354 | * return value: | |
355 | * 0 OK | |
356 | * 1 no options found | |
357 | * | |
358 | --------------------------------------------*/ | |
d62a17ae | 359 | extern int rfapi_extract_l2o( |
360 | struct bgp_tea_options *pHop, /* chain of options */ | |
361 | struct rfapi_l2address_option *l2o); /* return extracted value */ | |
65efcfce | 362 | |
d62a17ae | 363 | /* |
65efcfce | 364 | * compaitibility to old quagga_time call |
d62a17ae | 365 | * time_t value in terms of stabilised absolute time. |
65efcfce LB |
366 | * replacement for POSIX time() |
367 | */ | |
d62a17ae | 368 | extern time_t rfapi_time(time_t *t); |
65efcfce | 369 | |
bf8d3d6a DL |
370 | DECLARE_MGROUP(RFAPI); |
371 | DECLARE_MTYPE(RFAPI_CFG); | |
372 | DECLARE_MTYPE(RFAPI_GROUP_CFG); | |
373 | DECLARE_MTYPE(RFAPI_L2_CFG); | |
374 | DECLARE_MTYPE(RFAPI_RFP_GROUP_CFG); | |
375 | DECLARE_MTYPE(RFAPI); | |
376 | DECLARE_MTYPE(RFAPI_DESC); | |
377 | DECLARE_MTYPE(RFAPI_IMPORTTABLE); | |
378 | DECLARE_MTYPE(RFAPI_MONITOR); | |
379 | DECLARE_MTYPE(RFAPI_MONITOR_ENCAP); | |
380 | DECLARE_MTYPE(RFAPI_NEXTHOP); | |
381 | DECLARE_MTYPE(RFAPI_VN_OPTION); | |
382 | DECLARE_MTYPE(RFAPI_UN_OPTION); | |
383 | DECLARE_MTYPE(RFAPI_WITHDRAW); | |
384 | DECLARE_MTYPE(RFAPI_RFG_NAME); | |
385 | DECLARE_MTYPE(RFAPI_ADB); | |
386 | DECLARE_MTYPE(RFAPI_ETI); | |
387 | DECLARE_MTYPE(RFAPI_NVE_ADDR); | |
388 | DECLARE_MTYPE(RFAPI_PREFIX_BAG); | |
389 | DECLARE_MTYPE(RFAPI_IT_EXTRA); | |
390 | DECLARE_MTYPE(RFAPI_INFO); | |
391 | DECLARE_MTYPE(RFAPI_ADDR); | |
392 | DECLARE_MTYPE(RFAPI_UPDATED_RESPONSE_QUEUE); | |
393 | DECLARE_MTYPE(RFAPI_RECENT_DELETE); | |
394 | DECLARE_MTYPE(RFAPI_L2ADDR_OPT); | |
395 | DECLARE_MTYPE(RFAPI_AP); | |
396 | DECLARE_MTYPE(RFAPI_MONITOR_ETH); | |
65efcfce | 397 | |
5ff06872 LB |
398 | |
399 | /* | |
400 | * Caller must supply an already-allocated rfd with the "caller" | |
401 | * fields already set (vn_addr, un_addr, callback, cookie) | |
402 | * The advertised_prefixes[] array elements should be NULL to | |
403 | * have this function set them to newly-allocated radix trees. | |
404 | */ | |
d62a17ae | 405 | extern int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd, |
406 | struct rfapi_nve_group_cfg *rfg); | |
5ff06872 | 407 | |
65efcfce | 408 | #endif /* _QUAGGA_BGP_RFAPI_PRIVATE_H */ |