]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* |
2 | * OSPF ABR functions. | |
3 | * Copyright (C) 1999, 2000 Alex Zinin, Toshiaki Takada | |
4 | * | |
5 | * This file is part of GNU Zebra. | |
6 | * | |
7 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2, or (at your option) any | |
10 | * later version. | |
11 | * | |
12 | * GNU Zebra is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with GNU Zebra; see the file COPYING. If not, write to the Free | |
19 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
20 | * 02111-1307, USA. | |
21 | */ | |
22 | ||
23 | ||
24 | #include <zebra.h> | |
25 | ||
26 | #include "thread.h" | |
27 | #include "memory.h" | |
28 | #include "linklist.h" | |
29 | #include "prefix.h" | |
30 | #include "if.h" | |
31 | #include "table.h" | |
32 | #include "vty.h" | |
33 | #include "filter.h" | |
34 | #include "plist.h" | |
35 | #include "log.h" | |
36 | ||
37 | #include "ospfd/ospfd.h" | |
38 | #include "ospfd/ospf_interface.h" | |
39 | #include "ospfd/ospf_ism.h" | |
40 | #include "ospfd/ospf_asbr.h" | |
41 | #include "ospfd/ospf_lsa.h" | |
42 | #include "ospfd/ospf_lsdb.h" | |
43 | #include "ospfd/ospf_neighbor.h" | |
44 | #include "ospfd/ospf_nsm.h" | |
45 | #include "ospfd/ospf_spf.h" | |
46 | #include "ospfd/ospf_route.h" | |
47 | #include "ospfd/ospf_ia.h" | |
48 | #include "ospfd/ospf_flood.h" | |
49 | #include "ospfd/ospf_abr.h" | |
50 | #include "ospfd/ospf_ase.h" | |
51 | #include "ospfd/ospf_zebra.h" | |
52 | #include "ospfd/ospf_dump.h" | |
53 | ||
54 | \f | |
55 | struct ospf_area_range * | |
56 | ospf_area_range_new (struct prefix_ipv4 *p) | |
57 | { | |
58 | struct ospf_area_range *range; | |
59 | ||
60 | range = XCALLOC (MTYPE_OSPF_AREA_RANGE, sizeof (struct ospf_area_range)); | |
61 | range->addr = p->prefix; | |
62 | range->masklen = p->prefixlen; | |
63 | range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC; | |
64 | ||
65 | return range; | |
66 | } | |
67 | ||
68 | void | |
69 | ospf_area_range_free (struct ospf_area_range *range) | |
70 | { | |
71 | XFREE (MTYPE_OSPF_AREA_RANGE, range); | |
72 | } | |
73 | ||
74 | void | |
75 | ospf_area_range_add (struct ospf_area *area, struct ospf_area_range *range) | |
76 | { | |
77 | struct route_node *rn; | |
78 | struct prefix_ipv4 p; | |
79 | ||
80 | p.family = AF_INET; | |
81 | p.prefixlen = range->masklen; | |
82 | p.prefix = range->addr; | |
83 | ||
84 | rn = route_node_get (area->ranges, (struct prefix *)&p); | |
85 | if (rn->info) | |
86 | route_unlock_node (rn); | |
87 | else | |
88 | rn->info = range; | |
89 | } | |
90 | ||
91 | void | |
92 | ospf_area_range_delete (struct ospf_area *area, struct ospf_area_range *range) | |
93 | { | |
94 | struct route_node *rn; | |
95 | struct prefix_ipv4 p; | |
96 | ||
97 | p.family = AF_INET; | |
98 | p.prefixlen = range->masklen; | |
99 | p.prefix = range->addr; | |
100 | ||
101 | rn = route_node_lookup (area->ranges, (struct prefix *)&p); | |
102 | if (rn) | |
103 | { | |
104 | ospf_area_range_free (rn->info); | |
105 | rn->info = NULL; | |
106 | route_unlock_node (rn); | |
107 | route_unlock_node (rn); | |
108 | } | |
109 | } | |
110 | ||
111 | struct ospf_area_range * | |
112 | ospf_area_range_lookup (struct ospf_area *area, struct prefix_ipv4 *p) | |
113 | { | |
114 | struct route_node *rn; | |
115 | ||
116 | rn = route_node_lookup (area->ranges, (struct prefix *)p); | |
117 | if (rn) | |
118 | { | |
119 | route_unlock_node (rn); | |
120 | return rn->info; | |
121 | } | |
122 | return NULL; | |
123 | } | |
124 | ||
125 | struct ospf_area_range * | |
126 | ospf_area_range_lookup_next (struct ospf_area *area, struct in_addr *range_net, | |
127 | int first) | |
128 | { | |
129 | struct route_node *rn; | |
130 | struct prefix_ipv4 p; | |
131 | struct ospf_area_range *find; | |
132 | ||
133 | p.family = AF_INET; | |
134 | p.prefixlen = IPV4_MAX_BITLEN; | |
135 | p.prefix = *range_net; | |
136 | ||
137 | if (first) | |
138 | rn = route_top (area->ranges); | |
139 | else | |
140 | { | |
141 | rn = route_node_get (area->ranges, (struct prefix *) &p); | |
142 | rn = route_next (rn); | |
143 | } | |
144 | ||
145 | for (; rn; rn = route_next (rn)) | |
146 | if (rn->info) | |
147 | break; | |
148 | ||
149 | if (rn && rn->info) | |
150 | { | |
151 | find = rn->info; | |
152 | *range_net = rn->p.u.prefix4; | |
153 | route_unlock_node (rn); | |
154 | return find; | |
155 | } | |
156 | return NULL; | |
157 | } | |
158 | ||
159 | struct ospf_area_range * | |
160 | ospf_area_range_match (struct ospf_area *area, struct prefix_ipv4 *p) | |
161 | { | |
162 | struct route_node *node; | |
163 | ||
164 | node = route_node_match (area->ranges, (struct prefix *) p); | |
165 | if (node) | |
166 | { | |
167 | route_unlock_node (node); | |
168 | return node->info; | |
169 | } | |
170 | return NULL; | |
171 | } | |
172 | ||
173 | struct ospf_area_range * | |
174 | ospf_area_range_match_any (struct ospf *ospf, struct prefix_ipv4 *p) | |
175 | { | |
176 | struct ospf_area_range *range; | |
177 | listnode node; | |
178 | ||
179 | for (node = listhead (ospf->areas); node; nextnode (node)) | |
180 | if ((range = ospf_area_range_match (node->data, p))) | |
181 | return range; | |
182 | ||
183 | return NULL; | |
184 | } | |
185 | ||
186 | int | |
187 | ospf_area_range_active (struct ospf_area_range *range) | |
188 | { | |
189 | return range->specifics; | |
190 | } | |
191 | ||
192 | int | |
193 | ospf_area_actively_attached (struct ospf_area *area) | |
194 | { | |
195 | return area->act_ints; | |
196 | } | |
197 | ||
198 | int | |
199 | ospf_area_range_set (struct ospf *ospf, struct in_addr area_id, | |
200 | struct prefix_ipv4 *p, int advertise) | |
201 | { | |
202 | struct ospf_area *area; | |
203 | struct ospf_area_range *range; | |
147193a2 | 204 | int ret = OSPF_AREA_ID_FORMAT_ADDRESS; |
718e3744 | 205 | |
147193a2 | 206 | area = ospf_area_get (ospf, area_id, ret); |
718e3744 | 207 | if (area == NULL) |
208 | return 0; | |
209 | ||
210 | range = ospf_area_range_lookup (area, p); | |
211 | if (range != NULL) | |
212 | { | |
213 | if ((CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE) | |
214 | && !CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE)) | |
215 | || (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE) | |
216 | && CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE))) | |
147193a2 | 217 | ospf_schedule_abr_task (ospf); |
718e3744 | 218 | } |
219 | else | |
220 | { | |
221 | range = ospf_area_range_new (p); | |
222 | ospf_area_range_add (area, range); | |
147193a2 | 223 | ospf_schedule_abr_task (ospf); |
718e3744 | 224 | } |
225 | ||
226 | if (CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE)) | |
227 | SET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE); | |
228 | else | |
229 | UNSET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE); | |
230 | ||
231 | return 1; | |
232 | } | |
233 | ||
234 | int | |
235 | ospf_area_range_cost_set (struct ospf *ospf, struct in_addr area_id, | |
236 | struct prefix_ipv4 *p, u_int32_t cost) | |
237 | { | |
238 | struct ospf_area *area; | |
239 | struct ospf_area_range *range; | |
147193a2 | 240 | int ret = OSPF_AREA_ID_FORMAT_ADDRESS; |
718e3744 | 241 | |
147193a2 | 242 | area = ospf_area_get (ospf, area_id, ret); |
718e3744 | 243 | if (area == NULL) |
244 | return 0; | |
245 | ||
246 | range = ospf_area_range_new (p); | |
247 | if (range == NULL) | |
248 | return 0; | |
249 | ||
250 | if (range->cost_config != cost) | |
251 | { | |
252 | range->cost_config = cost; | |
253 | if (ospf_area_range_active (range)) | |
147193a2 | 254 | ospf_schedule_abr_task (ospf); |
718e3744 | 255 | } |
256 | ||
257 | return 1; | |
258 | } | |
259 | ||
260 | int | |
261 | ospf_area_range_unset (struct ospf *ospf, struct in_addr area_id, | |
262 | struct prefix_ipv4 *p) | |
263 | { | |
264 | struct ospf_area *area; | |
265 | struct ospf_area_range *range; | |
266 | ||
147193a2 | 267 | area = ospf_area_lookup_by_area_id (ospf, area_id); |
718e3744 | 268 | if (area == NULL) |
269 | return 0; | |
270 | ||
271 | range = ospf_area_range_lookup (area, p); | |
272 | if (range == NULL) | |
273 | return 0; | |
274 | ||
275 | if (ospf_area_range_active (range)) | |
147193a2 | 276 | ospf_schedule_abr_task (ospf); |
718e3744 | 277 | |
278 | ospf_area_range_delete (area, range); | |
279 | ||
280 | return 1; | |
281 | } | |
282 | ||
283 | int | |
284 | ospf_area_range_substitute_set (struct ospf *ospf, struct in_addr area_id, | |
285 | struct prefix_ipv4 *p, struct prefix_ipv4 *s) | |
286 | { | |
287 | struct ospf_area *area; | |
288 | struct ospf_area_range *range; | |
147193a2 | 289 | int ret = OSPF_AREA_ID_FORMAT_ADDRESS; |
718e3744 | 290 | |
147193a2 | 291 | area = ospf_area_get (ospf, area_id, ret); |
718e3744 | 292 | range = ospf_area_range_lookup (area, p); |
293 | ||
294 | if (range != NULL) | |
295 | { | |
296 | if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE) || | |
297 | !CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) | |
147193a2 | 298 | ospf_schedule_abr_task (ospf); |
718e3744 | 299 | } |
300 | else | |
301 | { | |
302 | range = ospf_area_range_new (p); | |
303 | ospf_area_range_add (area, range); | |
147193a2 | 304 | ospf_schedule_abr_task (ospf); |
718e3744 | 305 | } |
306 | ||
307 | SET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE); | |
308 | SET_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE); | |
309 | range->subst_addr = s->prefix; | |
310 | range->subst_masklen = s->prefixlen; | |
311 | ||
312 | return 1; | |
313 | } | |
314 | ||
315 | int | |
316 | ospf_area_range_substitute_unset (struct ospf *ospf, struct in_addr area_id, | |
317 | struct prefix_ipv4 *p) | |
318 | { | |
319 | struct ospf_area *area; | |
320 | struct ospf_area_range *range; | |
321 | ||
147193a2 | 322 | area = ospf_area_lookup_by_area_id (ospf, area_id); |
718e3744 | 323 | if (area == NULL) |
324 | return 0; | |
325 | ||
326 | range = ospf_area_range_lookup (area, p); | |
327 | if (range == NULL) | |
328 | return 0; | |
329 | ||
330 | if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) | |
331 | if (ospf_area_range_active (range)) | |
147193a2 | 332 | ospf_schedule_abr_task (ospf); |
718e3744 | 333 | |
334 | UNSET_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE); | |
335 | range->subst_addr.s_addr = 0; | |
336 | range->subst_masklen = 0; | |
337 | ||
338 | return 1; | |
339 | } | |
340 | ||
341 | int | |
147193a2 | 342 | ospf_act_bb_connection (struct ospf *ospf) |
718e3744 | 343 | { |
147193a2 | 344 | if (ospf->backbone == NULL) |
718e3744 | 345 | return 0; |
346 | ||
147193a2 | 347 | return ospf->backbone->full_nbrs; |
718e3744 | 348 | } |
349 | ||
350 | /* Check area border router status. */ | |
351 | void | |
147193a2 | 352 | ospf_check_abr_status (struct ospf *ospf) |
718e3744 | 353 | { |
354 | struct ospf_area *area; | |
355 | listnode node; | |
356 | int bb_configured = 0; | |
357 | int bb_act_attached = 0; | |
358 | int areas_configured = 0; | |
359 | int areas_act_attached = 0; | |
147193a2 | 360 | u_char new_flags = ospf->flags; |
718e3744 | 361 | |
362 | if (IS_DEBUG_OSPF_EVENT) | |
363 | zlog_info ("ospf_check_abr_status(): Start"); | |
364 | ||
147193a2 | 365 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 366 | { |
367 | area = getdata (node); | |
368 | ||
369 | if (listcount (area->oiflist)) | |
370 | { | |
371 | areas_configured++; | |
372 | ||
373 | if (OSPF_IS_AREA_BACKBONE (area)) | |
374 | bb_configured = 1; | |
375 | } | |
376 | ||
377 | if (ospf_area_actively_attached (area)) | |
378 | { | |
379 | areas_act_attached++; | |
380 | ||
381 | if (OSPF_IS_AREA_BACKBONE (area)) | |
382 | bb_act_attached = 1; | |
383 | } | |
384 | } | |
385 | ||
386 | if (IS_DEBUG_OSPF_EVENT) | |
387 | { | |
388 | zlog_info ("ospf_check_abr_status(): looked through areas"); | |
389 | zlog_info ("ospf_check_abr_status(): bb_configured: %d", bb_configured); | |
390 | zlog_info ("ospf_check_abr_status(): bb_act_attached: %d", | |
391 | bb_act_attached); | |
392 | zlog_info ("ospf_check_abr_status(): areas_configured: %d", | |
393 | areas_configured); | |
394 | zlog_info ("ospf_check_abr_status(): areas_act_attached: %d", | |
395 | areas_act_attached); | |
396 | } | |
397 | ||
147193a2 | 398 | switch (ospf->abr_type) |
718e3744 | 399 | { |
400 | case OSPF_ABR_SHORTCUT: | |
401 | case OSPF_ABR_STAND: | |
402 | if (areas_act_attached > 1) | |
403 | SET_FLAG (new_flags, OSPF_FLAG_ABR); | |
404 | else | |
405 | UNSET_FLAG (new_flags, OSPF_FLAG_ABR); | |
406 | break; | |
407 | ||
408 | case OSPF_ABR_IBM: | |
409 | if ((areas_act_attached > 1) && bb_configured) | |
410 | SET_FLAG (new_flags, OSPF_FLAG_ABR); | |
411 | else | |
412 | UNSET_FLAG (new_flags, OSPF_FLAG_ABR); | |
413 | break; | |
414 | ||
415 | case OSPF_ABR_CISCO: | |
416 | if ((areas_configured > 1) && bb_act_attached) | |
417 | SET_FLAG (new_flags, OSPF_FLAG_ABR); | |
418 | else | |
419 | UNSET_FLAG (new_flags, OSPF_FLAG_ABR); | |
420 | break; | |
421 | default: | |
422 | break; | |
423 | } | |
424 | ||
147193a2 | 425 | if (new_flags != ospf->flags) |
718e3744 | 426 | { |
147193a2 | 427 | ospf_spf_calculate_schedule (ospf); |
718e3744 | 428 | if (IS_DEBUG_OSPF_EVENT) |
429 | zlog_info ("ospf_check_abr_status(): new router flags: %x",new_flags); | |
147193a2 | 430 | ospf->flags = new_flags; |
431 | OSPF_TIMER_ON (ospf->t_router_lsa_update, | |
718e3744 | 432 | ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY); |
433 | } | |
434 | } | |
435 | ||
436 | void | |
437 | ospf_abr_update_aggregate (struct ospf_area_range *range, | |
438 | struct ospf_route *or) | |
439 | { | |
440 | if (IS_DEBUG_OSPF_EVENT) | |
441 | zlog_info ("ospf_abr_update_aggregate(): Start"); | |
442 | ||
443 | if (range->cost_config != -1) | |
444 | { | |
445 | if (IS_DEBUG_OSPF_EVENT) | |
446 | zlog_info ("ospf_abr_update_aggregate(): use configured cost %d", | |
447 | range->cost_config); | |
448 | ||
449 | range->cost = range->cost_config; | |
450 | } | |
451 | else | |
452 | { | |
453 | if (range->specifics == 0) | |
454 | range->cost = or->cost; /* 1st time get 1st cost */ | |
455 | ||
456 | if (or->cost < range->cost) | |
457 | { | |
458 | if (IS_DEBUG_OSPF_EVENT) | |
459 | zlog_info ("ospf_abr_update_aggregate(): lowest cost, update"); | |
460 | ||
461 | range->cost = or->cost; | |
462 | } | |
463 | } | |
464 | ||
465 | range->specifics++; | |
466 | } | |
467 | ||
468 | static void | |
469 | set_metric (struct ospf_lsa *lsa, u_int32_t metric) | |
470 | { | |
471 | struct summary_lsa *header; | |
472 | u_char *mp; | |
473 | metric = htonl (metric); | |
474 | mp = (char *) &metric; | |
475 | mp++; | |
476 | header = (struct summary_lsa *) lsa->data; | |
477 | memcpy(header->metric, mp, 3); | |
478 | } | |
479 | ||
480 | #ifdef HAVE_NSSA | |
481 | int | |
482 | ospf_abr_check_nssa_range (struct prefix_ipv4 *p, u_int32_t cost, | |
483 | struct ospf_area *area) | |
484 | { | |
485 | /* The Type-7 is tested against the aggregated prefix and forwarded | |
486 | for lsa installation and flooding */ | |
487 | return 0; | |
488 | } | |
489 | ||
490 | /* ospf_abr_translate_nssa */ | |
491 | int | |
147193a2 | 492 | ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa) |
718e3744 | 493 | { |
494 | /* Incoming Type-7 or later aggregated Type-7 | |
495 | ||
496 | LSA is skipped if P-bit is off. | |
497 | LSA is aggregated if within range. | |
498 | ||
499 | The Type-7 is translated, Installed/Approved as a Type-5 into | |
500 | global LSDB, then Flooded through AS | |
501 | ||
502 | Later, any Unapproved Translated Type-5's are flushed/discarded */ | |
503 | ||
504 | struct ospf_lsa *dup; | |
505 | ||
506 | if (! CHECK_FLAG (lsa->data->options, OSPF_OPTION_NP)) | |
507 | { | |
508 | if (IS_DEBUG_OSPF_NSSA) | |
509 | zlog_info ("ospf_abr_nssa(): P-bit off, NO Translation"); | |
510 | return 0; | |
511 | } | |
512 | ||
513 | if (IS_DEBUG_OSPF_NSSA) | |
514 | zlog_info ("ospf_abr_nssa(): TRANSLATING 7 to 5"); | |
515 | ||
516 | /* No more P-bit. */ | |
517 | /* UNSET_FLAG (lsa->data->options, OSPF_OPTION_NP); */ | |
518 | ||
519 | /* Area where Aggregate testing will be inserted, just like summary | |
520 | advertisements */ | |
521 | /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */ | |
522 | ||
523 | /* Follow thru here means no aggregation */ | |
524 | dup = ospf_lsa_dup (lsa); /* keep LSDB intact, lock = 1 */ | |
525 | ||
526 | SET_FLAG (dup->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */ | |
527 | SET_FLAG (dup->flags, OSPF_LSA_APPROVED); /* So, do not remove it */ | |
528 | ||
529 | dup->data->type = OSPF_AS_EXTERNAL_LSA; /* make Type-5 */ | |
530 | ||
531 | ospf_lsa_checksum (dup->data); | |
532 | ||
147193a2 | 533 | ospf_lsa_install (area->ospf, NULL, dup); /* Install this Type-5 into LSDB, Lock = 2. */ |
718e3744 | 534 | |
147193a2 | 535 | ospf_flood_through_as (area->ospf, NULL, dup); /* flood non-NSSA/STUB areas */ |
718e3744 | 536 | |
537 | /* This translated Type-5 will go to all non-NSSA areas connected to | |
538 | this ABR; The Type-5 could come from any of the NSSA's connected | |
539 | to this ABR. */ | |
540 | ||
541 | return 0; | |
542 | } | |
543 | ||
544 | void | |
545 | ospf_abr_translate_nssa_range (struct prefix_ipv4 *p, u_int32_t cost) | |
546 | { | |
547 | /* The Type-7 is created from the aggregated prefix and forwarded | |
548 | for lsa installation and flooding... to be added... */ | |
549 | } | |
550 | #endif /* HAVE_NSSA */ | |
551 | ||
552 | void | |
553 | ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost, | |
554 | struct ospf_area *area) | |
555 | { | |
556 | struct ospf_lsa *lsa, *old = NULL; | |
557 | struct summary_lsa *sl = NULL; | |
558 | ||
559 | if (IS_DEBUG_OSPF_EVENT) | |
560 | zlog_info ("ospf_abr_announce_network_to_area(): Start"); | |
561 | ||
147193a2 | 562 | old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA, p, |
563 | area->ospf->router_id); | |
718e3744 | 564 | if (old) |
565 | { | |
566 | if (IS_DEBUG_OSPF_EVENT) | |
567 | zlog_info ("ospf_abr_announce_network_to_area(): old summary found"); | |
568 | sl = (struct summary_lsa *) old->data; | |
569 | ||
570 | if (IS_DEBUG_OSPF_EVENT) | |
571 | zlog_info ("ospf_abr_announce_network_to_area(): " | |
572 | "old metric: %d, new metric: %d", | |
573 | GET_METRIC (sl->metric), cost); | |
574 | } | |
575 | ||
576 | if (old && (GET_METRIC (sl->metric) == cost)) | |
577 | { | |
578 | if (IS_DEBUG_OSPF_EVENT) | |
579 | zlog_info ("ospf_abr_announce_network_to_area(): " | |
580 | "old summary approved"); | |
581 | SET_FLAG (old->flags, OSPF_LSA_APPROVED); | |
582 | } | |
583 | else | |
584 | { | |
585 | if (IS_DEBUG_OSPF_EVENT) | |
586 | zlog_info ("ospf_abr_announce_network_to_area(): " | |
587 | "creating new summary"); | |
588 | if (old) | |
589 | { | |
590 | ||
591 | set_metric (old, cost); | |
147193a2 | 592 | lsa = ospf_summary_lsa_refresh (area->ospf, old); |
718e3744 | 593 | /* This will flood through area. */ |
594 | } | |
595 | else | |
596 | { | |
597 | lsa = ospf_summary_lsa_originate (p, cost, area); | |
598 | /* This will flood through area. */ | |
599 | } | |
600 | ||
601 | ||
602 | SET_FLAG (lsa->flags, OSPF_LSA_APPROVED); | |
603 | if (IS_DEBUG_OSPF_EVENT) | |
604 | zlog_info ("ospf_abr_announce_network_to_area(): " | |
605 | "flooding new version of summary"); | |
606 | ||
607 | #ifndef HAVE_NSSA | |
608 | ospf_flood_through_area (area, NULL, lsa); | |
609 | #endif /* ! HAVE_NSSA */ | |
610 | } | |
611 | ||
612 | if (IS_DEBUG_OSPF_EVENT) | |
613 | zlog_info ("ospf_abr_announce_network_to_area(): Stop"); | |
614 | } | |
615 | ||
616 | int | |
617 | ospf_abr_nexthops_belong_to_area (struct ospf_route *or, | |
618 | struct ospf_area *area) | |
619 | { | |
620 | listnode node; | |
621 | ||
622 | for (node = listhead (or->path); node; nextnode (node)) | |
623 | { | |
624 | struct ospf_path *path = node->data; | |
625 | struct ospf_interface *oi = path->oi; | |
626 | ||
627 | if (oi != NULL) | |
628 | if (oi->area == area) | |
629 | return 1; | |
630 | } | |
631 | ||
632 | return 0; | |
633 | } | |
634 | ||
635 | int | |
636 | ospf_abr_should_accept (struct prefix *p, struct ospf_area *area) | |
637 | { | |
638 | if (IMPORT_NAME (area)) | |
639 | { | |
640 | if (IMPORT_LIST (area) == NULL) | |
641 | IMPORT_LIST (area) = access_list_lookup (AFI_IP, IMPORT_NAME (area)); | |
642 | ||
643 | if (IMPORT_LIST (area)) | |
644 | if (access_list_apply (IMPORT_LIST (area), p) == FILTER_DENY) | |
645 | return 0; | |
646 | } | |
647 | ||
648 | return 1; | |
649 | } | |
650 | ||
651 | int | |
652 | ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or, | |
653 | struct prefix *p) | |
654 | { | |
655 | if (PREFIX_NAME_IN (area)) | |
656 | { | |
657 | if (PREFIX_LIST_IN (area) == NULL) | |
658 | PREFIX_LIST_IN (area) = prefix_list_lookup (AFI_IP, | |
659 | PREFIX_NAME_IN (area)); | |
660 | if (PREFIX_LIST_IN (area)) | |
661 | if (prefix_list_apply (PREFIX_LIST_IN (area), p) != PREFIX_PERMIT) | |
662 | return 0; | |
663 | } | |
664 | return 1; | |
665 | } | |
666 | ||
667 | int | |
668 | ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or, | |
669 | struct prefix *p) | |
670 | { | |
671 | if (PREFIX_NAME_OUT (area)) | |
672 | { | |
673 | if (PREFIX_LIST_OUT (area) == NULL) | |
674 | PREFIX_LIST_OUT (area) = prefix_list_lookup (AFI_IP, | |
675 | PREFIX_NAME_OUT (area)); | |
676 | if (PREFIX_LIST_OUT (area)) | |
677 | if (prefix_list_apply (PREFIX_LIST_OUT (area), p) != PREFIX_PERMIT) | |
678 | return 0; | |
679 | } | |
680 | return 1; | |
681 | } | |
682 | ||
683 | void | |
147193a2 | 684 | ospf_abr_announce_network (struct ospf *ospf, |
685 | struct route_node *n, struct ospf_route *or) | |
718e3744 | 686 | { |
718e3744 | 687 | struct ospf_area_range *range; |
718e3744 | 688 | struct ospf_area *area, *or_area; |
147193a2 | 689 | struct prefix_ipv4 *p; |
690 | listnode node; | |
718e3744 | 691 | |
692 | if (IS_DEBUG_OSPF_EVENT) | |
693 | zlog_info ("ospf_abr_announce_network(): Start"); | |
694 | p = (struct prefix_ipv4 *) &n->p; | |
695 | ||
147193a2 | 696 | or_area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id); |
718e3744 | 697 | assert (or_area); |
698 | ||
147193a2 | 699 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 700 | { |
701 | area = getdata (node); | |
702 | ||
703 | if (IS_DEBUG_OSPF_EVENT) | |
704 | zlog_info ("ospf_abr_announce_network(): looking at area %s", | |
705 | inet_ntoa (area->area_id)); | |
706 | ||
707 | if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id)) | |
708 | continue; | |
709 | ||
710 | if (ospf_abr_nexthops_belong_to_area (or, area)) | |
711 | continue; | |
712 | ||
713 | if (!ospf_abr_should_accept (&n->p, area)) | |
714 | { | |
715 | if (IS_DEBUG_OSPF_EVENT) | |
716 | zlog_info ("ospf_abr_announce_network(): " | |
717 | "prefix %s/%d was denied by import-list", | |
718 | inet_ntoa (p->prefix), p->prefixlen); | |
719 | continue; | |
720 | } | |
721 | ||
722 | if (!ospf_abr_plist_in_check (area, or, &n->p)) | |
723 | { | |
724 | if (IS_DEBUG_OSPF_EVENT) | |
725 | zlog_info ("ospf_abr_announce_network(): " | |
726 | "prefix %s/%d was denied by prefix-list", | |
727 | inet_ntoa (p->prefix), p->prefixlen); | |
728 | continue; | |
729 | } | |
730 | ||
731 | if (area->external_routing != OSPF_AREA_DEFAULT && area->no_summary) | |
732 | { | |
733 | if (IS_DEBUG_OSPF_EVENT) | |
734 | zlog_info ("ospf_abr_announce_network(): " | |
735 | "area %s is stub and no_summary", | |
736 | inet_ntoa (area->area_id)); | |
737 | continue; | |
738 | } | |
739 | ||
740 | if (or->path_type == OSPF_PATH_INTER_AREA) | |
741 | { | |
742 | if (IS_DEBUG_OSPF_EVENT) | |
743 | zlog_info ("ospf_abr_announce_network(): this is " | |
744 | "inter-area route to %s/%d", | |
745 | inet_ntoa (p->prefix), p->prefixlen); | |
746 | ||
747 | if (!OSPF_IS_AREA_BACKBONE (area)) | |
748 | ospf_abr_announce_network_to_area (p, or->cost, area); | |
749 | } | |
750 | ||
751 | if (or->path_type == OSPF_PATH_INTRA_AREA) | |
752 | { | |
753 | if (IS_DEBUG_OSPF_EVENT) | |
754 | zlog_info ("ospf_abr_announce_network(): " | |
755 | "this is intra-area route to %s/%d", | |
756 | inet_ntoa (p->prefix), p->prefixlen); | |
757 | if ((range = ospf_area_range_match (or_area, p)) && | |
758 | !ospf_area_is_transit (area)) | |
759 | ospf_abr_update_aggregate (range, or); | |
760 | else | |
761 | ospf_abr_announce_network_to_area (p, or->cost, area); | |
762 | } | |
763 | } | |
764 | } | |
765 | ||
766 | int | |
147193a2 | 767 | ospf_abr_should_announce (struct ospf *ospf, |
768 | struct prefix *p, struct ospf_route *or) | |
718e3744 | 769 | { |
147193a2 | 770 | struct ospf_area *area; |
771 | ||
772 | area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id); | |
718e3744 | 773 | |
774 | assert (area); | |
775 | ||
776 | if (EXPORT_NAME (area)) | |
777 | { | |
778 | if (EXPORT_LIST (area) == NULL) | |
779 | EXPORT_LIST (area) = access_list_lookup (AFI_IP, EXPORT_NAME (area)); | |
780 | ||
781 | if (EXPORT_LIST (area)) | |
782 | if (access_list_apply (EXPORT_LIST (area), p) == FILTER_DENY) | |
783 | return 0; | |
784 | } | |
785 | ||
786 | return 1; | |
787 | } | |
788 | ||
789 | #ifdef HAVE_NSSA | |
790 | void | |
147193a2 | 791 | ospf_abr_process_nssa_translates (struct ospf *ospf) |
718e3744 | 792 | { |
793 | /* Scan through all NSSA_LSDB records for all areas; | |
794 | ||
795 | If P-bit is on, translate all Type-7's to 5's and aggregate or | |
796 | flood install as approved in Type-5 LSDB with XLATE Flag on | |
797 | later, do same for all aggregates... At end, DISCARD all | |
798 | remaining UNAPPROVED Type-5's (Aggregate is for future ) */ | |
799 | listnode node; | |
800 | struct ospf_area *area; | |
147193a2 | 801 | struct route_node *rn; |
802 | struct ospf_lsa *lsa; | |
718e3744 | 803 | |
804 | if (IS_DEBUG_OSPF_NSSA) | |
805 | zlog_info ("ospf_abr_process_nssa_translates(): Start"); | |
806 | ||
147193a2 | 807 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 808 | { |
809 | area = getdata (node); | |
810 | ||
811 | if (! area->NSSATranslator) | |
812 | continue; /* skip if not translator */ | |
813 | ||
814 | if (area->external_routing != OSPF_AREA_NSSA) | |
815 | continue; /* skip if not Nssa Area */ | |
816 | ||
817 | if (IS_DEBUG_OSPF_NSSA) | |
818 | zlog_info ("ospf_abr_process_nssa_translates(): " | |
819 | "looking at area %s", inet_ntoa (area->area_id)); | |
820 | ||
147193a2 | 821 | LSDB_LOOP (NSSA_LSDB (area), rn, lsa) |
822 | ospf_abr_translate_nssa (area, lsa); | |
718e3744 | 823 | } |
824 | ||
825 | if (IS_DEBUG_OSPF_NSSA) | |
826 | zlog_info ("ospf_abr_process_nssa_translates(): Stop"); | |
827 | ||
828 | } | |
829 | #endif /* HAVE_NSSA */ | |
830 | ||
831 | void | |
147193a2 | 832 | ospf_abr_process_network_rt (struct ospf *ospf, |
833 | struct route_table *rt) | |
718e3744 | 834 | { |
718e3744 | 835 | struct ospf_area *area; |
147193a2 | 836 | struct ospf_route *or; |
837 | struct route_node *rn; | |
718e3744 | 838 | |
839 | if (IS_DEBUG_OSPF_EVENT) | |
840 | zlog_info ("ospf_abr_process_network_rt(): Start"); | |
841 | ||
842 | for (rn = route_top (rt); rn; rn = route_next (rn)) | |
843 | { | |
844 | if ((or = rn->info) == NULL) | |
845 | continue; | |
846 | ||
147193a2 | 847 | if (!(area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id))) |
718e3744 | 848 | { |
849 | if (IS_DEBUG_OSPF_EVENT) | |
850 | zlog_info ("ospf_abr_process_network_rt(): area %s no longer exists", | |
851 | inet_ntoa (or->u.std.area_id)); | |
852 | continue; | |
853 | } | |
854 | ||
855 | if (IS_DEBUG_OSPF_EVENT) | |
856 | zlog_info ("ospf_abr_process_network_rt(): this is a route to %s/%d", | |
857 | inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen); | |
858 | if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL) | |
859 | { | |
860 | if (IS_DEBUG_OSPF_EVENT) | |
861 | zlog_info ("ospf_abr_process_network_rt(): " | |
862 | "this is an External router, skipping"); | |
863 | continue; | |
864 | } | |
865 | ||
866 | if (or->cost >= OSPF_LS_INFINITY) | |
867 | { | |
868 | if (IS_DEBUG_OSPF_EVENT) | |
869 | zlog_info ("ospf_abr_process_network_rt():" | |
870 | " this route's cost is infinity, skipping"); | |
871 | continue; | |
872 | } | |
873 | ||
874 | if (or->type == OSPF_DESTINATION_DISCARD) | |
875 | { | |
876 | if (IS_DEBUG_OSPF_EVENT) | |
877 | zlog_info ("ospf_abr_process_network_rt():" | |
878 | " this is a discard entry, skipping"); | |
879 | continue; | |
880 | } | |
881 | ||
882 | if (or->path_type == OSPF_PATH_INTRA_AREA && | |
147193a2 | 883 | !ospf_abr_should_announce (ospf, &rn->p, or)) |
718e3744 | 884 | { |
885 | if (IS_DEBUG_OSPF_EVENT) | |
886 | zlog_info("ospf_abr_process_network_rt(): denied by export-list"); | |
887 | continue; | |
888 | } | |
889 | ||
890 | if (or->path_type == OSPF_PATH_INTRA_AREA && | |
891 | !ospf_abr_plist_out_check (area, or, &rn->p)) | |
892 | { | |
893 | if (IS_DEBUG_OSPF_EVENT) | |
894 | zlog_info("ospf_abr_process_network_rt(): denied by prefix-list"); | |
895 | continue; | |
896 | } | |
897 | ||
898 | if ((or->path_type == OSPF_PATH_INTER_AREA) && | |
899 | !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) | |
900 | { | |
901 | if (IS_DEBUG_OSPF_EVENT) | |
902 | zlog_info ("ospf_abr_process_network_rt():" | |
903 | " this is route is not backbone one, skipping"); | |
904 | continue; | |
905 | } | |
906 | ||
907 | ||
147193a2 | 908 | if ((ospf->abr_type == OSPF_ABR_CISCO) || |
909 | (ospf->abr_type == OSPF_ABR_IBM)) | |
718e3744 | 910 | |
147193a2 | 911 | if (!ospf_act_bb_connection (ospf) && |
718e3744 | 912 | or->path_type != OSPF_PATH_INTRA_AREA) |
913 | { | |
914 | if (IS_DEBUG_OSPF_EVENT) | |
915 | zlog_info ("ospf_abr_process_network_rt(): ALT ABR: " | |
916 | "No BB connection, skip not intra-area routes"); | |
917 | continue; | |
918 | } | |
919 | ||
920 | if (IS_DEBUG_OSPF_EVENT) | |
921 | zlog_info ("ospf_abr_process_network_rt(): announcing"); | |
147193a2 | 922 | ospf_abr_announce_network (ospf, rn, or); |
718e3744 | 923 | } |
924 | ||
925 | if (IS_DEBUG_OSPF_EVENT) | |
926 | zlog_info ("ospf_abr_process_network_rt(): Stop"); | |
927 | } | |
928 | ||
929 | void | |
930 | ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost, | |
931 | struct ospf_area *area) | |
932 | { | |
933 | struct ospf_lsa *lsa, *old = NULL; | |
934 | struct summary_lsa *slsa = NULL; | |
935 | ||
936 | if (IS_DEBUG_OSPF_EVENT) | |
937 | zlog_info ("ospf_abr_announce_rtr_to_area(): Start"); | |
938 | ||
147193a2 | 939 | old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_ASBR_SUMMARY_LSA, |
940 | p, area->ospf->router_id); | |
718e3744 | 941 | if (old) |
942 | { | |
943 | if (IS_DEBUG_OSPF_EVENT) | |
944 | zlog_info ("ospf_abr_announce_rtr_to_area(): old summary found"); | |
945 | slsa = (struct summary_lsa *) old->data; | |
946 | ||
947 | if (IS_DEBUG_OSPF_EVENT) | |
948 | zlog_info ("ospf_abr_announce_network_to_area(): " | |
949 | "old metric: %d, new metric: %d", | |
950 | GET_METRIC (slsa->metric), cost); | |
951 | } | |
952 | ||
953 | if (old && (GET_METRIC (slsa->metric) == cost)) | |
954 | { | |
955 | if (IS_DEBUG_OSPF_EVENT) | |
956 | zlog_info ("ospf_abr_announce_rtr_to_area(): old summary approved"); | |
957 | SET_FLAG (old->flags, OSPF_LSA_APPROVED); | |
958 | } | |
959 | else | |
960 | { | |
961 | if (IS_DEBUG_OSPF_EVENT) | |
962 | zlog_info ("ospf_abr_announce_rtr_to_area(): 2.2"); | |
963 | ||
964 | if (old) | |
965 | { | |
966 | set_metric (old, cost); | |
147193a2 | 967 | lsa = ospf_summary_asbr_lsa_refresh (area->ospf, old); |
718e3744 | 968 | } |
969 | else | |
970 | lsa = ospf_summary_asbr_lsa_originate (p, cost, area); | |
971 | ||
972 | if (IS_DEBUG_OSPF_EVENT) | |
973 | zlog_info ("ospf_abr_announce_rtr_to_area(): " | |
974 | "flooding new version of summary"); | |
975 | /* | |
976 | zlog_info ("ospf_abr_announce_rtr_to_area(): creating new summary"); | |
977 | lsa = ospf_summary_asbr_lsa (p, cost, area, old); */ | |
978 | ||
979 | SET_FLAG (lsa->flags, OSPF_LSA_APPROVED); | |
980 | /* ospf_flood_through_area (area, NULL, lsa);*/ | |
981 | } | |
982 | ||
983 | if (IS_DEBUG_OSPF_EVENT) | |
984 | zlog_info ("ospf_abr_announce_rtr_to_area(): Stop"); | |
985 | } | |
986 | ||
987 | ||
988 | void | |
147193a2 | 989 | ospf_abr_announce_rtr (struct ospf *ospf, |
990 | struct prefix_ipv4 *p, struct ospf_route *or) | |
718e3744 | 991 | { |
992 | listnode node; | |
993 | struct ospf_area *area; | |
994 | ||
995 | if (IS_DEBUG_OSPF_EVENT) | |
996 | zlog_info ("ospf_abr_announce_rtr(): Start"); | |
997 | ||
147193a2 | 998 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 999 | { |
1000 | area = getdata (node); | |
1001 | ||
1002 | if (IS_DEBUG_OSPF_EVENT) | |
1003 | zlog_info ("ospf_abr_announce_rtr(): looking at area %s", | |
1004 | inet_ntoa (area->area_id)); | |
1005 | ||
1006 | if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id)) | |
1007 | continue; | |
1008 | ||
1009 | if (ospf_abr_nexthops_belong_to_area (or, area)) | |
1010 | continue; | |
1011 | ||
1012 | if (area->external_routing != OSPF_AREA_DEFAULT) | |
1013 | { | |
1014 | if (IS_DEBUG_OSPF_EVENT) | |
1015 | zlog_info ("ospf_abr_announce_network(): " | |
1016 | "area %s doesn't support external routing", | |
1017 | inet_ntoa(area->area_id)); | |
1018 | continue; | |
1019 | } | |
1020 | ||
1021 | if (or->path_type == OSPF_PATH_INTER_AREA) | |
1022 | { | |
1023 | if (IS_DEBUG_OSPF_EVENT) | |
1024 | zlog_info ("ospf_abr_announce_rtr(): " | |
1025 | "this is inter-area route to %s", inet_ntoa (p->prefix)); | |
1026 | if (!OSPF_IS_AREA_BACKBONE (area)) | |
1027 | ospf_abr_announce_rtr_to_area (p, or->cost, area); | |
1028 | } | |
1029 | ||
1030 | if (or->path_type == OSPF_PATH_INTRA_AREA) | |
1031 | { | |
1032 | if (IS_DEBUG_OSPF_EVENT) | |
1033 | zlog_info ("ospf_abr_announce_rtr(): " | |
1034 | "this is intra-area route to %s", inet_ntoa (p->prefix)); | |
1035 | ospf_abr_announce_rtr_to_area (p, or->cost, area); | |
1036 | } | |
1037 | } | |
1038 | ||
1039 | if (IS_DEBUG_OSPF_EVENT) | |
1040 | zlog_info ("ospf_abr_announce_rtr(): Stop"); | |
1041 | } | |
1042 | ||
1043 | void | |
147193a2 | 1044 | ospf_abr_process_router_rt (struct ospf *ospf, struct route_table *rt) |
718e3744 | 1045 | { |
718e3744 | 1046 | struct ospf_route *or; |
147193a2 | 1047 | struct route_node *rn; |
718e3744 | 1048 | struct list *l; |
1049 | ||
1050 | if (IS_DEBUG_OSPF_EVENT) | |
1051 | zlog_info ("ospf_abr_process_router_rt(): Start"); | |
1052 | ||
1053 | for (rn = route_top (rt); rn; rn = route_next (rn)) | |
1054 | { | |
1055 | listnode node; | |
1056 | char flag = 0; | |
1057 | struct ospf_route *best = NULL; | |
1058 | ||
1059 | if (rn->info == NULL) | |
1060 | continue; | |
1061 | ||
1062 | l = rn->info; | |
1063 | ||
1064 | if (IS_DEBUG_OSPF_EVENT) | |
1065 | zlog_info ("ospf_abr_process_router_rt(): this is a route to %s", | |
1066 | inet_ntoa (rn->p.u.prefix4)); | |
1067 | ||
1068 | for (node = listhead (l); node; nextnode (node)) | |
1069 | { | |
1070 | or = getdata (node); | |
1071 | if (or == NULL) | |
1072 | continue; | |
1073 | ||
147193a2 | 1074 | if (!ospf_area_lookup_by_area_id (ospf, or->u.std.area_id)) |
718e3744 | 1075 | { |
1076 | if (IS_DEBUG_OSPF_EVENT) | |
1077 | zlog_info ("ospf_abr_process_router_rt(): area %s no longer exists", | |
1078 | inet_ntoa (or->u.std.area_id)); | |
1079 | continue; | |
1080 | } | |
1081 | ||
1082 | ||
1083 | if (!CHECK_FLAG (or->u.std.flags, ROUTER_LSA_EXTERNAL)) | |
1084 | { | |
1085 | if (IS_DEBUG_OSPF_EVENT) | |
1086 | zlog_info ("ospf_abr_process_router_rt(): " | |
1087 | "This is not an ASBR, skipping"); | |
1088 | continue; | |
1089 | } | |
1090 | ||
1091 | if (!flag) | |
1092 | { | |
147193a2 | 1093 | best = ospf_find_asbr_route (ospf, rt, |
1094 | (struct prefix_ipv4 *) &rn->p); | |
718e3744 | 1095 | flag = 1; |
1096 | } | |
1097 | ||
1098 | if (best == NULL) | |
1099 | continue; | |
1100 | ||
1101 | if (or != best) | |
1102 | { | |
1103 | if (IS_DEBUG_OSPF_EVENT) | |
1104 | zlog_info ("ospf_abr_process_router_rt(): " | |
1105 | "This route is not the best among possible, skipping"); | |
1106 | continue; | |
1107 | } | |
1108 | ||
1109 | if (or->path_type == OSPF_PATH_INTER_AREA && | |
1110 | !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) | |
1111 | { | |
1112 | if (IS_DEBUG_OSPF_EVENT) | |
1113 | zlog_info ("ospf_abr_process_router_rt(): " | |
1114 | "This route is not a backbone one, skipping"); | |
1115 | continue; | |
1116 | } | |
1117 | ||
1118 | if (or->cost >= OSPF_LS_INFINITY) | |
1119 | { | |
1120 | if (IS_DEBUG_OSPF_EVENT) | |
1121 | zlog_info ("ospf_abr_process_router_rt(): " | |
1122 | "This route has LS_INFINITY metric, skipping"); | |
1123 | continue; | |
1124 | } | |
1125 | ||
147193a2 | 1126 | if (ospf->abr_type == OSPF_ABR_CISCO |
1127 | || ospf->abr_type == OSPF_ABR_IBM) | |
1128 | if (!ospf_act_bb_connection (ospf) | |
1129 | && or->path_type != OSPF_PATH_INTRA_AREA) | |
718e3744 | 1130 | { |
1131 | if (IS_DEBUG_OSPF_EVENT) | |
1132 | zlog_info("ospf_abr_process_network_rt(): ALT ABR: " | |
1133 | "No BB connection, skip not intra-area routes"); | |
1134 | continue; | |
1135 | } | |
1136 | ||
147193a2 | 1137 | ospf_abr_announce_rtr (ospf, (struct prefix_ipv4 *) &rn->p, or); |
718e3744 | 1138 | |
1139 | } | |
1140 | ||
1141 | } | |
1142 | ||
1143 | if (IS_DEBUG_OSPF_EVENT) | |
1144 | zlog_info ("ospf_abr_process_router_rt(): Stop"); | |
1145 | } | |
1146 | ||
1147 | #ifdef HAVE_NSSA | |
718e3744 | 1148 | void |
147193a2 | 1149 | ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */ |
718e3744 | 1150 | { |
147193a2 | 1151 | struct ospf_lsa *lsa; |
1152 | struct route_node *rn; | |
1153 | ||
718e3744 | 1154 | if (IS_DEBUG_OSPF_NSSA) |
1155 | zlog_info ("ospf_abr_unapprove_translates(): Start"); | |
1156 | ||
1157 | /* NSSA Translator is not checked, because it may have gone away, | |
1158 | and we would want to flush any residuals anyway */ | |
1159 | ||
147193a2 | 1160 | LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) |
1161 | if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) | |
1162 | UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); | |
718e3744 | 1163 | |
1164 | if (IS_DEBUG_OSPF_NSSA) | |
1165 | zlog_info ("ospf_abr_unapprove_translates(): Stop"); | |
1166 | } | |
1167 | #endif /* HAVE_NSSA */ | |
1168 | ||
718e3744 | 1169 | void |
147193a2 | 1170 | ospf_abr_unapprove_summaries (struct ospf *ospf) |
718e3744 | 1171 | { |
1172 | listnode node; | |
1173 | struct ospf_area *area; | |
147193a2 | 1174 | struct route_node *rn; |
1175 | struct ospf_lsa *lsa; | |
718e3744 | 1176 | |
1177 | if (IS_DEBUG_OSPF_EVENT) | |
1178 | zlog_info ("ospf_abr_unapprove_summaries(): Start"); | |
1179 | ||
147193a2 | 1180 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 1181 | { |
1182 | area = getdata (node); | |
147193a2 | 1183 | LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) |
1184 | if (ospf_lsa_is_self_originated (ospf, lsa)) | |
1185 | UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); | |
1186 | ||
1187 | LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) | |
1188 | if (ospf_lsa_is_self_originated (ospf, lsa)) | |
1189 | UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); | |
718e3744 | 1190 | } |
1191 | ||
1192 | if (IS_DEBUG_OSPF_EVENT) | |
1193 | zlog_info ("ospf_abr_unapprove_summaries(): Stop"); | |
1194 | } | |
1195 | ||
1196 | void | |
147193a2 | 1197 | ospf_abr_prepare_aggregates (struct ospf *ospf) |
718e3744 | 1198 | { |
1199 | listnode node; | |
1200 | struct route_node *rn; | |
1201 | struct ospf_area_range *range; | |
1202 | ||
1203 | if (IS_DEBUG_OSPF_EVENT) | |
1204 | zlog_info ("ospf_abr_prepare_aggregates(): Start"); | |
1205 | ||
147193a2 | 1206 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 1207 | { |
1208 | struct ospf_area *area = getdata (node); | |
1209 | ||
1210 | for (rn = route_top (area->ranges); rn; rn = route_next (rn)) | |
1211 | if ((range = rn->info) != NULL) | |
1212 | { | |
1213 | range->cost = 0; | |
1214 | range->specifics = 0; | |
1215 | } | |
1216 | } | |
1217 | ||
1218 | if (IS_DEBUG_OSPF_EVENT) | |
1219 | zlog_info ("ospf_abr_prepare_aggregates(): Stop"); | |
1220 | } | |
1221 | ||
1222 | void | |
147193a2 | 1223 | ospf_abr_announce_aggregates (struct ospf *ospf) |
718e3744 | 1224 | { |
1225 | struct ospf_area *area, *ar; | |
1226 | struct ospf_area_range *range; | |
1227 | struct route_node *rn; | |
1228 | struct prefix_ipv4 p; | |
1229 | listnode node, n; | |
1230 | ||
1231 | if (IS_DEBUG_OSPF_EVENT) | |
1232 | zlog_info ("ospf_abr_announce_aggregates(): Start"); | |
1233 | ||
147193a2 | 1234 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 1235 | { |
1236 | area = getdata (node); | |
1237 | ||
1238 | if (IS_DEBUG_OSPF_EVENT) | |
1239 | zlog_info ("ospf_abr_announce_aggregates(): looking at area %s", | |
1240 | inet_ntoa (area->area_id)); | |
1241 | ||
1242 | for (rn = route_top (area->ranges); rn; rn = route_next (rn)) | |
1243 | if ((range = rn->info)) | |
1244 | { | |
1245 | if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)) | |
1246 | { | |
1247 | if (IS_DEBUG_OSPF_EVENT) | |
1248 | zlog_info ("ospf_abr_announce_aggregates():" | |
1249 | " discarding suppress-ranges"); | |
1250 | continue; | |
1251 | } | |
1252 | ||
1253 | p.family = AF_INET; | |
1254 | p.prefix = range->addr; | |
1255 | p.prefixlen = range->masklen; | |
1256 | ||
1257 | if (IS_DEBUG_OSPF_EVENT) | |
1258 | zlog_info ("ospf_abr_announce_aggregates():" | |
1259 | " this is range: %s/%d", | |
1260 | inet_ntoa (p.prefix), p.prefixlen); | |
1261 | ||
1262 | if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) | |
1263 | { | |
1264 | p.family = AF_INET; | |
1265 | p.prefix = range->subst_addr; | |
1266 | p.prefixlen = range->subst_masklen; | |
1267 | } | |
1268 | ||
1269 | if (range->specifics) | |
1270 | { | |
1271 | if (IS_DEBUG_OSPF_EVENT) | |
1272 | zlog_info ("ospf_abr_announce_aggregates(): active range"); | |
1273 | ||
147193a2 | 1274 | for (n = listhead (ospf->areas); n; nextnode (n)) |
718e3744 | 1275 | { |
1276 | ar = getdata (n); | |
1277 | if (ar == area) | |
1278 | continue; | |
1279 | ||
1280 | /* We do not check nexthops here, because | |
1281 | intra-area routes can be associated with | |
1282 | one area only */ | |
1283 | ||
1284 | /* backbone routes are not summarized | |
1285 | when announced into transit areas */ | |
1286 | ||
1287 | if (ospf_area_is_transit (ar) && | |
1288 | OSPF_IS_AREA_BACKBONE (area)) | |
1289 | { | |
1290 | if (IS_DEBUG_OSPF_EVENT) | |
1291 | zlog_info ("ospf_abr_announce_aggregates(): Skipping " | |
1292 | "announcement of BB aggregate into" | |
1293 | " a transit area"); | |
1294 | continue; | |
1295 | } | |
1296 | ospf_abr_announce_network_to_area (&p, range->cost, ar); | |
1297 | } | |
1298 | } | |
1299 | } | |
1300 | } | |
1301 | ||
1302 | if (IS_DEBUG_OSPF_EVENT) | |
1303 | zlog_info ("ospf_abr_announce_aggregates(): Stop"); | |
1304 | } | |
1305 | ||
1306 | #ifdef HAVE_NSSA | |
1307 | void | |
147193a2 | 1308 | ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */ |
718e3744 | 1309 | { |
1310 | listnode node; /*, n; */ | |
1311 | struct ospf_area *area; /*, *ar; */ | |
1312 | struct route_node *rn; | |
1313 | struct ospf_area_range *range; | |
1314 | struct prefix_ipv4 p; | |
1315 | ||
1316 | if (IS_DEBUG_OSPF_NSSA) | |
1317 | zlog_info ("ospf_abr_send_nssa_aggregates(): Start"); | |
1318 | ||
147193a2 | 1319 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 1320 | { |
1321 | area = getdata (node); | |
1322 | ||
1323 | if (! area->NSSATranslator) | |
1324 | continue; | |
1325 | ||
1326 | if (IS_DEBUG_OSPF_NSSA) | |
1327 | zlog_info ("ospf_abr_send_nssa_aggregates(): looking at area %s", | |
1328 | inet_ntoa (area->area_id)); | |
1329 | ||
1330 | for (rn = route_top (area->ranges); rn; rn = route_next (rn)) | |
1331 | { | |
1332 | if (rn->info == NULL) | |
1333 | continue; | |
1334 | ||
1335 | range = rn->info; | |
1336 | ||
1337 | if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)) | |
1338 | { | |
1339 | if (IS_DEBUG_OSPF_NSSA) | |
1340 | zlog_info ("ospf_abr_send_nssa_aggregates():" | |
1341 | " discarding suppress-ranges"); | |
1342 | continue; | |
1343 | } | |
1344 | ||
1345 | p.family = AF_INET; | |
1346 | p.prefix = range->addr; | |
1347 | p.prefixlen = range->masklen; | |
1348 | ||
1349 | if (IS_DEBUG_OSPF_NSSA) | |
1350 | zlog_info ("ospf_abr_send_nssa_aggregates():" | |
1351 | " this is range: %s/%d", | |
1352 | inet_ntoa (p.prefix), p.prefixlen); | |
1353 | ||
1354 | if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) | |
1355 | { | |
1356 | p.family = AF_INET; | |
1357 | p.prefix = range->subst_addr; | |
1358 | p.prefixlen = range->subst_masklen; | |
1359 | } | |
1360 | ||
1361 | if (range->specifics) | |
1362 | { | |
1363 | if (IS_DEBUG_OSPF_NSSA) | |
1364 | zlog_info ("ospf_abr_send_nssa_aggregates(): active range"); | |
1365 | ||
1366 | /* Fetch LSA-Type-7 from aggregate prefix, and then | |
1367 | translate, Install (as Type-5), Approve, and Flood */ | |
1368 | ospf_abr_translate_nssa_range (&p, range->cost); | |
1369 | } /* if (range->specifics)*/ | |
1370 | } /* all area ranges*/ | |
1371 | } /* all areas */ | |
1372 | ||
1373 | if (IS_DEBUG_OSPF_NSSA) | |
1374 | zlog_info ("ospf_abr_send_nssa_aggregates(): Stop"); | |
1375 | } | |
1376 | ||
1377 | void | |
147193a2 | 1378 | ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */ |
718e3744 | 1379 | { |
1380 | listnode node; | |
1381 | struct ospf_area *area; | |
1382 | struct prefix_ipv4 p; | |
1383 | ||
147193a2 | 1384 | if (! IS_OSPF_ABR (ospf)) |
718e3744 | 1385 | return; |
1386 | ||
1387 | if (IS_DEBUG_OSPF_NSSA) | |
1388 | zlog_info ("ospf_abr_announce_stub_defaults(): Start"); | |
1389 | ||
1390 | p.family = AF_INET; | |
1391 | p.prefix.s_addr = OSPF_DEFAULT_DESTINATION; | |
1392 | p.prefixlen = 0; | |
1393 | ||
147193a2 | 1394 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 1395 | { |
1396 | area = getdata (node); | |
1397 | if (IS_DEBUG_OSPF_NSSA) | |
1398 | zlog_info ("ospf_abr_announce_nssa_defaults(): looking at area %s", | |
1399 | inet_ntoa (area->area_id)); | |
1400 | ||
1401 | if (area->external_routing != OSPF_AREA_NSSA) | |
1402 | continue; | |
1403 | ||
1404 | if (OSPF_IS_AREA_BACKBONE (area)) | |
1405 | continue; /* Sanity Check */ | |
1406 | ||
1407 | /* if (!TranslatorRole continue V 1.0 look for "always" conf */ | |
1408 | if (area->NSSATranslator) | |
1409 | { | |
1410 | if (IS_DEBUG_OSPF_NSSA) | |
1411 | zlog_info ("ospf_abr_announce_nssa_defaults(): " | |
1412 | "announcing 0.0.0.0/0 to this nssa"); | |
1413 | /* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */ | |
1414 | } | |
1415 | } | |
1416 | } | |
1417 | #endif /* HAVE_NSSA */ | |
1418 | ||
1419 | void | |
147193a2 | 1420 | ospf_abr_announce_stub_defaults (struct ospf *ospf) |
718e3744 | 1421 | { |
1422 | listnode node; | |
1423 | struct ospf_area *area; | |
1424 | struct prefix_ipv4 p; | |
1425 | ||
147193a2 | 1426 | if (! IS_OSPF_ABR (ospf)) |
718e3744 | 1427 | return; |
1428 | ||
1429 | if (IS_DEBUG_OSPF_EVENT) | |
1430 | zlog_info ("ospf_abr_announce_stub_defaults(): Start"); | |
1431 | ||
1432 | p.family = AF_INET; | |
1433 | p.prefix.s_addr = OSPF_DEFAULT_DESTINATION; | |
1434 | p.prefixlen = 0; | |
1435 | ||
147193a2 | 1436 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 1437 | { |
1438 | area = getdata (node); | |
1439 | if (IS_DEBUG_OSPF_EVENT) | |
1440 | zlog_info ("ospf_abr_announce_stub_defaults(): looking at area %s", | |
1441 | inet_ntoa (area->area_id)); | |
1442 | ||
1443 | #ifdef HAVE_NSSA | |
1444 | if (area->external_routing != OSPF_AREA_STUB) | |
1445 | #else /* ! HAVE_NSSA */ | |
1446 | if (area->external_routing == OSPF_AREA_DEFAULT) | |
1447 | #endif /* HAVE_NSSA */ | |
1448 | continue; | |
1449 | ||
1450 | if (OSPF_IS_AREA_BACKBONE (area)) | |
1451 | continue; /* Sanity Check */ | |
1452 | ||
1453 | if (IS_DEBUG_OSPF_EVENT) | |
1454 | zlog_info ("ospf_abr_announce_stub_defaults(): " | |
1455 | "announcing 0.0.0.0/0 to this area"); | |
1456 | ospf_abr_announce_network_to_area (&p, area->default_cost, area); | |
1457 | } | |
1458 | ||
1459 | if (IS_DEBUG_OSPF_EVENT) | |
1460 | zlog_info ("ospf_abr_announce_stub_defaults(): Stop"); | |
1461 | } | |
1462 | ||
1463 | #ifdef HAVE_NSSA | |
1464 | int | |
147193a2 | 1465 | ospf_abr_remove_unapproved_translates_apply (struct ospf *ospf, |
1466 | struct ospf_lsa *lsa) | |
718e3744 | 1467 | { |
1468 | if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT) | |
1469 | && ! CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED)) | |
1470 | { | |
1471 | zlog_info ("ospf_abr_remove_unapproved_translates(): " | |
1472 | "removing unapproved translates, ID: %s", | |
1473 | inet_ntoa (lsa->data->id)); | |
1474 | ||
1475 | /* FLUSH THROUGHOUT AS */ | |
147193a2 | 1476 | ospf_lsa_flush_as (ospf, lsa); |
718e3744 | 1477 | |
1478 | /* DISCARD from LSDB */ | |
1479 | } | |
1480 | return 0; | |
1481 | } | |
1482 | ||
1483 | void | |
147193a2 | 1484 | ospf_abr_remove_unapproved_translates (struct ospf *ospf) |
718e3744 | 1485 | { |
147193a2 | 1486 | struct route_node *rn; |
1487 | struct ospf_lsa *lsa; | |
1488 | ||
718e3744 | 1489 | /* All AREA PROCESS should have APPROVED necessary LSAs */ |
1490 | /* Remove any left over and not APPROVED */ | |
1491 | if (IS_DEBUG_OSPF_NSSA) | |
1492 | zlog_info ("ospf_abr_remove_unapproved_translates(): Start"); | |
1493 | ||
147193a2 | 1494 | LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) |
1495 | ospf_abr_remove_unapproved_translates_apply (ospf, lsa); | |
718e3744 | 1496 | |
1497 | if (IS_DEBUG_OSPF_NSSA) | |
1498 | zlog_info ("ospf_abr_remove_unapproved_translates(): Stop"); | |
1499 | } | |
1500 | #endif /* HAVE_NSSA */ | |
1501 | ||
718e3744 | 1502 | void |
147193a2 | 1503 | ospf_abr_remove_unapproved_summaries (struct ospf *ospf) |
718e3744 | 1504 | { |
1505 | listnode node; | |
1506 | struct ospf_area *area; | |
147193a2 | 1507 | struct route_node *rn; |
1508 | struct ospf_lsa *lsa; | |
718e3744 | 1509 | |
1510 | if (IS_DEBUG_OSPF_EVENT) | |
1511 | zlog_info ("ospf_abr_remove_unapproved_summaries(): Start"); | |
1512 | ||
147193a2 | 1513 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 1514 | { |
1515 | area = getdata (node); | |
1516 | ||
1517 | if (IS_DEBUG_OSPF_EVENT) | |
1518 | zlog_info ("ospf_abr_remove_unapproved_summaries(): " | |
1519 | "looking at area %s", inet_ntoa (area->area_id)); | |
1520 | ||
147193a2 | 1521 | LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) |
1522 | if (ospf_lsa_is_self_originated (ospf, lsa)) | |
1523 | if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED)) | |
1524 | ospf_lsa_flush_area (lsa, area); | |
1525 | ||
1526 | LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) | |
1527 | if (ospf_lsa_is_self_originated (ospf, lsa)) | |
1528 | if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED)) | |
1529 | ospf_lsa_flush_area (lsa, area); | |
718e3744 | 1530 | } |
1531 | ||
1532 | if (IS_DEBUG_OSPF_EVENT) | |
1533 | zlog_info ("ospf_abr_remove_unapproved_summaries(): Stop"); | |
1534 | } | |
1535 | ||
1536 | void | |
147193a2 | 1537 | ospf_abr_manage_discard_routes (struct ospf *ospf) |
718e3744 | 1538 | { |
1539 | listnode node; | |
1540 | struct route_node *rn; | |
1541 | struct ospf_area *area; | |
1542 | struct ospf_area_range *range; | |
1543 | ||
147193a2 | 1544 | for (node = listhead (ospf->areas); node; nextnode (node)) |
718e3744 | 1545 | if ((area = node->data) != NULL) |
1546 | for (rn = route_top (area->ranges); rn; rn = route_next (rn)) | |
1547 | if ((range = rn->info) != NULL) | |
1548 | if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)) | |
1549 | { | |
1550 | if (range->specifics) | |
147193a2 | 1551 | ospf_add_discard_route (ospf->new_table, area, |
718e3744 | 1552 | (struct prefix_ipv4 *) &rn->p); |
1553 | else | |
1554 | ospf_delete_discard_route ((struct prefix_ipv4 *) &rn->p); | |
1555 | } | |
1556 | } | |
1557 | ||
1558 | #ifdef HAVE_NSSA | |
1559 | /* This is the function taking care about ABR NSSA, i.e. NSSA | |
1560 | Translator, -LSA aggregation and flooding. For all NSSAs | |
1561 | ||
1562 | Any SELF-AS-LSA is in the Type-5 LSDB and Type-7 LSDB. These LSA's | |
1563 | are refreshed from the Type-5 LSDB, installed into the Type-7 LSDB | |
1564 | with the P-bit set. | |
1565 | ||
1566 | Any received Type-5s are legal for an ABR, else illegal for IR. | |
1567 | Received Type-7s are installed, by area, with incoming P-bit. They | |
1568 | are flooded; if the Elected NSSA Translator, then P-bit off. | |
1569 | ||
1570 | Additionally, this ABR will place "translated type-7's" into the | |
1571 | Type-5 LSDB in order to keep track of APPROVAL or not. | |
1572 | ||
1573 | It will scan through every area, looking for Type-7 LSAs with P-Bit | |
1574 | SET. The Type-7's are either AS-FLOODED & 5-INSTALLED or | |
1575 | AGGREGATED. Later, the AGGREGATED LSAs are AS-FLOODED & | |
1576 | 5-INSTALLED. | |
1577 | ||
1578 | 5-INSTALLED is into the Type-5 LSDB; Any UNAPPROVED Type-5 LSAs | |
1579 | left over are FLUSHED and DISCARDED. | |
1580 | ||
1581 | For External Calculations, any NSSA areas use the Type-7 AREA-LSDB, | |
1582 | any ABR-non-NSSA areas use the Type-5 GLOBAL-LSDB. */ | |
1583 | ||
1584 | void | |
147193a2 | 1585 | ospf_abr_nssa_task (struct ospf *ospf) /* called only if any_nssa */ |
718e3744 | 1586 | { |
1587 | if (IS_DEBUG_OSPF_NSSA) | |
1588 | zlog_info ("Check for NSSA-ABR Tasks():"); | |
1589 | ||
147193a2 | 1590 | if (! IS_OSPF_ABR (ospf)) |
718e3744 | 1591 | return; |
1592 | ||
147193a2 | 1593 | if (! ospf->anyNSSA) |
718e3744 | 1594 | return; |
1595 | ||
1596 | /* Each area must confirm TranslatorRole */ | |
1597 | if (IS_DEBUG_OSPF_NSSA) | |
1598 | zlog_info ("ospf_abr_nssa_task(): Start"); | |
1599 | ||
1600 | /* For all Global Entries flagged "local-translate", unset APPROVED */ | |
1601 | if (IS_DEBUG_OSPF_NSSA) | |
1602 | zlog_info ("ospf_abr_nssa_task(): unapprove translates"); | |
1603 | ||
147193a2 | 1604 | ospf_abr_unapprove_translates (ospf); |
718e3744 | 1605 | |
1606 | /* RESET all Ranges in every Area, same as summaries */ | |
1607 | if (IS_DEBUG_OSPF_NSSA) | |
1608 | zlog_info ("ospf_abr_nssa_task(): NSSA initialize aggregates"); | |
1609 | ||
1610 | /* ospf_abr_prepare_aggregates (); TURNED OFF just for now */ | |
1611 | ||
1612 | /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or | |
1613 | Aggregate as Type-7 */ | |
1614 | /* Install or Approve in Type-5 Global LSDB */ | |
1615 | if (IS_DEBUG_OSPF_NSSA) | |
1616 | zlog_info ("ospf_abr_nssa_task(): process translates"); | |
1617 | ||
147193a2 | 1618 | ospf_abr_process_nssa_translates (ospf); |
718e3744 | 1619 | |
1620 | /* Translate/Send any "ranged" aggregates, and also 5-Install and | |
1621 | Approve */ | |
1622 | /* Scan Type-7's for aggregates, translate to Type-5's, | |
1623 | Install/Flood/Approve */ | |
1624 | if (IS_DEBUG_OSPF_NSSA) | |
1625 | zlog_info("ospf_abr_nssa_task(): send NSSA aggregates"); | |
1626 | /* ospf_abr_send_nssa_aggregates (); TURNED OFF FOR NOW */ | |
1627 | ||
1628 | /* Send any NSSA defaults as Type-5 */ | |
1629 | if (IS_DEBUG_OSPF_NSSA) | |
1630 | zlog_info ("ospf_abr_nssa_task(): announce nssa defaults"); | |
147193a2 | 1631 | ospf_abr_announce_nssa_defaults (ospf); |
718e3744 | 1632 | |
1633 | /* Flush any unapproved previous translates from Global Data Base */ | |
1634 | if (IS_DEBUG_OSPF_NSSA) | |
1635 | zlog_info ("ospf_abr_nssa_task(): remove unapproved translates"); | |
147193a2 | 1636 | ospf_abr_remove_unapproved_translates (ospf); |
718e3744 | 1637 | |
147193a2 | 1638 | ospf_abr_manage_discard_routes (ospf); /* same as normal...discard */ |
718e3744 | 1639 | |
1640 | if (IS_DEBUG_OSPF_NSSA) | |
1641 | zlog_info ("ospf_abr_nssa_task(): Stop"); | |
1642 | } | |
1643 | #endif /* HAVE_NSSA */ | |
1644 | ||
1645 | /* This is the function taking care about ABR stuff, i.e. | |
1646 | summary-LSA origination and flooding. */ | |
1647 | void | |
147193a2 | 1648 | ospf_abr_task (struct ospf *ospf) |
718e3744 | 1649 | { |
1650 | if (IS_DEBUG_OSPF_EVENT) | |
1651 | zlog_info ("ospf_abr_task(): Start"); | |
1652 | ||
147193a2 | 1653 | if (ospf->new_table == NULL || ospf->new_rtrs == NULL) |
718e3744 | 1654 | { |
1655 | if (IS_DEBUG_OSPF_EVENT) | |
1656 | zlog_info ("ospf_abr_task(): Routing tables are not yet ready"); | |
1657 | return; | |
1658 | } | |
1659 | ||
1660 | if (IS_DEBUG_OSPF_EVENT) | |
1661 | zlog_info ("ospf_abr_task(): unapprove summaries"); | |
147193a2 | 1662 | ospf_abr_unapprove_summaries (ospf); |
718e3744 | 1663 | |
1664 | if (IS_DEBUG_OSPF_EVENT) | |
1665 | zlog_info ("ospf_abr_task(): prepare aggregates"); | |
147193a2 | 1666 | ospf_abr_prepare_aggregates (ospf); |
718e3744 | 1667 | |
147193a2 | 1668 | if (IS_OSPF_ABR (ospf)) |
718e3744 | 1669 | { |
1670 | if (IS_DEBUG_OSPF_EVENT) | |
1671 | zlog_info ("ospf_abr_task(): process network RT"); | |
147193a2 | 1672 | ospf_abr_process_network_rt (ospf, ospf->new_table); |
718e3744 | 1673 | |
1674 | if (IS_DEBUG_OSPF_EVENT) | |
1675 | zlog_info ("ospf_abr_task(): process router RT"); | |
147193a2 | 1676 | ospf_abr_process_router_rt (ospf, ospf->new_rtrs); |
718e3744 | 1677 | |
1678 | if (IS_DEBUG_OSPF_EVENT) | |
1679 | zlog_info ("ospf_abr_task(): announce aggregates"); | |
147193a2 | 1680 | ospf_abr_announce_aggregates (ospf); |
718e3744 | 1681 | |
1682 | if (IS_DEBUG_OSPF_EVENT) | |
1683 | zlog_info ("ospf_abr_task(): announce stub defaults"); | |
147193a2 | 1684 | ospf_abr_announce_stub_defaults (ospf); |
718e3744 | 1685 | } |
1686 | ||
1687 | if (IS_DEBUG_OSPF_EVENT) | |
1688 | zlog_info ("ospf_abr_task(): remove unapproved summaries"); | |
147193a2 | 1689 | ospf_abr_remove_unapproved_summaries (ospf); |
718e3744 | 1690 | |
147193a2 | 1691 | ospf_abr_manage_discard_routes (ospf); |
718e3744 | 1692 | |
1693 | #ifdef HAVE_NSSA | |
147193a2 | 1694 | ospf_abr_nssa_task (ospf); /* if nssa-abr, then scan Type-7 LSDB */ |
718e3744 | 1695 | #endif /* HAVE_NSSA */ |
1696 | ||
1697 | if (IS_DEBUG_OSPF_EVENT) | |
1698 | zlog_info ("ospf_abr_task(): Stop"); | |
1699 | } | |
1700 | ||
1701 | ||
1702 | int | |
147193a2 | 1703 | ospf_abr_task_timer (struct thread *thread) |
718e3744 | 1704 | { |
147193a2 | 1705 | struct ospf *ospf = THREAD_ARG (thread); |
1706 | ||
1707 | ospf->t_abr_task = 0; | |
718e3744 | 1708 | |
1709 | if (IS_DEBUG_OSPF_EVENT) | |
1710 | zlog_info ("Running ABR task on timer"); | |
1711 | ||
147193a2 | 1712 | ospf_check_abr_status (ospf); |
718e3744 | 1713 | |
147193a2 | 1714 | ospf_abr_task (ospf); |
718e3744 | 1715 | |
147193a2 | 1716 | return 0; |
718e3744 | 1717 | } |
1718 | ||
1719 | void | |
147193a2 | 1720 | ospf_schedule_abr_task (struct ospf *ospf) |
718e3744 | 1721 | { |
1722 | if (IS_DEBUG_OSPF_EVENT) | |
1723 | zlog_info ("Scheduling ABR task"); | |
147193a2 | 1724 | |
1725 | if (ospf->t_abr_task == NULL) | |
1726 | ospf->t_abr_task = thread_add_timer (master, ospf_abr_task_timer, | |
1727 | ospf, OSPF_ABR_TASK_DELAY); | |
718e3744 | 1728 | } |