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