blob: 51fb2d6e4c9b9168178f6cd6ca412577c6769fc1 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
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"
paul718e3742002-12-13 20:15:29 +000053
54struct ospf_area_range *
55ospf_area_range_new (struct prefix_ipv4 *p)
56{
57 struct ospf_area_range *range;
58
59 range = XCALLOC (MTYPE_OSPF_AREA_RANGE, sizeof (struct ospf_area_range));
60 range->addr = p->prefix;
61 range->masklen = p->prefixlen;
62 range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;
63
64 return range;
65}
66
67void
68ospf_area_range_free (struct ospf_area_range *range)
69{
70 XFREE (MTYPE_OSPF_AREA_RANGE, range);
71}
72
73void
74ospf_area_range_add (struct ospf_area *area, struct ospf_area_range *range)
75{
76 struct route_node *rn;
77 struct prefix_ipv4 p;
78
79 p.family = AF_INET;
80 p.prefixlen = range->masklen;
81 p.prefix = range->addr;
82
83 rn = route_node_get (area->ranges, (struct prefix *)&p);
84 if (rn->info)
85 route_unlock_node (rn);
86 else
87 rn->info = range;
88}
89
90void
91ospf_area_range_delete (struct ospf_area *area, struct ospf_area_range *range)
92{
93 struct route_node *rn;
94 struct prefix_ipv4 p;
95
96 p.family = AF_INET;
97 p.prefixlen = range->masklen;
98 p.prefix = range->addr;
99
100 rn = route_node_lookup (area->ranges, (struct prefix *)&p);
101 if (rn)
102 {
103 ospf_area_range_free (rn->info);
104 rn->info = NULL;
105 route_unlock_node (rn);
106 route_unlock_node (rn);
107 }
108}
109
110struct ospf_area_range *
111ospf_area_range_lookup (struct ospf_area *area, struct prefix_ipv4 *p)
112{
113 struct route_node *rn;
114
115 rn = route_node_lookup (area->ranges, (struct prefix *)p);
116 if (rn)
117 {
118 route_unlock_node (rn);
119 return rn->info;
120 }
121 return NULL;
122}
123
124struct ospf_area_range *
pauld4a53d52003-07-12 21:30:57 +0000125ospf_area_range_lookup_next (struct ospf_area *area,
126 struct in_addr *range_net,
127 int first)
paul718e3742002-12-13 20:15:29 +0000128{
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
159struct ospf_area_range *
160ospf_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
173struct ospf_area_range *
174ospf_area_range_match_any (struct ospf *ospf, struct prefix_ipv4 *p)
175{
176 struct ospf_area_range *range;
hasso52dc7ee2004-09-23 19:18:23 +0000177 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000178
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
186int
187ospf_area_range_active (struct ospf_area_range *range)
188{
189 return range->specifics;
190}
191
192int
193ospf_area_actively_attached (struct ospf_area *area)
194{
195 return area->act_ints;
196}
197
198int
199ospf_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;
paul147193a2003-04-19 00:31:59 +0000204 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000205
paul147193a2003-04-19 00:31:59 +0000206 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000207 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)))
paul147193a2003-04-19 00:31:59 +0000217 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000218 }
219 else
220 {
221 range = ospf_area_range_new (p);
222 ospf_area_range_add (area, range);
paul147193a2003-04-19 00:31:59 +0000223 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000224 }
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
234int
235ospf_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;
paul147193a2003-04-19 00:31:59 +0000240 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000241
paul147193a2003-04-19 00:31:59 +0000242 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000243 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))
paul147193a2003-04-19 00:31:59 +0000254 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000255 }
256
257 return 1;
258}
259
260int
261ospf_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
paul147193a2003-04-19 00:31:59 +0000267 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000268 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))
paul147193a2003-04-19 00:31:59 +0000276 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000277
278 ospf_area_range_delete (area, range);
279
280 return 1;
281}
282
283int
284ospf_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;
paul147193a2003-04-19 00:31:59 +0000289 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
paul718e3742002-12-13 20:15:29 +0000290
paul147193a2003-04-19 00:31:59 +0000291 area = ospf_area_get (ospf, area_id, ret);
paul718e3742002-12-13 20:15:29 +0000292 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))
paul147193a2003-04-19 00:31:59 +0000298 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000299 }
300 else
301 {
302 range = ospf_area_range_new (p);
303 ospf_area_range_add (area, range);
paul147193a2003-04-19 00:31:59 +0000304 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000305 }
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
315int
316ospf_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
paul147193a2003-04-19 00:31:59 +0000322 area = ospf_area_lookup_by_area_id (ospf, area_id);
paul718e3742002-12-13 20:15:29 +0000323 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))
paul147193a2003-04-19 00:31:59 +0000332 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +0000333
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
341int
paul147193a2003-04-19 00:31:59 +0000342ospf_act_bb_connection (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000343{
paul147193a2003-04-19 00:31:59 +0000344 if (ospf->backbone == NULL)
paul718e3742002-12-13 20:15:29 +0000345 return 0;
346
paul147193a2003-04-19 00:31:59 +0000347 return ospf->backbone->full_nbrs;
paul718e3742002-12-13 20:15:29 +0000348}
349
paule2c6c152003-06-22 08:49:25 +0000350/* Determine whether this router is elected translator or not for area */
351int
352ospf_abr_nssa_am_elected (struct ospf_area *area)
353{
354 struct route_node *rn;
355 struct ospf_lsa *lsa;
356 struct router_lsa *rlsa;
357 struct in_addr *best = NULL;
358
359 LSDB_LOOP ( ROUTER_LSDB (area), rn, lsa)
360 {
361 /* sanity checks */
362 if (!lsa
363 || (lsa->data->type != OSPF_ROUTER_LSA)
364 || IS_LSA_SELF (lsa))
365 continue;
366
367 rlsa = (struct router_lsa *) lsa->data;
368
369 /* ignore non-ABR routers */
370 if (!IS_ROUTER_LSA_BORDER (rlsa))
371 continue;
372
373 /* Router has Nt flag - always translate */
374 if (IS_ROUTER_LSA_NT (rlsa))
375 {
376 if (IS_DEBUG_OSPF_NSSA)
pauld4a53d52003-07-12 21:30:57 +0000377 zlog_info ("ospf_abr_nssa_am_elected: "
paule2c6c152003-06-22 08:49:25 +0000378 "router %s asserts Nt",
379 inet_ntoa (lsa->data->id) );
380 return 0;
381 }
382
383 if (best == NULL)
384 best = &lsa->data->id;
385 else
386 if ( IPV4_ADDR_CMP (&best, &lsa->data->id) < 0)
387 best = &lsa->data->id;
388 }
389
390 if (IS_DEBUG_OSPF_NSSA)
391 zlog_info ("ospf_abr_nssa_am_elected: best electable ABR is: %s",
392 (best) ? inet_ntoa (*best) : "<none>" );
393
394 if (best == NULL)
395 return 1;
396
397 if ( IPV4_ADDR_CMP (&best, &area->ospf->router_id) < 0)
398 return 1;
399 else
400 return 0;
401}
402
403/* Check NSSA ABR status
404 * assumes there are nssa areas
405 */
406void
407ospf_abr_nssa_check_status (struct ospf *ospf)
408{
409 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000410 struct listnode *lnode;
paule2c6c152003-06-22 08:49:25 +0000411
412 LIST_LOOP (ospf->areas, area, lnode)
413 {
414
415 if (area->external_routing != OSPF_AREA_NSSA)
416 continue;
417
418 if (IS_DEBUG_OSPF (nssa, NSSA))
419 zlog_info ("ospf_abr_nssa_check_status: "
420 "checking area %s",
421 inet_ntoa (area->area_id));
422
423 if (!IS_OSPF_ABR (area->ospf))
424 {
425 if (IS_DEBUG_OSPF (nssa, NSSA))
426 zlog_info ("ospf_abr_nssa_check_status: "
427 "not ABR");
pauld4a53d52003-07-12 21:30:57 +0000428 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paule2c6c152003-06-22 08:49:25 +0000429 continue;
430 }
431
432 switch (area->NSSATranslatorRole)
433 {
434 case OSPF_NSSA_ROLE_NEVER:
435 /* We never Translate Type-7 LSA. */
436 /* TODO: check previous state and flush? */
437 if (IS_DEBUG_OSPF (nssa, NSSA))
438 zlog_info ("ospf_abr_nssa_check_status: "
439 "never translate");
pauld4a53d52003-07-12 21:30:57 +0000440 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paule2c6c152003-06-22 08:49:25 +0000441 continue;
442
443 case OSPF_NSSA_ROLE_ALWAYS:
444 /* We always translate if we are an ABR
445 * TODO: originate new LSAs if state change?
446 * or let the nssa abr task take care of it?
447 */
448 if (IS_DEBUG_OSPF (nssa, NSSA))
449 zlog_info ("ospf_abr_nssa_check_status: "
450 "translate always");
pauld4a53d52003-07-12 21:30:57 +0000451 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
paule2c6c152003-06-22 08:49:25 +0000452 continue;
453
454 case OSPF_NSSA_ROLE_CANDIDATE:
455 /* We are a candidate for Translation */
456 if (ospf_abr_nssa_am_elected (area) > 0 )
457 {
pauld4a53d52003-07-12 21:30:57 +0000458 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
paule2c6c152003-06-22 08:49:25 +0000459 if (IS_DEBUG_OSPF (nssa, NSSA))
460 zlog_info ("ospf_abr_nssa_check_status: "
461 "elected translator");
462 }
463 else
464 {
pauld4a53d52003-07-12 21:30:57 +0000465 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
paule2c6c152003-06-22 08:49:25 +0000466 if (IS_DEBUG_OSPF (nssa, NSSA))
467 zlog_info ("ospf_abr_nssa_check_status: "
468 "not elected");
469 }
470 continue;
471 }
472 }
473}
paule2c6c152003-06-22 08:49:25 +0000474
paul718e3742002-12-13 20:15:29 +0000475/* Check area border router status. */
476void
paul147193a2003-04-19 00:31:59 +0000477ospf_check_abr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000478{
479 struct ospf_area *area;
hasso52dc7ee2004-09-23 19:18:23 +0000480 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000481 int bb_configured = 0;
482 int bb_act_attached = 0;
483 int areas_configured = 0;
484 int areas_act_attached = 0;
paul147193a2003-04-19 00:31:59 +0000485 u_char new_flags = ospf->flags;
paul718e3742002-12-13 20:15:29 +0000486
487 if (IS_DEBUG_OSPF_EVENT)
488 zlog_info ("ospf_check_abr_status(): Start");
489
paul147193a2003-04-19 00:31:59 +0000490 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000491 {
492 area = getdata (node);
paule2c6c152003-06-22 08:49:25 +0000493
paul718e3742002-12-13 20:15:29 +0000494 if (listcount (area->oiflist))
495 {
496 areas_configured++;
497
498 if (OSPF_IS_AREA_BACKBONE (area))
499 bb_configured = 1;
500 }
501
502 if (ospf_area_actively_attached (area))
503 {
504 areas_act_attached++;
505
506 if (OSPF_IS_AREA_BACKBONE (area))
507 bb_act_attached = 1;
508 }
509 }
510
511 if (IS_DEBUG_OSPF_EVENT)
512 {
513 zlog_info ("ospf_check_abr_status(): looked through areas");
514 zlog_info ("ospf_check_abr_status(): bb_configured: %d", bb_configured);
515 zlog_info ("ospf_check_abr_status(): bb_act_attached: %d",
516 bb_act_attached);
517 zlog_info ("ospf_check_abr_status(): areas_configured: %d",
518 areas_configured);
519 zlog_info ("ospf_check_abr_status(): areas_act_attached: %d",
520 areas_act_attached);
521 }
522
paul147193a2003-04-19 00:31:59 +0000523 switch (ospf->abr_type)
paul718e3742002-12-13 20:15:29 +0000524 {
525 case OSPF_ABR_SHORTCUT:
526 case OSPF_ABR_STAND:
527 if (areas_act_attached > 1)
528 SET_FLAG (new_flags, OSPF_FLAG_ABR);
529 else
530 UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
531 break;
532
533 case OSPF_ABR_IBM:
534 if ((areas_act_attached > 1) && bb_configured)
535 SET_FLAG (new_flags, OSPF_FLAG_ABR);
536 else
537 UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
538 break;
539
540 case OSPF_ABR_CISCO:
541 if ((areas_configured > 1) && bb_act_attached)
542 SET_FLAG (new_flags, OSPF_FLAG_ABR);
543 else
544 UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
545 break;
546 default:
547 break;
548 }
549
paul147193a2003-04-19 00:31:59 +0000550 if (new_flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +0000551 {
paul147193a2003-04-19 00:31:59 +0000552 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +0000553 if (IS_DEBUG_OSPF_EVENT)
554 zlog_info ("ospf_check_abr_status(): new router flags: %x",new_flags);
paul147193a2003-04-19 00:31:59 +0000555 ospf->flags = new_flags;
556 OSPF_TIMER_ON (ospf->t_router_lsa_update,
paul718e3742002-12-13 20:15:29 +0000557 ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
558 }
559}
560
561void
562ospf_abr_update_aggregate (struct ospf_area_range *range,
paul7f352b82004-02-19 19:37:47 +0000563 struct ospf_route *or)
paul718e3742002-12-13 20:15:29 +0000564{
565 if (IS_DEBUG_OSPF_EVENT)
566 zlog_info ("ospf_abr_update_aggregate(): Start");
567
paul6c835672004-10-11 11:00:30 +0000568 if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC)
paul718e3742002-12-13 20:15:29 +0000569 {
570 if (IS_DEBUG_OSPF_EVENT)
paul7f352b82004-02-19 19:37:47 +0000571 zlog_info ("ospf_abr_update_aggregate(): use configured cost %d",
572 range->cost_config);
paul718e3742002-12-13 20:15:29 +0000573
574 range->cost = range->cost_config;
575 }
576 else
577 {
578 if (range->specifics == 0)
paul7f352b82004-02-19 19:37:47 +0000579 range->cost = or->cost; /* 1st time get 1st cost */
paul718e3742002-12-13 20:15:29 +0000580
paul7f352b82004-02-19 19:37:47 +0000581 if (or->cost > range->cost)
582 {
583 if (IS_DEBUG_OSPF_EVENT)
584 zlog_info ("ospf_abr_update_aggregate(): lowest cost, update");
paul718e3742002-12-13 20:15:29 +0000585
paul7f352b82004-02-19 19:37:47 +0000586 range->cost = or->cost;
587 }
paul718e3742002-12-13 20:15:29 +0000588 }
589
590 range->specifics++;
591}
592
593static void
594set_metric (struct ospf_lsa *lsa, u_int32_t metric)
595{
596 struct summary_lsa *header;
597 u_char *mp;
598 metric = htonl (metric);
hassoc9e52be2004-09-26 16:09:34 +0000599 mp = (u_char *) &metric;
paul718e3742002-12-13 20:15:29 +0000600 mp++;
601 header = (struct summary_lsa *) lsa->data;
602 memcpy(header->metric, mp, 3);
603}
604
paul718e3742002-12-13 20:15:29 +0000605int
606ospf_abr_check_nssa_range (struct prefix_ipv4 *p, u_int32_t cost,
607 struct ospf_area *area)
608{
609 /* The Type-7 is tested against the aggregated prefix and forwarded
610 for lsa installation and flooding */
611 return 0;
612}
613
614/* ospf_abr_translate_nssa */
615int
paul147193a2003-04-19 00:31:59 +0000616ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +0000617{
618 /* Incoming Type-7 or later aggregated Type-7
pauld4a53d52003-07-12 21:30:57 +0000619 *
620 * LSA is skipped if P-bit is off.
621 * LSA is aggregated if within range.
622 *
623 * The Type-7 is translated, Installed/Approved as a Type-5 into
624 * global LSDB, then Flooded through AS
625 *
626 * Later, any Unapproved Translated Type-5's are flushed/discarded
627 */
paul718e3742002-12-13 20:15:29 +0000628
pauld4a53d52003-07-12 21:30:57 +0000629 struct ospf_lsa *old = NULL,
630 *new = NULL;
631 struct as_external_lsa *ext7;
632 struct prefix_ipv4 p;
paul718e3742002-12-13 20:15:29 +0000633
634 if (! CHECK_FLAG (lsa->data->options, OSPF_OPTION_NP))
635 {
636 if (IS_DEBUG_OSPF_NSSA)
pauld4a53d52003-07-12 21:30:57 +0000637 zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation",
638 inet_ntoa (lsa->data->id));
639 return 1;
paul718e3742002-12-13 20:15:29 +0000640 }
pauld4a53d52003-07-12 21:30:57 +0000641
paul718e3742002-12-13 20:15:29 +0000642 if (IS_DEBUG_OSPF_NSSA)
pauld4a53d52003-07-12 21:30:57 +0000643 zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5",
644 inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +0000645
pauld4a53d52003-07-12 21:30:57 +0000646 ext7 = (struct as_external_lsa *)(lsa->data);
647 p.prefix = lsa->data->id;
648 p.prefixlen = ip_masklen (ext7->mask);
649
650 if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION)
651 {
652 if (IS_DEBUG_OSPF_NSSA)
653 zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, "
654 "Forward address is 0, NO Translation",
655 inet_ntoa (lsa->data->id));
656 return 1;
657 }
658
659 /* try find existing AS-External LSA for this prefix */
660
661 old = ospf_external_info_find_lsa (area->ospf, &p);
662
663 if (old)
664 {
665 if (IS_DEBUG_OSPF_NSSA)
666 zlog_info ("ospf_abr_translate_nssa(): "
667 "found old translated LSA Id %s, refreshing",
668 inet_ntoa (old->data->id));
669
670 /* refresh */
671 new = ospf_translated_nssa_refresh (area->ospf, lsa, old);
672 if (!new)
673 {
674 if (IS_DEBUG_OSPF_NSSA)
675 zlog_info ("ospf_abr_translate_nssa(): "
676 "could not refresh translated LSA Id %s",
677 inet_ntoa (old->data->id));
678 }
679 }
680 else
681 {
682 /* no existing external route for this LSA Id
683 * originate translated LSA
684 */
685
686 if ((new = ospf_translated_nssa_originate (area->ospf, lsa))
687 == NULL)
688 {
689 if (IS_DEBUG_OSPF_NSSA)
690 zlog_info ("ospf_abr_translate_nssa(): Could not translate "
691 "Type-7 for %s to Type-5",
692 inet_ntoa (lsa->data->id));
693 return 1;
694 }
695 }
paul718e3742002-12-13 20:15:29 +0000696
697 /* Area where Aggregate testing will be inserted, just like summary
698 advertisements */
699 /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */
700
paul718e3742002-12-13 20:15:29 +0000701 return 0;
702}
703
704void
705ospf_abr_translate_nssa_range (struct prefix_ipv4 *p, u_int32_t cost)
706{
707 /* The Type-7 is created from the aggregated prefix and forwarded
708 for lsa installation and flooding... to be added... */
709}
paul718e3742002-12-13 20:15:29 +0000710
711void
712ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
713 struct ospf_area *area)
714{
715 struct ospf_lsa *lsa, *old = NULL;
716 struct summary_lsa *sl = NULL;
717
718 if (IS_DEBUG_OSPF_EVENT)
719 zlog_info ("ospf_abr_announce_network_to_area(): Start");
720
pauld4a53d52003-07-12 21:30:57 +0000721 old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA,
722 (struct prefix_ipv4 *) p,
723 area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000724 if (old)
725 {
726 if (IS_DEBUG_OSPF_EVENT)
pauld4a53d52003-07-12 21:30:57 +0000727 zlog_info ("ospf_abr_announce_network_to_area(): old summary found");
728
paul718e3742002-12-13 20:15:29 +0000729 sl = (struct summary_lsa *) old->data;
730
731 if (IS_DEBUG_OSPF_EVENT)
pauld4a53d52003-07-12 21:30:57 +0000732 zlog_info ("ospf_abr_announce_network_to_area(): "
733 "old metric: %d, new metric: %d",
734 GET_METRIC (sl->metric), cost);
735
736 if (GET_METRIC (sl->metric) == cost)
737 {
738 /* unchanged. simply reapprove it */
739 if (IS_DEBUG_OSPF_EVENT)
740 zlog_info ("ospf_abr_announce_network_to_area(): "
741 "old summary approved");
742 SET_FLAG (old->flags, OSPF_LSA_APPROVED);
743 }
744 else
745 {
746 /* LSA is changed, refresh it */
747 if (IS_DEBUG_OSPF_EVENT)
748 zlog_info ("ospf_abr_announce_network_to_area(): "
749 "refreshing summary");
750 set_metric (old, cost);
751 lsa = ospf_summary_lsa_refresh (area->ospf, old);
752 /* This will flood through area. */
753 }
paul718e3742002-12-13 20:15:29 +0000754 }
755 else
756 {
757 if (IS_DEBUG_OSPF_EVENT)
pauld4a53d52003-07-12 21:30:57 +0000758 zlog_info ("ospf_abr_announce_network_to_area(): "
759 "creating new summary");
760 lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, cost, area);
761 /* This will flood through area. */
paul718e3742002-12-13 20:15:29 +0000762
paul718e3742002-12-13 20:15:29 +0000763 SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
764 if (IS_DEBUG_OSPF_EVENT)
pauld4a53d52003-07-12 21:30:57 +0000765 zlog_info ("ospf_abr_announce_network_to_area(): "
766 "flooding new version of summary");
paul718e3742002-12-13 20:15:29 +0000767 }
768
769 if (IS_DEBUG_OSPF_EVENT)
770 zlog_info ("ospf_abr_announce_network_to_area(): Stop");
771}
772
773int
774ospf_abr_nexthops_belong_to_area (struct ospf_route *or,
775 struct ospf_area *area)
776{
hasso52dc7ee2004-09-23 19:18:23 +0000777 struct listnode *node;
paul96735ee2003-08-10 02:51:22 +0000778 struct ospf_path *path;
paul718e3742002-12-13 20:15:29 +0000779
paul96735ee2003-08-10 02:51:22 +0000780 LIST_LOOP (or->paths, path, node)
paul718e3742002-12-13 20:15:29 +0000781 {
paul718e3742002-12-13 20:15:29 +0000782 struct ospf_interface *oi = path->oi;
783
784 if (oi != NULL)
paul96735ee2003-08-10 02:51:22 +0000785 if (oi->area == area)
786 return 1;
paul718e3742002-12-13 20:15:29 +0000787 }
788
789 return 0;
790}
791
792int
pauld4a53d52003-07-12 21:30:57 +0000793ospf_abr_should_accept (struct prefix_ipv4 *p, struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000794{
795 if (IMPORT_NAME (area))
796 {
797 if (IMPORT_LIST (area) == NULL)
798 IMPORT_LIST (area) = access_list_lookup (AFI_IP, IMPORT_NAME (area));
799
800 if (IMPORT_LIST (area))
801 if (access_list_apply (IMPORT_LIST (area), p) == FILTER_DENY)
802 return 0;
803 }
804
805 return 1;
806}
807
808int
809ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or,
pauld4a53d52003-07-12 21:30:57 +0000810 struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000811{
812 if (PREFIX_NAME_IN (area))
813 {
814 if (PREFIX_LIST_IN (area) == NULL)
815 PREFIX_LIST_IN (area) = prefix_list_lookup (AFI_IP,
816 PREFIX_NAME_IN (area));
817 if (PREFIX_LIST_IN (area))
818 if (prefix_list_apply (PREFIX_LIST_IN (area), p) != PREFIX_PERMIT)
819 return 0;
820 }
821 return 1;
822}
823
824int
825ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or,
pauld4a53d52003-07-12 21:30:57 +0000826 struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000827{
828 if (PREFIX_NAME_OUT (area))
829 {
830 if (PREFIX_LIST_OUT (area) == NULL)
831 PREFIX_LIST_OUT (area) = prefix_list_lookup (AFI_IP,
832 PREFIX_NAME_OUT (area));
833 if (PREFIX_LIST_OUT (area))
834 if (prefix_list_apply (PREFIX_LIST_OUT (area), p) != PREFIX_PERMIT)
835 return 0;
836 }
837 return 1;
838}
839
840void
paul147193a2003-04-19 00:31:59 +0000841ospf_abr_announce_network (struct ospf *ospf,
pauld4a53d52003-07-12 21:30:57 +0000842 struct prefix_ipv4 *p, struct ospf_route *or)
paul718e3742002-12-13 20:15:29 +0000843{
paul718e3742002-12-13 20:15:29 +0000844 struct ospf_area_range *range;
paul718e3742002-12-13 20:15:29 +0000845 struct ospf_area *area, *or_area;
hasso52dc7ee2004-09-23 19:18:23 +0000846 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000847
848 if (IS_DEBUG_OSPF_EVENT)
849 zlog_info ("ospf_abr_announce_network(): Start");
paul718e3742002-12-13 20:15:29 +0000850
paul147193a2003-04-19 00:31:59 +0000851 or_area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id);
paul718e3742002-12-13 20:15:29 +0000852 assert (or_area);
853
paul147193a2003-04-19 00:31:59 +0000854 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000855 {
856 area = getdata (node);
857
858 if (IS_DEBUG_OSPF_EVENT)
859 zlog_info ("ospf_abr_announce_network(): looking at area %s",
860 inet_ntoa (area->area_id));
861
862 if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id))
863 continue;
864
865 if (ospf_abr_nexthops_belong_to_area (or, area))
866 continue;
867
pauld4a53d52003-07-12 21:30:57 +0000868 if (!ospf_abr_should_accept (p, area))
paul718e3742002-12-13 20:15:29 +0000869 {
870 if (IS_DEBUG_OSPF_EVENT)
871 zlog_info ("ospf_abr_announce_network(): "
872 "prefix %s/%d was denied by import-list",
873 inet_ntoa (p->prefix), p->prefixlen);
874 continue;
875 }
876
pauld4a53d52003-07-12 21:30:57 +0000877 if (!ospf_abr_plist_in_check (area, or, p))
paul718e3742002-12-13 20:15:29 +0000878 {
879 if (IS_DEBUG_OSPF_EVENT)
880 zlog_info ("ospf_abr_announce_network(): "
881 "prefix %s/%d was denied by prefix-list",
882 inet_ntoa (p->prefix), p->prefixlen);
883 continue;
884 }
885
886 if (area->external_routing != OSPF_AREA_DEFAULT && area->no_summary)
887 {
888 if (IS_DEBUG_OSPF_EVENT)
889 zlog_info ("ospf_abr_announce_network(): "
890 "area %s is stub and no_summary",
891 inet_ntoa (area->area_id));
892 continue;
893 }
894
895 if (or->path_type == OSPF_PATH_INTER_AREA)
896 {
897 if (IS_DEBUG_OSPF_EVENT)
898 zlog_info ("ospf_abr_announce_network(): this is "
899 "inter-area route to %s/%d",
900 inet_ntoa (p->prefix), p->prefixlen);
901
902 if (!OSPF_IS_AREA_BACKBONE (area))
903 ospf_abr_announce_network_to_area (p, or->cost, area);
904 }
905
906 if (or->path_type == OSPF_PATH_INTRA_AREA)
pauld4a53d52003-07-12 21:30:57 +0000907 {
908 if (IS_DEBUG_OSPF_EVENT)
909 zlog_info ("ospf_abr_announce_network(): "
910 "this is intra-area route to %s/%d",
911 inet_ntoa (p->prefix), p->prefixlen);
912 if ((range = ospf_area_range_match (or_area, p))
913 && !ospf_area_is_transit (area))
914 ospf_abr_update_aggregate (range, or);
915 else
916 ospf_abr_announce_network_to_area (p, or->cost, area);
917 }
paul718e3742002-12-13 20:15:29 +0000918 }
919}
920
921int
paul147193a2003-04-19 00:31:59 +0000922ospf_abr_should_announce (struct ospf *ospf,
pauld4a53d52003-07-12 21:30:57 +0000923 struct prefix_ipv4 *p, struct ospf_route *or)
paul718e3742002-12-13 20:15:29 +0000924{
paul147193a2003-04-19 00:31:59 +0000925 struct ospf_area *area;
926
927 area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id);
paul718e3742002-12-13 20:15:29 +0000928
929 assert (area);
930
931 if (EXPORT_NAME (area))
932 {
933 if (EXPORT_LIST (area) == NULL)
934 EXPORT_LIST (area) = access_list_lookup (AFI_IP, EXPORT_NAME (area));
935
936 if (EXPORT_LIST (area))
937 if (access_list_apply (EXPORT_LIST (area), p) == FILTER_DENY)
938 return 0;
939 }
940
941 return 1;
942}
943
paul718e3742002-12-13 20:15:29 +0000944void
paul147193a2003-04-19 00:31:59 +0000945ospf_abr_process_nssa_translates (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000946{
947 /* Scan through all NSSA_LSDB records for all areas;
948
949 If P-bit is on, translate all Type-7's to 5's and aggregate or
950 flood install as approved in Type-5 LSDB with XLATE Flag on
951 later, do same for all aggregates... At end, DISCARD all
952 remaining UNAPPROVED Type-5's (Aggregate is for future ) */
hasso52dc7ee2004-09-23 19:18:23 +0000953 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000954 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +0000955 struct route_node *rn;
956 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000957
958 if (IS_DEBUG_OSPF_NSSA)
959 zlog_info ("ospf_abr_process_nssa_translates(): Start");
960
paul147193a2003-04-19 00:31:59 +0000961 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000962 {
963 area = getdata (node);
964
paule2c6c152003-06-22 08:49:25 +0000965 if (! area->NSSATranslatorState)
pauld4a53d52003-07-12 21:30:57 +0000966 continue; /* skip if not translator */
paul718e3742002-12-13 20:15:29 +0000967
968 if (area->external_routing != OSPF_AREA_NSSA)
pauld4a53d52003-07-12 21:30:57 +0000969 continue; /* skip if not Nssa Area */
paul718e3742002-12-13 20:15:29 +0000970
971 if (IS_DEBUG_OSPF_NSSA)
pauld4a53d52003-07-12 21:30:57 +0000972 zlog_info ("ospf_abr_process_nssa_translates(): "
973 "looking at area %s", inet_ntoa (area->area_id));
paul718e3742002-12-13 20:15:29 +0000974
paul147193a2003-04-19 00:31:59 +0000975 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
pauld4a53d52003-07-12 21:30:57 +0000976 ospf_abr_translate_nssa (area, lsa);
paul718e3742002-12-13 20:15:29 +0000977 }
978
979 if (IS_DEBUG_OSPF_NSSA)
980 zlog_info ("ospf_abr_process_nssa_translates(): Stop");
981
982}
paul718e3742002-12-13 20:15:29 +0000983
984void
paul147193a2003-04-19 00:31:59 +0000985ospf_abr_process_network_rt (struct ospf *ospf,
986 struct route_table *rt)
paul718e3742002-12-13 20:15:29 +0000987{
paul718e3742002-12-13 20:15:29 +0000988 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +0000989 struct ospf_route *or;
990 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000991
992 if (IS_DEBUG_OSPF_EVENT)
993 zlog_info ("ospf_abr_process_network_rt(): Start");
994
995 for (rn = route_top (rt); rn; rn = route_next (rn))
996 {
997 if ((or = rn->info) == NULL)
998 continue;
999
paul147193a2003-04-19 00:31:59 +00001000 if (!(area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id)))
paul718e3742002-12-13 20:15:29 +00001001 {
1002 if (IS_DEBUG_OSPF_EVENT)
1003 zlog_info ("ospf_abr_process_network_rt(): area %s no longer exists",
1004 inet_ntoa (or->u.std.area_id));
1005 continue;
1006 }
1007
1008 if (IS_DEBUG_OSPF_EVENT)
1009 zlog_info ("ospf_abr_process_network_rt(): this is a route to %s/%d",
1010 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
1011 if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL)
1012 {
1013 if (IS_DEBUG_OSPF_EVENT)
1014 zlog_info ("ospf_abr_process_network_rt(): "
1015 "this is an External router, skipping");
1016 continue;
1017 }
1018
1019 if (or->cost >= OSPF_LS_INFINITY)
1020 {
1021 if (IS_DEBUG_OSPF_EVENT)
1022 zlog_info ("ospf_abr_process_network_rt():"
1023 " this route's cost is infinity, skipping");
1024 continue;
1025 }
1026
1027 if (or->type == OSPF_DESTINATION_DISCARD)
1028 {
1029 if (IS_DEBUG_OSPF_EVENT)
1030 zlog_info ("ospf_abr_process_network_rt():"
1031 " this is a discard entry, skipping");
1032 continue;
1033 }
1034
1035 if (or->path_type == OSPF_PATH_INTRA_AREA &&
pauld4a53d52003-07-12 21:30:57 +00001036 !ospf_abr_should_announce (ospf, (struct prefix_ipv4 *) &rn->p, or))
paul718e3742002-12-13 20:15:29 +00001037 {
1038 if (IS_DEBUG_OSPF_EVENT)
1039 zlog_info("ospf_abr_process_network_rt(): denied by export-list");
1040 continue;
1041 }
1042
1043 if (or->path_type == OSPF_PATH_INTRA_AREA &&
pauld4a53d52003-07-12 21:30:57 +00001044 !ospf_abr_plist_out_check (area, or, (struct prefix_ipv4 *) &rn->p))
paul718e3742002-12-13 20:15:29 +00001045 {
1046 if (IS_DEBUG_OSPF_EVENT)
1047 zlog_info("ospf_abr_process_network_rt(): denied by prefix-list");
1048 continue;
1049 }
1050
1051 if ((or->path_type == OSPF_PATH_INTER_AREA) &&
1052 !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
1053 {
1054 if (IS_DEBUG_OSPF_EVENT)
1055 zlog_info ("ospf_abr_process_network_rt():"
1056 " this is route is not backbone one, skipping");
1057 continue;
1058 }
1059
1060
paul147193a2003-04-19 00:31:59 +00001061 if ((ospf->abr_type == OSPF_ABR_CISCO) ||
1062 (ospf->abr_type == OSPF_ABR_IBM))
paul718e3742002-12-13 20:15:29 +00001063
paul147193a2003-04-19 00:31:59 +00001064 if (!ospf_act_bb_connection (ospf) &&
paul718e3742002-12-13 20:15:29 +00001065 or->path_type != OSPF_PATH_INTRA_AREA)
1066 {
1067 if (IS_DEBUG_OSPF_EVENT)
1068 zlog_info ("ospf_abr_process_network_rt(): ALT ABR: "
1069 "No BB connection, skip not intra-area routes");
1070 continue;
1071 }
1072
1073 if (IS_DEBUG_OSPF_EVENT)
1074 zlog_info ("ospf_abr_process_network_rt(): announcing");
hassofa2b17e2004-03-04 17:45:00 +00001075 ospf_abr_announce_network (ospf, (struct prefix_ipv4 *)&rn->p, or);
paul718e3742002-12-13 20:15:29 +00001076 }
1077
1078 if (IS_DEBUG_OSPF_EVENT)
1079 zlog_info ("ospf_abr_process_network_rt(): Stop");
1080}
1081
1082void
1083ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost,
1084 struct ospf_area *area)
1085{
1086 struct ospf_lsa *lsa, *old = NULL;
1087 struct summary_lsa *slsa = NULL;
1088
1089 if (IS_DEBUG_OSPF_EVENT)
1090 zlog_info ("ospf_abr_announce_rtr_to_area(): Start");
1091
paul147193a2003-04-19 00:31:59 +00001092 old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_ASBR_SUMMARY_LSA,
1093 p, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001094 if (old)
1095 {
1096 if (IS_DEBUG_OSPF_EVENT)
1097 zlog_info ("ospf_abr_announce_rtr_to_area(): old summary found");
1098 slsa = (struct summary_lsa *) old->data;
1099
1100 if (IS_DEBUG_OSPF_EVENT)
1101 zlog_info ("ospf_abr_announce_network_to_area(): "
1102 "old metric: %d, new metric: %d",
1103 GET_METRIC (slsa->metric), cost);
1104 }
1105
1106 if (old && (GET_METRIC (slsa->metric) == cost))
1107 {
1108 if (IS_DEBUG_OSPF_EVENT)
1109 zlog_info ("ospf_abr_announce_rtr_to_area(): old summary approved");
1110 SET_FLAG (old->flags, OSPF_LSA_APPROVED);
1111 }
1112 else
1113 {
1114 if (IS_DEBUG_OSPF_EVENT)
1115 zlog_info ("ospf_abr_announce_rtr_to_area(): 2.2");
1116
1117 if (old)
1118 {
1119 set_metric (old, cost);
paul147193a2003-04-19 00:31:59 +00001120 lsa = ospf_summary_asbr_lsa_refresh (area->ospf, old);
paul718e3742002-12-13 20:15:29 +00001121 }
1122 else
1123 lsa = ospf_summary_asbr_lsa_originate (p, cost, area);
1124
1125 if (IS_DEBUG_OSPF_EVENT)
1126 zlog_info ("ospf_abr_announce_rtr_to_area(): "
1127 "flooding new version of summary");
1128 /*
1129 zlog_info ("ospf_abr_announce_rtr_to_area(): creating new summary");
1130 lsa = ospf_summary_asbr_lsa (p, cost, area, old); */
1131
1132 SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1133 /* ospf_flood_through_area (area, NULL, lsa);*/
1134 }
1135
1136 if (IS_DEBUG_OSPF_EVENT)
1137 zlog_info ("ospf_abr_announce_rtr_to_area(): Stop");
1138}
1139
1140
1141void
paul147193a2003-04-19 00:31:59 +00001142ospf_abr_announce_rtr (struct ospf *ospf,
1143 struct prefix_ipv4 *p, struct ospf_route *or)
paul718e3742002-12-13 20:15:29 +00001144{
hasso52dc7ee2004-09-23 19:18:23 +00001145 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001146 struct ospf_area *area;
1147
1148 if (IS_DEBUG_OSPF_EVENT)
1149 zlog_info ("ospf_abr_announce_rtr(): Start");
1150
paul147193a2003-04-19 00:31:59 +00001151 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001152 {
1153 area = getdata (node);
1154
1155 if (IS_DEBUG_OSPF_EVENT)
1156 zlog_info ("ospf_abr_announce_rtr(): looking at area %s",
1157 inet_ntoa (area->area_id));
1158
1159 if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id))
1160 continue;
1161
1162 if (ospf_abr_nexthops_belong_to_area (or, area))
1163 continue;
1164
1165 if (area->external_routing != OSPF_AREA_DEFAULT)
1166 {
1167 if (IS_DEBUG_OSPF_EVENT)
pauld4a53d52003-07-12 21:30:57 +00001168 zlog_info ("ospf_abr_announce_rtr(): "
paul718e3742002-12-13 20:15:29 +00001169 "area %s doesn't support external routing",
1170 inet_ntoa(area->area_id));
1171 continue;
1172 }
1173
1174 if (or->path_type == OSPF_PATH_INTER_AREA)
1175 {
1176 if (IS_DEBUG_OSPF_EVENT)
1177 zlog_info ("ospf_abr_announce_rtr(): "
1178 "this is inter-area route to %s", inet_ntoa (p->prefix));
1179 if (!OSPF_IS_AREA_BACKBONE (area))
1180 ospf_abr_announce_rtr_to_area (p, or->cost, area);
1181 }
1182
1183 if (or->path_type == OSPF_PATH_INTRA_AREA)
1184 {
1185 if (IS_DEBUG_OSPF_EVENT)
1186 zlog_info ("ospf_abr_announce_rtr(): "
1187 "this is intra-area route to %s", inet_ntoa (p->prefix));
1188 ospf_abr_announce_rtr_to_area (p, or->cost, area);
1189 }
1190 }
1191
1192 if (IS_DEBUG_OSPF_EVENT)
1193 zlog_info ("ospf_abr_announce_rtr(): Stop");
1194}
1195
1196void
paul147193a2003-04-19 00:31:59 +00001197ospf_abr_process_router_rt (struct ospf *ospf, struct route_table *rt)
paul718e3742002-12-13 20:15:29 +00001198{
paul718e3742002-12-13 20:15:29 +00001199 struct ospf_route *or;
paul147193a2003-04-19 00:31:59 +00001200 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00001201 struct list *l;
1202
1203 if (IS_DEBUG_OSPF_EVENT)
1204 zlog_info ("ospf_abr_process_router_rt(): Start");
1205
1206 for (rn = route_top (rt); rn; rn = route_next (rn))
1207 {
hasso52dc7ee2004-09-23 19:18:23 +00001208 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001209 char flag = 0;
1210 struct ospf_route *best = NULL;
1211
1212 if (rn->info == NULL)
1213 continue;
1214
1215 l = rn->info;
1216
1217 if (IS_DEBUG_OSPF_EVENT)
1218 zlog_info ("ospf_abr_process_router_rt(): this is a route to %s",
1219 inet_ntoa (rn->p.u.prefix4));
1220
1221 for (node = listhead (l); node; nextnode (node))
1222 {
1223 or = getdata (node);
1224 if (or == NULL)
1225 continue;
1226
paul147193a2003-04-19 00:31:59 +00001227 if (!ospf_area_lookup_by_area_id (ospf, or->u.std.area_id))
paul718e3742002-12-13 20:15:29 +00001228 {
1229 if (IS_DEBUG_OSPF_EVENT)
1230 zlog_info ("ospf_abr_process_router_rt(): area %s no longer exists",
1231 inet_ntoa (or->u.std.area_id));
1232 continue;
1233 }
1234
1235
1236 if (!CHECK_FLAG (or->u.std.flags, ROUTER_LSA_EXTERNAL))
1237 {
1238 if (IS_DEBUG_OSPF_EVENT)
1239 zlog_info ("ospf_abr_process_router_rt(): "
1240 "This is not an ASBR, skipping");
1241 continue;
1242 }
1243
1244 if (!flag)
1245 {
paul147193a2003-04-19 00:31:59 +00001246 best = ospf_find_asbr_route (ospf, rt,
1247 (struct prefix_ipv4 *) &rn->p);
paul718e3742002-12-13 20:15:29 +00001248 flag = 1;
1249 }
1250
1251 if (best == NULL)
1252 continue;
1253
1254 if (or != best)
1255 {
1256 if (IS_DEBUG_OSPF_EVENT)
1257 zlog_info ("ospf_abr_process_router_rt(): "
1258 "This route is not the best among possible, skipping");
1259 continue;
1260 }
1261
1262 if (or->path_type == OSPF_PATH_INTER_AREA &&
1263 !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
1264 {
1265 if (IS_DEBUG_OSPF_EVENT)
1266 zlog_info ("ospf_abr_process_router_rt(): "
1267 "This route is not a backbone one, skipping");
1268 continue;
1269 }
1270
1271 if (or->cost >= OSPF_LS_INFINITY)
1272 {
1273 if (IS_DEBUG_OSPF_EVENT)
1274 zlog_info ("ospf_abr_process_router_rt(): "
1275 "This route has LS_INFINITY metric, skipping");
1276 continue;
1277 }
1278
paul147193a2003-04-19 00:31:59 +00001279 if (ospf->abr_type == OSPF_ABR_CISCO
1280 || ospf->abr_type == OSPF_ABR_IBM)
1281 if (!ospf_act_bb_connection (ospf)
1282 && or->path_type != OSPF_PATH_INTRA_AREA)
paul718e3742002-12-13 20:15:29 +00001283 {
1284 if (IS_DEBUG_OSPF_EVENT)
1285 zlog_info("ospf_abr_process_network_rt(): ALT ABR: "
1286 "No BB connection, skip not intra-area routes");
1287 continue;
1288 }
1289
paul147193a2003-04-19 00:31:59 +00001290 ospf_abr_announce_rtr (ospf, (struct prefix_ipv4 *) &rn->p, or);
paul718e3742002-12-13 20:15:29 +00001291
1292 }
1293
1294 }
1295
1296 if (IS_DEBUG_OSPF_EVENT)
1297 zlog_info ("ospf_abr_process_router_rt(): Stop");
1298}
1299
paul718e3742002-12-13 20:15:29 +00001300void
paul147193a2003-04-19 00:31:59 +00001301ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */
paul718e3742002-12-13 20:15:29 +00001302{
paul147193a2003-04-19 00:31:59 +00001303 struct ospf_lsa *lsa;
1304 struct route_node *rn;
1305
paul718e3742002-12-13 20:15:29 +00001306 if (IS_DEBUG_OSPF_NSSA)
1307 zlog_info ("ospf_abr_unapprove_translates(): Start");
1308
1309 /* NSSA Translator is not checked, because it may have gone away,
1310 and we would want to flush any residuals anyway */
1311
paul147193a2003-04-19 00:31:59 +00001312 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
1313 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
pauld4a53d52003-07-12 21:30:57 +00001314 {
1315 UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1316 if (IS_DEBUG_OSPF_NSSA)
1317 zlog_info ("ospf_abr_unapprove_translates(): "
1318 "approved unset on link id %s",
1319 inet_ntoa (lsa->data->id));
1320 }
paul718e3742002-12-13 20:15:29 +00001321
1322 if (IS_DEBUG_OSPF_NSSA)
1323 zlog_info ("ospf_abr_unapprove_translates(): Stop");
1324}
paul718e3742002-12-13 20:15:29 +00001325
paul718e3742002-12-13 20:15:29 +00001326void
paul147193a2003-04-19 00:31:59 +00001327ospf_abr_unapprove_summaries (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001328{
hasso52dc7ee2004-09-23 19:18:23 +00001329 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001330 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001331 struct route_node *rn;
1332 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00001333
1334 if (IS_DEBUG_OSPF_EVENT)
1335 zlog_info ("ospf_abr_unapprove_summaries(): Start");
1336
paul147193a2003-04-19 00:31:59 +00001337 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001338 {
1339 area = getdata (node);
pauld4a53d52003-07-12 21:30:57 +00001340 if (IS_DEBUG_OSPF_EVENT)
1341 zlog_info ("ospf_abr_unapprove_summaries(): "
1342 "considering area %s",
1343 inet_ntoa (area->area_id));
paul147193a2003-04-19 00:31:59 +00001344 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
pauld4a53d52003-07-12 21:30:57 +00001345 if (ospf_lsa_is_self_originated (ospf, lsa))
1346 {
1347 if (IS_DEBUG_OSPF_EVENT)
1348 zlog_info ("ospf_abr_unapprove_summaries(): "
1349 "approved unset on summary link id %s",
1350 inet_ntoa (lsa->data->id));
1351 UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1352 }
paul147193a2003-04-19 00:31:59 +00001353
1354 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
pauld4a53d52003-07-12 21:30:57 +00001355 if (ospf_lsa_is_self_originated (ospf, lsa))
1356 {
1357 if (IS_DEBUG_OSPF_EVENT)
1358 zlog_info ("ospf_abr_unapprove_summaries(): "
1359 "approved unset on asbr-summary link id %s",
1360 inet_ntoa (lsa->data->id));
1361 UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1362 }
paul718e3742002-12-13 20:15:29 +00001363 }
1364
1365 if (IS_DEBUG_OSPF_EVENT)
1366 zlog_info ("ospf_abr_unapprove_summaries(): Stop");
1367}
1368
1369void
paul147193a2003-04-19 00:31:59 +00001370ospf_abr_prepare_aggregates (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001371{
hasso52dc7ee2004-09-23 19:18:23 +00001372 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001373 struct route_node *rn;
1374 struct ospf_area_range *range;
1375
1376 if (IS_DEBUG_OSPF_EVENT)
1377 zlog_info ("ospf_abr_prepare_aggregates(): Start");
1378
paul147193a2003-04-19 00:31:59 +00001379 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001380 {
1381 struct ospf_area *area = getdata (node);
1382
1383 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1384 if ((range = rn->info) != NULL)
1385 {
1386 range->cost = 0;
1387 range->specifics = 0;
1388 }
1389 }
1390
1391 if (IS_DEBUG_OSPF_EVENT)
1392 zlog_info ("ospf_abr_prepare_aggregates(): Stop");
1393}
1394
1395void
paul147193a2003-04-19 00:31:59 +00001396ospf_abr_announce_aggregates (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001397{
1398 struct ospf_area *area, *ar;
1399 struct ospf_area_range *range;
1400 struct route_node *rn;
pauld4a53d52003-07-12 21:30:57 +00001401 struct prefix p;
hasso52dc7ee2004-09-23 19:18:23 +00001402 struct listnode *node, *n;
paul718e3742002-12-13 20:15:29 +00001403
1404 if (IS_DEBUG_OSPF_EVENT)
1405 zlog_info ("ospf_abr_announce_aggregates(): Start");
1406
paul147193a2003-04-19 00:31:59 +00001407 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001408 {
1409 area = getdata (node);
1410
1411 if (IS_DEBUG_OSPF_EVENT)
1412 zlog_info ("ospf_abr_announce_aggregates(): looking at area %s",
1413 inet_ntoa (area->area_id));
1414
1415 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1416 if ((range = rn->info))
1417 {
1418 if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1419 {
1420 if (IS_DEBUG_OSPF_EVENT)
1421 zlog_info ("ospf_abr_announce_aggregates():"
1422 " discarding suppress-ranges");
1423 continue;
1424 }
1425
1426 p.family = AF_INET;
pauld4a53d52003-07-12 21:30:57 +00001427 p.u.prefix4 = range->addr;
paul718e3742002-12-13 20:15:29 +00001428 p.prefixlen = range->masklen;
1429
1430 if (IS_DEBUG_OSPF_EVENT)
1431 zlog_info ("ospf_abr_announce_aggregates():"
1432 " this is range: %s/%d",
pauld4a53d52003-07-12 21:30:57 +00001433 inet_ntoa (p.u.prefix4), p.prefixlen);
paul718e3742002-12-13 20:15:29 +00001434
1435 if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
1436 {
1437 p.family = AF_INET;
pauld4a53d52003-07-12 21:30:57 +00001438 p.u.prefix4 = range->subst_addr;
paul718e3742002-12-13 20:15:29 +00001439 p.prefixlen = range->subst_masklen;
1440 }
1441
1442 if (range->specifics)
1443 {
1444 if (IS_DEBUG_OSPF_EVENT)
1445 zlog_info ("ospf_abr_announce_aggregates(): active range");
1446
paul147193a2003-04-19 00:31:59 +00001447 for (n = listhead (ospf->areas); n; nextnode (n))
paul718e3742002-12-13 20:15:29 +00001448 {
1449 ar = getdata (n);
1450 if (ar == area)
1451 continue;
1452
1453 /* We do not check nexthops here, because
1454 intra-area routes can be associated with
1455 one area only */
1456
1457 /* backbone routes are not summarized
1458 when announced into transit areas */
1459
1460 if (ospf_area_is_transit (ar) &&
1461 OSPF_IS_AREA_BACKBONE (area))
1462 {
1463 if (IS_DEBUG_OSPF_EVENT)
1464 zlog_info ("ospf_abr_announce_aggregates(): Skipping "
1465 "announcement of BB aggregate into"
1466 " a transit area");
1467 continue;
1468 }
hassofa2b17e2004-03-04 17:45:00 +00001469 ospf_abr_announce_network_to_area ((struct prefix_ipv4 *)&p, range->cost, ar);
paul718e3742002-12-13 20:15:29 +00001470 }
1471 }
1472 }
1473 }
1474
1475 if (IS_DEBUG_OSPF_EVENT)
1476 zlog_info ("ospf_abr_announce_aggregates(): Stop");
1477}
1478
paul718e3742002-12-13 20:15:29 +00001479void
paul147193a2003-04-19 00:31:59 +00001480ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */
paul718e3742002-12-13 20:15:29 +00001481{
hasso52dc7ee2004-09-23 19:18:23 +00001482 struct listnode *node; /*, n; */
paul718e3742002-12-13 20:15:29 +00001483 struct ospf_area *area; /*, *ar; */
1484 struct route_node *rn;
1485 struct ospf_area_range *range;
1486 struct prefix_ipv4 p;
1487
1488 if (IS_DEBUG_OSPF_NSSA)
1489 zlog_info ("ospf_abr_send_nssa_aggregates(): Start");
1490
paul147193a2003-04-19 00:31:59 +00001491 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001492 {
1493 area = getdata (node);
1494
paule2c6c152003-06-22 08:49:25 +00001495 if (! area->NSSATranslatorState)
paul718e3742002-12-13 20:15:29 +00001496 continue;
1497
1498 if (IS_DEBUG_OSPF_NSSA)
1499 zlog_info ("ospf_abr_send_nssa_aggregates(): looking at area %s",
1500 inet_ntoa (area->area_id));
1501
1502 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1503 {
1504 if (rn->info == NULL)
1505 continue;
1506
1507 range = rn->info;
1508
1509 if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1510 {
1511 if (IS_DEBUG_OSPF_NSSA)
1512 zlog_info ("ospf_abr_send_nssa_aggregates():"
1513 " discarding suppress-ranges");
1514 continue;
1515 }
1516
1517 p.family = AF_INET;
1518 p.prefix = range->addr;
1519 p.prefixlen = range->masklen;
1520
1521 if (IS_DEBUG_OSPF_NSSA)
1522 zlog_info ("ospf_abr_send_nssa_aggregates():"
1523 " this is range: %s/%d",
1524 inet_ntoa (p.prefix), p.prefixlen);
1525
1526 if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
1527 {
1528 p.family = AF_INET;
1529 p.prefix = range->subst_addr;
1530 p.prefixlen = range->subst_masklen;
1531 }
1532
1533 if (range->specifics)
paule2c6c152003-06-22 08:49:25 +00001534 {
1535 if (IS_DEBUG_OSPF_NSSA)
1536 zlog_info ("ospf_abr_send_nssa_aggregates(): active range");
paul718e3742002-12-13 20:15:29 +00001537
paule2c6c152003-06-22 08:49:25 +00001538 /* Fetch LSA-Type-7 from aggregate prefix, and then
1539 * translate, Install (as Type-5), Approve, and Flood
1540 */
1541 ospf_abr_translate_nssa_range (&p, range->cost);
1542 }
1543 } /* all area ranges*/
paul718e3742002-12-13 20:15:29 +00001544 } /* all areas */
1545
1546 if (IS_DEBUG_OSPF_NSSA)
1547 zlog_info ("ospf_abr_send_nssa_aggregates(): Stop");
1548}
1549
1550void
paul147193a2003-04-19 00:31:59 +00001551ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */
paul718e3742002-12-13 20:15:29 +00001552{
hasso52dc7ee2004-09-23 19:18:23 +00001553 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001554 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00001555
paul147193a2003-04-19 00:31:59 +00001556 if (! IS_OSPF_ABR (ospf))
paul718e3742002-12-13 20:15:29 +00001557 return;
1558
1559 if (IS_DEBUG_OSPF_NSSA)
1560 zlog_info ("ospf_abr_announce_stub_defaults(): Start");
1561
paul147193a2003-04-19 00:31:59 +00001562 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001563 {
1564 area = getdata (node);
1565 if (IS_DEBUG_OSPF_NSSA)
paule2c6c152003-06-22 08:49:25 +00001566 zlog_info ("ospf_abr_announce_nssa_defaults(): looking at area %s",
1567 inet_ntoa (area->area_id));
paul718e3742002-12-13 20:15:29 +00001568
1569 if (area->external_routing != OSPF_AREA_NSSA)
paule2c6c152003-06-22 08:49:25 +00001570 continue;
paul718e3742002-12-13 20:15:29 +00001571
1572 if (OSPF_IS_AREA_BACKBONE (area))
paule2c6c152003-06-22 08:49:25 +00001573 continue; /* Sanity Check */
paul718e3742002-12-13 20:15:29 +00001574
1575 /* if (!TranslatorRole continue V 1.0 look for "always" conf */
paule2c6c152003-06-22 08:49:25 +00001576 if (area->NSSATranslatorState)
1577 {
1578 if (IS_DEBUG_OSPF_NSSA)
1579 zlog_info ("ospf_abr_announce_nssa_defaults(): "
1580 "announcing 0.0.0.0/0 to this nssa");
1581 /* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */
pauld4a53d52003-07-12 21:30:57 +00001582 /*ospf_abr_announce_network_to_area (&p, area->default_cost, area);*/
paule2c6c152003-06-22 08:49:25 +00001583 }
paul718e3742002-12-13 20:15:29 +00001584 }
1585}
paul718e3742002-12-13 20:15:29 +00001586
1587void
paul147193a2003-04-19 00:31:59 +00001588ospf_abr_announce_stub_defaults (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001589{
hasso52dc7ee2004-09-23 19:18:23 +00001590 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001591 struct ospf_area *area;
1592 struct prefix_ipv4 p;
1593
paul147193a2003-04-19 00:31:59 +00001594 if (! IS_OSPF_ABR (ospf))
paul718e3742002-12-13 20:15:29 +00001595 return;
1596
1597 if (IS_DEBUG_OSPF_EVENT)
1598 zlog_info ("ospf_abr_announce_stub_defaults(): Start");
1599
1600 p.family = AF_INET;
1601 p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
1602 p.prefixlen = 0;
1603
paul147193a2003-04-19 00:31:59 +00001604 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001605 {
1606 area = getdata (node);
1607 if (IS_DEBUG_OSPF_EVENT)
pauld4a53d52003-07-12 21:30:57 +00001608 zlog_info ("ospf_abr_announce_stub_defaults(): looking at area %s",
1609 inet_ntoa (area->area_id));
paul718e3742002-12-13 20:15:29 +00001610
pauld4a53d52003-07-12 21:30:57 +00001611 if ( (area->external_routing != OSPF_AREA_STUB)
pauld4a53d52003-07-12 21:30:57 +00001612 && (area->external_routing != OSPF_AREA_NSSA)
pauld4a53d52003-07-12 21:30:57 +00001613 )
1614 continue;
paul718e3742002-12-13 20:15:29 +00001615
1616 if (OSPF_IS_AREA_BACKBONE (area))
pauld4a53d52003-07-12 21:30:57 +00001617 continue; /* Sanity Check */
1618
paul718e3742002-12-13 20:15:29 +00001619 if (IS_DEBUG_OSPF_EVENT)
pauld4a53d52003-07-12 21:30:57 +00001620 zlog_info ("ospf_abr_announce_stub_defaults(): "
1621 "announcing 0.0.0.0/0 to area %s",
1622 inet_ntoa (area->area_id));
paul718e3742002-12-13 20:15:29 +00001623 ospf_abr_announce_network_to_area (&p, area->default_cost, area);
1624 }
1625
1626 if (IS_DEBUG_OSPF_EVENT)
1627 zlog_info ("ospf_abr_announce_stub_defaults(): Stop");
1628}
1629
paul718e3742002-12-13 20:15:29 +00001630int
paul147193a2003-04-19 00:31:59 +00001631ospf_abr_remove_unapproved_translates_apply (struct ospf *ospf,
1632 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001633{
1634 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)
1635 && ! CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1636 {
1637 zlog_info ("ospf_abr_remove_unapproved_translates(): "
1638 "removing unapproved translates, ID: %s",
1639 inet_ntoa (lsa->data->id));
1640
1641 /* FLUSH THROUGHOUT AS */
paul147193a2003-04-19 00:31:59 +00001642 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001643
1644 /* DISCARD from LSDB */
1645 }
1646 return 0;
1647}
1648
1649void
paul147193a2003-04-19 00:31:59 +00001650ospf_abr_remove_unapproved_translates (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001651{
paul147193a2003-04-19 00:31:59 +00001652 struct route_node *rn;
1653 struct ospf_lsa *lsa;
1654
paul718e3742002-12-13 20:15:29 +00001655 /* All AREA PROCESS should have APPROVED necessary LSAs */
1656 /* Remove any left over and not APPROVED */
1657 if (IS_DEBUG_OSPF_NSSA)
1658 zlog_info ("ospf_abr_remove_unapproved_translates(): Start");
1659
paul147193a2003-04-19 00:31:59 +00001660 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
1661 ospf_abr_remove_unapproved_translates_apply (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001662
1663 if (IS_DEBUG_OSPF_NSSA)
1664 zlog_info ("ospf_abr_remove_unapproved_translates(): Stop");
1665}
paul718e3742002-12-13 20:15:29 +00001666
paul718e3742002-12-13 20:15:29 +00001667void
paul147193a2003-04-19 00:31:59 +00001668ospf_abr_remove_unapproved_summaries (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001669{
hasso52dc7ee2004-09-23 19:18:23 +00001670 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001671 struct ospf_area *area;
paul147193a2003-04-19 00:31:59 +00001672 struct route_node *rn;
1673 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00001674
1675 if (IS_DEBUG_OSPF_EVENT)
1676 zlog_info ("ospf_abr_remove_unapproved_summaries(): Start");
1677
paul147193a2003-04-19 00:31:59 +00001678 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001679 {
1680 area = getdata (node);
1681
1682 if (IS_DEBUG_OSPF_EVENT)
1683 zlog_info ("ospf_abr_remove_unapproved_summaries(): "
1684 "looking at area %s", inet_ntoa (area->area_id));
1685
paul147193a2003-04-19 00:31:59 +00001686 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
1687 if (ospf_lsa_is_self_originated (ospf, lsa))
1688 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1689 ospf_lsa_flush_area (lsa, area);
1690
1691 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
1692 if (ospf_lsa_is_self_originated (ospf, lsa))
1693 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1694 ospf_lsa_flush_area (lsa, area);
paul718e3742002-12-13 20:15:29 +00001695 }
1696
1697 if (IS_DEBUG_OSPF_EVENT)
1698 zlog_info ("ospf_abr_remove_unapproved_summaries(): Stop");
1699}
1700
1701void
paul147193a2003-04-19 00:31:59 +00001702ospf_abr_manage_discard_routes (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001703{
hasso52dc7ee2004-09-23 19:18:23 +00001704 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001705 struct route_node *rn;
1706 struct ospf_area *area;
1707 struct ospf_area_range *range;
1708
paul147193a2003-04-19 00:31:59 +00001709 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001710 if ((area = node->data) != NULL)
1711 for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1712 if ((range = rn->info) != NULL)
1713 if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1714 {
1715 if (range->specifics)
paul147193a2003-04-19 00:31:59 +00001716 ospf_add_discard_route (ospf->new_table, area,
paul718e3742002-12-13 20:15:29 +00001717 (struct prefix_ipv4 *) &rn->p);
1718 else
1719 ospf_delete_discard_route ((struct prefix_ipv4 *) &rn->p);
1720 }
1721}
1722
paul718e3742002-12-13 20:15:29 +00001723/* This is the function taking care about ABR NSSA, i.e. NSSA
1724 Translator, -LSA aggregation and flooding. For all NSSAs
1725
1726 Any SELF-AS-LSA is in the Type-5 LSDB and Type-7 LSDB. These LSA's
1727 are refreshed from the Type-5 LSDB, installed into the Type-7 LSDB
1728 with the P-bit set.
1729
1730 Any received Type-5s are legal for an ABR, else illegal for IR.
1731 Received Type-7s are installed, by area, with incoming P-bit. They
1732 are flooded; if the Elected NSSA Translator, then P-bit off.
1733
1734 Additionally, this ABR will place "translated type-7's" into the
1735 Type-5 LSDB in order to keep track of APPROVAL or not.
1736
1737 It will scan through every area, looking for Type-7 LSAs with P-Bit
1738 SET. The Type-7's are either AS-FLOODED & 5-INSTALLED or
1739 AGGREGATED. Later, the AGGREGATED LSAs are AS-FLOODED &
1740 5-INSTALLED.
1741
1742 5-INSTALLED is into the Type-5 LSDB; Any UNAPPROVED Type-5 LSAs
1743 left over are FLUSHED and DISCARDED.
1744
1745 For External Calculations, any NSSA areas use the Type-7 AREA-LSDB,
1746 any ABR-non-NSSA areas use the Type-5 GLOBAL-LSDB. */
1747
1748void
paul147193a2003-04-19 00:31:59 +00001749ospf_abr_nssa_task (struct ospf *ospf) /* called only if any_nssa */
paul718e3742002-12-13 20:15:29 +00001750{
1751 if (IS_DEBUG_OSPF_NSSA)
1752 zlog_info ("Check for NSSA-ABR Tasks():");
1753
paul147193a2003-04-19 00:31:59 +00001754 if (! IS_OSPF_ABR (ospf))
paul718e3742002-12-13 20:15:29 +00001755 return;
1756
paul147193a2003-04-19 00:31:59 +00001757 if (! ospf->anyNSSA)
paul718e3742002-12-13 20:15:29 +00001758 return;
1759
1760 /* Each area must confirm TranslatorRole */
1761 if (IS_DEBUG_OSPF_NSSA)
1762 zlog_info ("ospf_abr_nssa_task(): Start");
1763
1764 /* For all Global Entries flagged "local-translate", unset APPROVED */
1765 if (IS_DEBUG_OSPF_NSSA)
1766 zlog_info ("ospf_abr_nssa_task(): unapprove translates");
1767
paul147193a2003-04-19 00:31:59 +00001768 ospf_abr_unapprove_translates (ospf);
paul718e3742002-12-13 20:15:29 +00001769
1770 /* RESET all Ranges in every Area, same as summaries */
1771 if (IS_DEBUG_OSPF_NSSA)
1772 zlog_info ("ospf_abr_nssa_task(): NSSA initialize aggregates");
paule2c6c152003-06-22 08:49:25 +00001773 ospf_abr_prepare_aggregates (ospf); /*TURNED OFF just for now */
paul718e3742002-12-13 20:15:29 +00001774
1775 /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or
paule2c6c152003-06-22 08:49:25 +00001776 * Aggregate as Type-7
1777 * Install or Approve in Type-5 Global LSDB
1778 */
paul718e3742002-12-13 20:15:29 +00001779 if (IS_DEBUG_OSPF_NSSA)
1780 zlog_info ("ospf_abr_nssa_task(): process translates");
paul147193a2003-04-19 00:31:59 +00001781 ospf_abr_process_nssa_translates (ospf);
paul718e3742002-12-13 20:15:29 +00001782
1783 /* Translate/Send any "ranged" aggregates, and also 5-Install and
paule2c6c152003-06-22 08:49:25 +00001784 * Approve
1785 * Scan Type-7's for aggregates, translate to Type-5's,
1786 * Install/Flood/Approve
1787 */
paul718e3742002-12-13 20:15:29 +00001788 if (IS_DEBUG_OSPF_NSSA)
1789 zlog_info("ospf_abr_nssa_task(): send NSSA aggregates");
paule2c6c152003-06-22 08:49:25 +00001790 ospf_abr_send_nssa_aggregates (ospf); /*TURNED OFF FOR NOW */
paul718e3742002-12-13 20:15:29 +00001791
pauld4a53d52003-07-12 21:30:57 +00001792 /* Send any NSSA defaults as Type-5
1793 *if (IS_DEBUG_OSPF_NSSA)
1794 * zlog_info ("ospf_abr_nssa_task(): announce nssa defaults");
1795 *ospf_abr_announce_nssa_defaults (ospf);
1796 * havnt a clue what above is supposed to do.
1797 */
paul718e3742002-12-13 20:15:29 +00001798
1799 /* Flush any unapproved previous translates from Global Data Base */
1800 if (IS_DEBUG_OSPF_NSSA)
1801 zlog_info ("ospf_abr_nssa_task(): remove unapproved translates");
paul147193a2003-04-19 00:31:59 +00001802 ospf_abr_remove_unapproved_translates (ospf);
paul718e3742002-12-13 20:15:29 +00001803
paul147193a2003-04-19 00:31:59 +00001804 ospf_abr_manage_discard_routes (ospf); /* same as normal...discard */
paul718e3742002-12-13 20:15:29 +00001805
1806 if (IS_DEBUG_OSPF_NSSA)
1807 zlog_info ("ospf_abr_nssa_task(): Stop");
1808}
paul718e3742002-12-13 20:15:29 +00001809
1810/* This is the function taking care about ABR stuff, i.e.
1811 summary-LSA origination and flooding. */
1812void
paul147193a2003-04-19 00:31:59 +00001813ospf_abr_task (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001814{
1815 if (IS_DEBUG_OSPF_EVENT)
1816 zlog_info ("ospf_abr_task(): Start");
1817
paul147193a2003-04-19 00:31:59 +00001818 if (ospf->new_table == NULL || ospf->new_rtrs == NULL)
paul718e3742002-12-13 20:15:29 +00001819 {
1820 if (IS_DEBUG_OSPF_EVENT)
1821 zlog_info ("ospf_abr_task(): Routing tables are not yet ready");
1822 return;
1823 }
1824
1825 if (IS_DEBUG_OSPF_EVENT)
1826 zlog_info ("ospf_abr_task(): unapprove summaries");
paul147193a2003-04-19 00:31:59 +00001827 ospf_abr_unapprove_summaries (ospf);
paul718e3742002-12-13 20:15:29 +00001828
1829 if (IS_DEBUG_OSPF_EVENT)
1830 zlog_info ("ospf_abr_task(): prepare aggregates");
paul147193a2003-04-19 00:31:59 +00001831 ospf_abr_prepare_aggregates (ospf);
paul718e3742002-12-13 20:15:29 +00001832
paul147193a2003-04-19 00:31:59 +00001833 if (IS_OSPF_ABR (ospf))
paul718e3742002-12-13 20:15:29 +00001834 {
1835 if (IS_DEBUG_OSPF_EVENT)
1836 zlog_info ("ospf_abr_task(): process network RT");
paul147193a2003-04-19 00:31:59 +00001837 ospf_abr_process_network_rt (ospf, ospf->new_table);
paul718e3742002-12-13 20:15:29 +00001838
1839 if (IS_DEBUG_OSPF_EVENT)
1840 zlog_info ("ospf_abr_task(): process router RT");
paul147193a2003-04-19 00:31:59 +00001841 ospf_abr_process_router_rt (ospf, ospf->new_rtrs);
paul718e3742002-12-13 20:15:29 +00001842
1843 if (IS_DEBUG_OSPF_EVENT)
1844 zlog_info ("ospf_abr_task(): announce aggregates");
paul147193a2003-04-19 00:31:59 +00001845 ospf_abr_announce_aggregates (ospf);
paul718e3742002-12-13 20:15:29 +00001846
1847 if (IS_DEBUG_OSPF_EVENT)
1848 zlog_info ("ospf_abr_task(): announce stub defaults");
paul147193a2003-04-19 00:31:59 +00001849 ospf_abr_announce_stub_defaults (ospf);
paul718e3742002-12-13 20:15:29 +00001850 }
1851
1852 if (IS_DEBUG_OSPF_EVENT)
1853 zlog_info ("ospf_abr_task(): remove unapproved summaries");
paul147193a2003-04-19 00:31:59 +00001854 ospf_abr_remove_unapproved_summaries (ospf);
paul718e3742002-12-13 20:15:29 +00001855
paul147193a2003-04-19 00:31:59 +00001856 ospf_abr_manage_discard_routes (ospf);
paul718e3742002-12-13 20:15:29 +00001857
paul718e3742002-12-13 20:15:29 +00001858 if (IS_DEBUG_OSPF_EVENT)
1859 zlog_info ("ospf_abr_task(): Stop");
1860}
1861
1862
1863int
paul147193a2003-04-19 00:31:59 +00001864ospf_abr_task_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00001865{
paul147193a2003-04-19 00:31:59 +00001866 struct ospf *ospf = THREAD_ARG (thread);
1867
1868 ospf->t_abr_task = 0;
paul718e3742002-12-13 20:15:29 +00001869
1870 if (IS_DEBUG_OSPF_EVENT)
1871 zlog_info ("Running ABR task on timer");
1872
paul147193a2003-04-19 00:31:59 +00001873 ospf_check_abr_status (ospf);
pauld4a53d52003-07-12 21:30:57 +00001874 ospf_abr_nssa_check_status (ospf);
paul718e3742002-12-13 20:15:29 +00001875
paul147193a2003-04-19 00:31:59 +00001876 ospf_abr_task (ospf);
paule2c6c152003-06-22 08:49:25 +00001877 ospf_abr_nssa_task (ospf); /* if nssa-abr, then scan Type-7 LSDB */
paul718e3742002-12-13 20:15:29 +00001878
paul147193a2003-04-19 00:31:59 +00001879 return 0;
paul718e3742002-12-13 20:15:29 +00001880}
1881
1882void
paul147193a2003-04-19 00:31:59 +00001883ospf_schedule_abr_task (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001884{
1885 if (IS_DEBUG_OSPF_EVENT)
1886 zlog_info ("Scheduling ABR task");
paul147193a2003-04-19 00:31:59 +00001887
1888 if (ospf->t_abr_task == NULL)
1889 ospf->t_abr_task = thread_add_timer (master, ospf_abr_task_timer,
1890 ospf, OSPF_ABR_TASK_DELAY);
paul718e3742002-12-13 20:15:29 +00001891}