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