Annotation of embedaddon/quagga/ospfd/ospf_abr.c, revision 1.1.1.2
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
1.1.1.2 ! misho 387: if (IPV4_ADDR_CMP (&best->s_addr, &lsa->data->id.s_addr) < 0)
1.1 misho 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:
1.1.1.2 ! misho 398: if (IPV4_ADDR_CMP (&best->s_addr, &area->ospf->router_id.s_addr) < 0)
1.1 misho 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: /* ospf_abr_translate_nssa */
617: static int
618: ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa)
619: {
620: /* Incoming Type-7 or later aggregated Type-7
621: *
622: * LSA is skipped if P-bit is off.
623: * LSA is aggregated if within range.
624: *
625: * The Type-7 is translated, Installed/Approved as a Type-5 into
626: * global LSDB, then Flooded through AS
627: *
628: * Later, any Unapproved Translated Type-5's are flushed/discarded
629: */
630:
631: struct ospf_lsa *old = NULL,
632: *new = NULL;
633: struct as_external_lsa *ext7;
634: struct prefix_ipv4 p;
635:
636: if (! CHECK_FLAG (lsa->data->options, OSPF_OPTION_NP))
637: {
638: if (IS_DEBUG_OSPF_NSSA)
639: zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation",
640: inet_ntoa (lsa->data->id));
641: return 1;
642: }
643:
644: if (IS_DEBUG_OSPF_NSSA)
645: zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5",
646: inet_ntoa (lsa->data->id));
647:
648: ext7 = (struct as_external_lsa *)(lsa->data);
649: p.prefix = lsa->data->id;
650: p.prefixlen = ip_masklen (ext7->mask);
651:
652: if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION)
653: {
654: if (IS_DEBUG_OSPF_NSSA)
655: zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, "
656: "Forward address is 0, NO Translation",
657: inet_ntoa (lsa->data->id));
658: return 1;
659: }
660:
661: /* try find existing AS-External LSA for this prefix */
662:
663: old = ospf_external_info_find_lsa (area->ospf, &p);
664:
665: if (old)
666: {
667: if (IS_DEBUG_OSPF_NSSA)
668: zlog_debug ("ospf_abr_translate_nssa(): "
669: "found old translated LSA Id %s, refreshing",
670: inet_ntoa (old->data->id));
671:
672: /* refresh */
673: new = ospf_translated_nssa_refresh (area->ospf, lsa, old);
674: if (!new)
675: {
676: if (IS_DEBUG_OSPF_NSSA)
677: zlog_debug ("ospf_abr_translate_nssa(): "
678: "could not refresh translated LSA Id %s",
679: inet_ntoa (old->data->id));
680: }
681: }
682: else
683: {
684: /* no existing external route for this LSA Id
685: * originate translated LSA
686: */
687:
688: if ((new = ospf_translated_nssa_originate (area->ospf, lsa))
689: == NULL)
690: {
691: if (IS_DEBUG_OSPF_NSSA)
692: zlog_debug ("ospf_abr_translate_nssa(): Could not translate "
693: "Type-7 for %s to Type-5",
694: inet_ntoa (lsa->data->id));
695: return 1;
696: }
697: }
698:
699: /* Area where Aggregate testing will be inserted, just like summary
700: advertisements */
701: /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */
702:
703: return 0;
704: }
705:
706: static void
707: ospf_abr_translate_nssa_range (struct prefix_ipv4 *p, u_int32_t cost)
708: {
709: /* The Type-7 is created from the aggregated prefix and forwarded
710: for lsa installation and flooding... to be added... */
711: }
712:
713: void
714: ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
715: struct ospf_area *area)
716: {
717: struct ospf_lsa *lsa, *old = NULL;
718: struct summary_lsa *sl = NULL;
719:
720: if (IS_DEBUG_OSPF_EVENT)
721: zlog_debug ("ospf_abr_announce_network_to_area(): Start");
722:
723: old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA,
724: (struct prefix_ipv4 *) p,
725: area->ospf->router_id);
726: if (old)
727: {
728: if (IS_DEBUG_OSPF_EVENT)
729: zlog_debug ("ospf_abr_announce_network_to_area(): old summary found");
730:
731: sl = (struct summary_lsa *) old->data;
732:
733: if (IS_DEBUG_OSPF_EVENT)
734: zlog_debug ("ospf_abr_announce_network_to_area(): "
735: "old metric: %d, new metric: %d",
736: GET_METRIC (sl->metric), cost);
737:
738: if (GET_METRIC (sl->metric) == cost)
739: {
740: /* unchanged. simply reapprove it */
741: if (IS_DEBUG_OSPF_EVENT)
742: zlog_debug ("ospf_abr_announce_network_to_area(): "
743: "old summary approved");
744: SET_FLAG (old->flags, OSPF_LSA_APPROVED);
745: }
746: else
747: {
748: /* LSA is changed, refresh it */
749: if (IS_DEBUG_OSPF_EVENT)
750: zlog_debug ("ospf_abr_announce_network_to_area(): "
751: "refreshing summary");
752: set_metric (old, cost);
753: lsa = ospf_lsa_refresh (area->ospf, old);
754:
755: if (!lsa)
756: {
757: char buf[INET_ADDRSTRLEN + 3]; /* ipv4 and /XX */
758:
759: prefix2str ((struct prefix *) p, buf, sizeof(buf));
760: zlog_warn ("%s: Could not refresh %s to %s",
761: __func__,
762: buf,
763: inet_ntoa (area->area_id));
764: return;
765: }
766:
767: SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
768: /* This will flood through area. */
769: }
770: }
771: else
772: {
773: if (IS_DEBUG_OSPF_EVENT)
774: zlog_debug ("ospf_abr_announce_network_to_area(): "
775: "creating new summary");
776: lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, cost, area);
777: /* This will flood through area. */
778:
779: if (!lsa)
780: {
781: char buf[INET_ADDRSTRLEN + 3]; /* ipv4 and /XX */
782:
783: prefix2str ((struct prefix *)p, buf, sizeof(buf));
784: zlog_warn ("%s: Could not originate %s to %s",
785: __func__,
786: buf,
787: inet_ntoa (area->area_id));
788: return;
789: }
790:
791: SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
792: if (IS_DEBUG_OSPF_EVENT)
793: zlog_debug ("ospf_abr_announce_network_to_area(): "
794: "flooding new version of summary");
795: }
796:
797: if (IS_DEBUG_OSPF_EVENT)
798: zlog_debug ("ospf_abr_announce_network_to_area(): Stop");
799: }
800:
801: static int
802: ospf_abr_nexthops_belong_to_area (struct ospf_route *or,
803: struct ospf_area *area)
804: {
805: struct listnode *node, *nnode;
806: struct ospf_path *path;
807: struct ospf_interface *oi;
808:
809: for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
810: for (ALL_LIST_ELEMENTS_RO (area->oiflist, nnode, oi))
811: if (oi->ifp && oi->ifp->ifindex == path->ifindex)
812: return 1;
813:
814: return 0;
815: }
816:
817: static int
818: ospf_abr_should_accept (struct prefix_ipv4 *p, struct ospf_area *area)
819: {
820: if (IMPORT_NAME (area))
821: {
822: if (IMPORT_LIST (area) == NULL)
823: IMPORT_LIST (area) = access_list_lookup (AFI_IP, IMPORT_NAME (area));
824:
825: if (IMPORT_LIST (area))
826: if (access_list_apply (IMPORT_LIST (area), p) == FILTER_DENY)
827: return 0;
828: }
829:
830: return 1;
831: }
832:
833: static int
834: ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or,
835: struct prefix_ipv4 *p)
836: {
837: if (PREFIX_NAME_IN (area))
838: {
839: if (PREFIX_LIST_IN (area) == NULL)
840: PREFIX_LIST_IN (area) = prefix_list_lookup (AFI_IP,
841: PREFIX_NAME_IN (area));
842: if (PREFIX_LIST_IN (area))
843: if (prefix_list_apply (PREFIX_LIST_IN (area), p) != PREFIX_PERMIT)
844: return 0;
845: }
846: return 1;
847: }
848:
849: static int
850: ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or,
851: struct prefix_ipv4 *p)
852: {
853: if (PREFIX_NAME_OUT (area))
854: {
855: if (PREFIX_LIST_OUT (area) == NULL)
856: PREFIX_LIST_OUT (area) = prefix_list_lookup (AFI_IP,
857: PREFIX_NAME_OUT (area));
858: if (PREFIX_LIST_OUT (area))
859: if (prefix_list_apply (PREFIX_LIST_OUT (area), p) != PREFIX_PERMIT)
860: return 0;
861: }
862: return 1;
863: }
864:
865: static void
866: ospf_abr_announce_network (struct ospf *ospf,
867: struct prefix_ipv4 *p, struct ospf_route *or)
868: {
869: struct ospf_area_range *range;
870: struct ospf_area *area, *or_area;
871: struct listnode *node;
872:
873: if (IS_DEBUG_OSPF_EVENT)
874: zlog_debug ("ospf_abr_announce_network(): Start");
875:
876: or_area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id);
877: assert (or_area);
878:
879: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
880: {
881: if (IS_DEBUG_OSPF_EVENT)
882: zlog_debug ("ospf_abr_announce_network(): looking at area %s",
883: inet_ntoa (area->area_id));
884:
885: if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id))
886: continue;
887:
888: if (ospf_abr_nexthops_belong_to_area (or, area))
889: continue;
890:
891: if (!ospf_abr_should_accept (p, area))
892: {
893: if (IS_DEBUG_OSPF_EVENT)
894: zlog_debug ("ospf_abr_announce_network(): "
895: "prefix %s/%d was denied by import-list",
896: inet_ntoa (p->prefix), p->prefixlen);
897: continue;
898: }
899:
900: if (!ospf_abr_plist_in_check (area, or, p))
901: {
902: if (IS_DEBUG_OSPF_EVENT)
903: zlog_debug ("ospf_abr_announce_network(): "
904: "prefix %s/%d was denied by prefix-list",
905: inet_ntoa (p->prefix), p->prefixlen);
906: continue;
907: }
908:
909: if (area->external_routing != OSPF_AREA_DEFAULT && area->no_summary)
910: {
911: if (IS_DEBUG_OSPF_EVENT)
912: zlog_debug ("ospf_abr_announce_network(): "
913: "area %s is stub and no_summary",
914: inet_ntoa (area->area_id));
915: continue;
916: }
917:
918: if (or->path_type == OSPF_PATH_INTER_AREA)
919: {
920: if (IS_DEBUG_OSPF_EVENT)
921: zlog_debug ("ospf_abr_announce_network(): this is "
922: "inter-area route to %s/%d",
923: inet_ntoa (p->prefix), p->prefixlen);
924:
925: if (!OSPF_IS_AREA_BACKBONE (area))
926: ospf_abr_announce_network_to_area (p, or->cost, area);
927: }
928:
929: if (or->path_type == OSPF_PATH_INTRA_AREA)
930: {
931: if (IS_DEBUG_OSPF_EVENT)
932: zlog_debug ("ospf_abr_announce_network(): "
933: "this is intra-area route to %s/%d",
934: inet_ntoa (p->prefix), p->prefixlen);
935: if ((range = ospf_area_range_match (or_area, p))
936: && !ospf_area_is_transit (area))
937: ospf_abr_update_aggregate (range, or);
938: else
939: ospf_abr_announce_network_to_area (p, or->cost, area);
940: }
941: }
942: }
943:
944: static int
945: ospf_abr_should_announce (struct ospf *ospf,
946: struct prefix_ipv4 *p, struct ospf_route *or)
947: {
948: struct ospf_area *area;
949:
950: area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id);
951:
952: assert (area);
953:
954: if (EXPORT_NAME (area))
955: {
956: if (EXPORT_LIST (area) == NULL)
957: EXPORT_LIST (area) = access_list_lookup (AFI_IP, EXPORT_NAME (area));
958:
959: if (EXPORT_LIST (area))
960: if (access_list_apply (EXPORT_LIST (area), p) == FILTER_DENY)
961: return 0;
962: }
963:
964: return 1;
965: }
966:
967: static void
968: ospf_abr_process_nssa_translates (struct ospf *ospf)
969: {
970: /* Scan through all NSSA_LSDB records for all areas;
971:
972: If P-bit is on, translate all Type-7's to 5's and aggregate or
973: flood install as approved in Type-5 LSDB with XLATE Flag on
974: later, do same for all aggregates... At end, DISCARD all
975: remaining UNAPPROVED Type-5's (Aggregate is for future ) */
976: struct listnode *node;
977: struct ospf_area *area;
978: struct route_node *rn;
979: struct ospf_lsa *lsa;
980:
981: if (IS_DEBUG_OSPF_NSSA)
982: zlog_debug ("ospf_abr_process_nssa_translates(): Start");
983:
984: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
985: {
986: if (! area->NSSATranslatorState)
987: continue; /* skip if not translator */
988:
989: if (area->external_routing != OSPF_AREA_NSSA)
990: continue; /* skip if not Nssa Area */
991:
992: if (IS_DEBUG_OSPF_NSSA)
993: zlog_debug ("ospf_abr_process_nssa_translates(): "
994: "looking at area %s", inet_ntoa (area->area_id));
995:
996: LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
997: ospf_abr_translate_nssa (area, lsa);
998: }
999:
1000: if (IS_DEBUG_OSPF_NSSA)
1001: zlog_debug ("ospf_abr_process_nssa_translates(): Stop");
1002:
1003: }
1004:
1005: static void
1006: ospf_abr_process_network_rt (struct ospf *ospf,
1007: struct route_table *rt)
1008: {
1009: struct ospf_area *area;
1010: struct ospf_route *or;
1011: struct route_node *rn;
1012:
1013: if (IS_DEBUG_OSPF_EVENT)
1014: zlog_debug ("ospf_abr_process_network_rt(): Start");
1015:
1016: for (rn = route_top (rt); rn; rn = route_next (rn))
1017: {
1018: if ((or = rn->info) == NULL)
1019: continue;
1020:
1021: if (!(area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id)))
1022: {
1023: if (IS_DEBUG_OSPF_EVENT)
1024: zlog_debug ("ospf_abr_process_network_rt(): area %s no longer exists",
1025: inet_ntoa (or->u.std.area_id));
1026: continue;
1027: }
1028:
1029: if (IS_DEBUG_OSPF_EVENT)
1030: zlog_debug ("ospf_abr_process_network_rt(): this is a route to %s/%d",
1031: inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
1032: if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL)
1033: {
1034: if (IS_DEBUG_OSPF_EVENT)
1035: zlog_debug ("ospf_abr_process_network_rt(): "
1036: "this is an External router, skipping");
1037: continue;
1038: }
1039:
1040: if (or->cost >= OSPF_LS_INFINITY)
1041: {
1042: if (IS_DEBUG_OSPF_EVENT)
1043: zlog_debug ("ospf_abr_process_network_rt():"
1044: " this route's cost is infinity, skipping");
1045: continue;
1046: }
1047:
1048: if (or->type == OSPF_DESTINATION_DISCARD)
1049: {
1050: if (IS_DEBUG_OSPF_EVENT)
1051: zlog_debug ("ospf_abr_process_network_rt():"
1052: " this is a discard entry, skipping");
1053: continue;
1054: }
1055:
1056: if (or->path_type == OSPF_PATH_INTRA_AREA &&
1057: !ospf_abr_should_announce (ospf, (struct prefix_ipv4 *) &rn->p, or))
1058: {
1059: if (IS_DEBUG_OSPF_EVENT)
1060: zlog_debug("ospf_abr_process_network_rt(): denied by export-list");
1061: continue;
1062: }
1063:
1064: if (or->path_type == OSPF_PATH_INTRA_AREA &&
1065: !ospf_abr_plist_out_check (area, or, (struct prefix_ipv4 *) &rn->p))
1066: {
1067: if (IS_DEBUG_OSPF_EVENT)
1068: zlog_debug("ospf_abr_process_network_rt(): denied by prefix-list");
1069: continue;
1070: }
1071:
1072: if ((or->path_type == OSPF_PATH_INTER_AREA) &&
1073: !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
1074: {
1075: if (IS_DEBUG_OSPF_EVENT)
1076: zlog_debug ("ospf_abr_process_network_rt():"
1077: " this is route is not backbone one, skipping");
1078: continue;
1079: }
1080:
1081:
1082: if ((ospf->abr_type == OSPF_ABR_CISCO) ||
1083: (ospf->abr_type == OSPF_ABR_IBM))
1084:
1085: if (!ospf_act_bb_connection (ospf) &&
1086: or->path_type != OSPF_PATH_INTRA_AREA)
1087: {
1088: if (IS_DEBUG_OSPF_EVENT)
1089: zlog_debug ("ospf_abr_process_network_rt(): ALT ABR: "
1090: "No BB connection, skip not intra-area routes");
1091: continue;
1092: }
1093:
1094: if (IS_DEBUG_OSPF_EVENT)
1095: zlog_debug ("ospf_abr_process_network_rt(): announcing");
1096: ospf_abr_announce_network (ospf, (struct prefix_ipv4 *)&rn->p, or);
1097: }
1098:
1099: if (IS_DEBUG_OSPF_EVENT)
1100: zlog_debug ("ospf_abr_process_network_rt(): Stop");
1101: }
1102:
1103: static void
1104: ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost,
1105: struct ospf_area *area)
1106: {
1107: struct ospf_lsa *lsa, *old = NULL;
1108: struct summary_lsa *slsa = NULL;
1109:
1110: if (IS_DEBUG_OSPF_EVENT)
1111: zlog_debug ("ospf_abr_announce_rtr_to_area(): Start");
1112:
1113: old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_ASBR_SUMMARY_LSA,
1114: p, area->ospf->router_id);
1115: if (old)
1116: {
1117: if (IS_DEBUG_OSPF_EVENT)
1118: zlog_debug ("ospf_abr_announce_rtr_to_area(): old summary found");
1119: slsa = (struct summary_lsa *) old->data;
1120:
1121: if (IS_DEBUG_OSPF_EVENT)
1122: zlog_debug ("ospf_abr_announce_network_to_area(): "
1123: "old metric: %d, new metric: %d",
1124: GET_METRIC (slsa->metric), cost);
1125: }
1126:
1127: if (old && (GET_METRIC (slsa->metric) == cost))
1128: {
1129: if (IS_DEBUG_OSPF_EVENT)
1130: zlog_debug ("ospf_abr_announce_rtr_to_area(): old summary approved");
1131: SET_FLAG (old->flags, OSPF_LSA_APPROVED);
1132: }
1133: else
1134: {
1135: if (IS_DEBUG_OSPF_EVENT)
1136: zlog_debug ("ospf_abr_announce_rtr_to_area(): 2.2");
1137:
1138: if (old)
1139: {
1140: set_metric (old, cost);
1141: lsa = ospf_lsa_refresh (area->ospf, old);
1142: }
1143: else
1144: lsa = ospf_summary_asbr_lsa_originate (p, cost, area);
1145: if (!lsa)
1146: {
1147: char buf[INET_ADDRSTRLEN + 3]; /* ipv4 and /XX */
1148:
1149: prefix2str ((struct prefix *)p, buf, sizeof(buf));
1150: zlog_warn ("%s: Could not refresh/originate %s to %s",
1151: __func__,
1152: buf,
1153: inet_ntoa (area->area_id));
1154: return;
1155: }
1156:
1157: if (IS_DEBUG_OSPF_EVENT)
1158: zlog_debug ("ospf_abr_announce_rtr_to_area(): "
1159: "flooding new version of summary");
1160:
1161: /*
1162: zlog_info ("ospf_abr_announce_rtr_to_area(): creating new summary");
1163: lsa = ospf_summary_asbr_lsa (p, cost, area, old); */
1164:
1165: SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1166: /* ospf_flood_through_area (area, NULL, lsa);*/
1167: }
1168:
1169: if (IS_DEBUG_OSPF_EVENT)
1170: zlog_debug ("ospf_abr_announce_rtr_to_area(): Stop");
1171: }
1172:
1173:
1174: static void
1175: ospf_abr_announce_rtr (struct ospf *ospf,
1176: struct prefix_ipv4 *p, struct ospf_route *or)
1177: {
1178: struct listnode *node;
1179: struct ospf_area *area;
1180:
1181: if (IS_DEBUG_OSPF_EVENT)
1182: zlog_debug ("ospf_abr_announce_rtr(): Start");
1183:
1184: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1185: {
1186: if (IS_DEBUG_OSPF_EVENT)
1187: zlog_debug ("ospf_abr_announce_rtr(): looking at area %s",
1188: inet_ntoa (area->area_id));
1189:
1190: if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id))
1191: continue;
1192:
1193: if (ospf_abr_nexthops_belong_to_area (or, area))
1194: continue;
1195:
1196: if (area->external_routing != OSPF_AREA_DEFAULT)
1197: {
1198: if (IS_DEBUG_OSPF_EVENT)
1199: zlog_debug ("ospf_abr_announce_rtr(): "
1200: "area %s doesn't support external routing",
1201: inet_ntoa(area->area_id));
1202: continue;
1203: }
1204:
1205: if (or->path_type == OSPF_PATH_INTER_AREA)
1206: {
1207: if (IS_DEBUG_OSPF_EVENT)
1208: zlog_debug ("ospf_abr_announce_rtr(): "
1209: "this is inter-area route to %s", inet_ntoa (p->prefix));
1210: if (!OSPF_IS_AREA_BACKBONE (area))
1211: ospf_abr_announce_rtr_to_area (p, or->cost, area);
1212: }
1213:
1214: if (or->path_type == OSPF_PATH_INTRA_AREA)
1215: {
1216: if (IS_DEBUG_OSPF_EVENT)
1217: zlog_debug ("ospf_abr_announce_rtr(): "
1218: "this is intra-area route to %s", inet_ntoa (p->prefix));
1219: ospf_abr_announce_rtr_to_area (p, or->cost, area);
1220: }
1221: }
1222:
1223: if (IS_DEBUG_OSPF_EVENT)
1224: zlog_debug ("ospf_abr_announce_rtr(): Stop");
1225: }
1226:
1227: static void
1228: ospf_abr_process_router_rt (struct ospf *ospf, struct route_table *rt)
1229: {
1230: struct ospf_route *or;
1231: struct route_node *rn;
1232: struct list *l;
1233:
1234: if (IS_DEBUG_OSPF_EVENT)
1235: zlog_debug ("ospf_abr_process_router_rt(): Start");
1236:
1237: for (rn = route_top (rt); rn; rn = route_next (rn))
1238: {
1239: struct listnode *node, *nnode;
1240: char flag = 0;
1241: struct ospf_route *best = NULL;
1242:
1243: if (rn->info == NULL)
1244: continue;
1245:
1246: l = rn->info;
1247:
1248: if (IS_DEBUG_OSPF_EVENT)
1249: zlog_debug ("ospf_abr_process_router_rt(): this is a route to %s",
1250: inet_ntoa (rn->p.u.prefix4));
1251:
1252: for (ALL_LIST_ELEMENTS (l, node, nnode, or))
1253: {
1254: if (!ospf_area_lookup_by_area_id (ospf, or->u.std.area_id))
1255: {
1256: if (IS_DEBUG_OSPF_EVENT)
1257: zlog_debug ("ospf_abr_process_router_rt(): area %s no longer exists",
1258: inet_ntoa (or->u.std.area_id));
1259: continue;
1260: }
1261:
1262:
1263: if (!CHECK_FLAG (or->u.std.flags, ROUTER_LSA_EXTERNAL))
1264: {
1265: if (IS_DEBUG_OSPF_EVENT)
1266: zlog_debug ("ospf_abr_process_router_rt(): "
1267: "This is not an ASBR, skipping");
1268: continue;
1269: }
1270:
1271: if (!flag)
1272: {
1273: best = ospf_find_asbr_route (ospf, rt,
1274: (struct prefix_ipv4 *) &rn->p);
1275: flag = 1;
1276: }
1277:
1278: if (best == NULL)
1279: continue;
1280:
1281: if (or != best)
1282: {
1283: if (IS_DEBUG_OSPF_EVENT)
1284: zlog_debug ("ospf_abr_process_router_rt(): "
1285: "This route is not the best among possible, skipping");
1286: continue;
1287: }
1288:
1289: if (or->path_type == OSPF_PATH_INTER_AREA &&
1290: !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
1291: {
1292: if (IS_DEBUG_OSPF_EVENT)
1293: zlog_debug ("ospf_abr_process_router_rt(): "
1294: "This route is not a backbone one, skipping");
1295: continue;
1296: }
1297:
1298: if (or->cost >= OSPF_LS_INFINITY)
1299: {
1300: if (IS_DEBUG_OSPF_EVENT)
1301: zlog_debug ("ospf_abr_process_router_rt(): "
1302: "This route has LS_INFINITY metric, skipping");
1303: continue;
1304: }
1305:
1306: if (ospf->abr_type == OSPF_ABR_CISCO
1307: || ospf->abr_type == OSPF_ABR_IBM)
1308: if (!ospf_act_bb_connection (ospf)
1309: && or->path_type != OSPF_PATH_INTRA_AREA)
1310: {
1311: if (IS_DEBUG_OSPF_EVENT)
1312: zlog_debug("ospf_abr_process_network_rt(): ALT ABR: "
1313: "No BB connection, skip not intra-area routes");
1314: continue;
1315: }
1316:
1317: ospf_abr_announce_rtr (ospf, (struct prefix_ipv4 *) &rn->p, or);
1318:
1319: }
1320:
1321: }
1322:
1323: if (IS_DEBUG_OSPF_EVENT)
1324: zlog_debug ("ospf_abr_process_router_rt(): Stop");
1325: }
1326:
1327: static void
1328: ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */
1329: {
1330: struct ospf_lsa *lsa;
1331: struct route_node *rn;
1332:
1333: if (IS_DEBUG_OSPF_NSSA)
1334: zlog_debug ("ospf_abr_unapprove_translates(): Start");
1335:
1336: /* NSSA Translator is not checked, because it may have gone away,
1337: and we would want to flush any residuals anyway */
1338:
1339: LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
1340: if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1341: {
1342: UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1343: if (IS_DEBUG_OSPF_NSSA)
1344: zlog_debug ("ospf_abr_unapprove_translates(): "
1345: "approved unset on link id %s",
1346: inet_ntoa (lsa->data->id));
1347: }
1348:
1349: if (IS_DEBUG_OSPF_NSSA)
1350: zlog_debug ("ospf_abr_unapprove_translates(): Stop");
1351: }
1352:
1353: static void
1354: ospf_abr_unapprove_summaries (struct ospf *ospf)
1355: {
1356: struct listnode *node;
1357: struct ospf_area *area;
1358: struct route_node *rn;
1359: struct ospf_lsa *lsa;
1360:
1361: if (IS_DEBUG_OSPF_EVENT)
1362: zlog_debug ("ospf_abr_unapprove_summaries(): Start");
1363:
1364: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1365: {
1366: if (IS_DEBUG_OSPF_EVENT)
1367: zlog_debug ("ospf_abr_unapprove_summaries(): "
1368: "considering area %s",
1369: inet_ntoa (area->area_id));
1370: LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
1371: if (ospf_lsa_is_self_originated (ospf, lsa))
1372: {
1373: if (IS_DEBUG_OSPF_EVENT)
1374: zlog_debug ("ospf_abr_unapprove_summaries(): "
1375: "approved unset on summary link id %s",
1376: inet_ntoa (lsa->data->id));
1377: UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1378: }
1379:
1380: LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
1381: if (ospf_lsa_is_self_originated (ospf, lsa))
1382: {
1383: if (IS_DEBUG_OSPF_EVENT)
1384: zlog_debug ("ospf_abr_unapprove_summaries(): "
1385: "approved unset on asbr-summary link id %s",
1386: inet_ntoa (lsa->data->id));
1387: UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
1388: }
1389: }
1390:
1391: if (IS_DEBUG_OSPF_EVENT)
1392: zlog_debug ("ospf_abr_unapprove_summaries(): Stop");
1393: }
1394:
1395: static void
1396: ospf_abr_prepare_aggregates (struct ospf *ospf)
1397: {
1398: struct listnode *node;
1399: struct route_node *rn;
1400: struct ospf_area_range *range;
1401: struct ospf_area *area;
1402:
1403: if (IS_DEBUG_OSPF_EVENT)
1404: zlog_debug ("ospf_abr_prepare_aggregates(): Start");
1405:
1406: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1407: {
1408: for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1409: if ((range = rn->info) != NULL)
1410: {
1411: range->cost = 0;
1412: range->specifics = 0;
1413: }
1414: }
1415:
1416: if (IS_DEBUG_OSPF_EVENT)
1417: zlog_debug ("ospf_abr_prepare_aggregates(): Stop");
1418: }
1419:
1420: static void
1421: ospf_abr_announce_aggregates (struct ospf *ospf)
1422: {
1423: struct ospf_area *area, *ar;
1424: struct ospf_area_range *range;
1425: struct route_node *rn;
1426: struct prefix p;
1427: struct listnode *node, *n;
1428:
1429: if (IS_DEBUG_OSPF_EVENT)
1430: zlog_debug ("ospf_abr_announce_aggregates(): Start");
1431:
1432: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1433: {
1434: if (IS_DEBUG_OSPF_EVENT)
1435: zlog_debug ("ospf_abr_announce_aggregates(): looking at area %s",
1436: inet_ntoa (area->area_id));
1437:
1438: for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1439: if ((range = rn->info))
1440: {
1441: if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1442: {
1443: if (IS_DEBUG_OSPF_EVENT)
1444: zlog_debug ("ospf_abr_announce_aggregates():"
1445: " discarding suppress-ranges");
1446: continue;
1447: }
1448:
1449: p.family = AF_INET;
1450: p.u.prefix4 = range->addr;
1451: p.prefixlen = range->masklen;
1452:
1453: if (IS_DEBUG_OSPF_EVENT)
1454: zlog_debug ("ospf_abr_announce_aggregates():"
1455: " this is range: %s/%d",
1456: inet_ntoa (p.u.prefix4), p.prefixlen);
1457:
1458: if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
1459: {
1460: p.family = AF_INET;
1461: p.u.prefix4 = range->subst_addr;
1462: p.prefixlen = range->subst_masklen;
1463: }
1464:
1465: if (range->specifics)
1466: {
1467: if (IS_DEBUG_OSPF_EVENT)
1468: zlog_debug ("ospf_abr_announce_aggregates(): active range");
1469:
1470: for (ALL_LIST_ELEMENTS_RO (ospf->areas, n, ar))
1471: {
1472: if (ar == area)
1473: continue;
1474:
1475: /* We do not check nexthops here, because
1476: intra-area routes can be associated with
1477: one area only */
1478:
1479: /* backbone routes are not summarized
1480: when announced into transit areas */
1481:
1482: if (ospf_area_is_transit (ar) &&
1483: OSPF_IS_AREA_BACKBONE (area))
1484: {
1485: if (IS_DEBUG_OSPF_EVENT)
1486: zlog_debug ("ospf_abr_announce_aggregates(): Skipping "
1487: "announcement of BB aggregate into"
1488: " a transit area");
1489: continue;
1490: }
1491: ospf_abr_announce_network_to_area ((struct prefix_ipv4 *)&p, range->cost, ar);
1492: }
1493: }
1494: }
1495: }
1496:
1497: if (IS_DEBUG_OSPF_EVENT)
1498: zlog_debug ("ospf_abr_announce_aggregates(): Stop");
1499: }
1500:
1501: static void
1502: ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */
1503: {
1504: struct listnode *node; /*, n; */
1505: struct ospf_area *area; /*, *ar; */
1506: struct route_node *rn;
1507: struct ospf_area_range *range;
1508: struct prefix_ipv4 p;
1509:
1510: if (IS_DEBUG_OSPF_NSSA)
1511: zlog_debug ("ospf_abr_send_nssa_aggregates(): Start");
1512:
1513: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1514: {
1515: if (! area->NSSATranslatorState)
1516: continue;
1517:
1518: if (IS_DEBUG_OSPF_NSSA)
1519: zlog_debug ("ospf_abr_send_nssa_aggregates(): looking at area %s",
1520: inet_ntoa (area->area_id));
1521:
1522: for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1523: {
1524: if (rn->info == NULL)
1525: continue;
1526:
1527: range = rn->info;
1528:
1529: if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1530: {
1531: if (IS_DEBUG_OSPF_NSSA)
1532: zlog_debug ("ospf_abr_send_nssa_aggregates():"
1533: " discarding suppress-ranges");
1534: continue;
1535: }
1536:
1537: p.family = AF_INET;
1538: p.prefix = range->addr;
1539: p.prefixlen = range->masklen;
1540:
1541: if (IS_DEBUG_OSPF_NSSA)
1542: zlog_debug ("ospf_abr_send_nssa_aggregates():"
1543: " this is range: %s/%d",
1544: inet_ntoa (p.prefix), p.prefixlen);
1545:
1546: if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
1547: {
1548: p.family = AF_INET;
1549: p.prefix = range->subst_addr;
1550: p.prefixlen = range->subst_masklen;
1551: }
1552:
1553: if (range->specifics)
1554: {
1555: if (IS_DEBUG_OSPF_NSSA)
1556: zlog_debug ("ospf_abr_send_nssa_aggregates(): active range");
1557:
1558: /* Fetch LSA-Type-7 from aggregate prefix, and then
1559: * translate, Install (as Type-5), Approve, and Flood
1560: */
1561: ospf_abr_translate_nssa_range (&p, range->cost);
1562: }
1563: } /* all area ranges*/
1564: } /* all areas */
1565:
1566: if (IS_DEBUG_OSPF_NSSA)
1567: zlog_debug ("ospf_abr_send_nssa_aggregates(): Stop");
1568: }
1569:
1570: static void
1571: ospf_abr_announce_stub_defaults (struct ospf *ospf)
1572: {
1573: struct listnode *node;
1574: struct ospf_area *area;
1575: struct prefix_ipv4 p;
1576:
1577: if (! IS_OSPF_ABR (ospf))
1578: return;
1579:
1580: if (IS_DEBUG_OSPF_EVENT)
1581: zlog_debug ("ospf_abr_announce_stub_defaults(): Start");
1582:
1583: p.family = AF_INET;
1584: p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
1585: p.prefixlen = 0;
1586:
1587: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1588: {
1589: if (IS_DEBUG_OSPF_EVENT)
1590: zlog_debug ("ospf_abr_announce_stub_defaults(): looking at area %s",
1591: inet_ntoa (area->area_id));
1592:
1593: if ( (area->external_routing != OSPF_AREA_STUB)
1594: && (area->external_routing != OSPF_AREA_NSSA)
1595: )
1596: continue;
1597:
1598: if (OSPF_IS_AREA_BACKBONE (area))
1599: continue; /* Sanity Check */
1600:
1601: if (IS_DEBUG_OSPF_EVENT)
1602: zlog_debug ("ospf_abr_announce_stub_defaults(): "
1603: "announcing 0.0.0.0/0 to area %s",
1604: inet_ntoa (area->area_id));
1605: ospf_abr_announce_network_to_area (&p, area->default_cost, area);
1606: }
1607:
1608: if (IS_DEBUG_OSPF_EVENT)
1609: zlog_debug ("ospf_abr_announce_stub_defaults(): Stop");
1610: }
1611:
1612: static int
1613: ospf_abr_remove_unapproved_translates_apply (struct ospf *ospf,
1614: struct ospf_lsa *lsa)
1615: {
1616: if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)
1617: && ! CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1618: {
1619: zlog_info ("ospf_abr_remove_unapproved_translates(): "
1620: "removing unapproved translates, ID: %s",
1621: inet_ntoa (lsa->data->id));
1622:
1623: /* FLUSH THROUGHOUT AS */
1624: ospf_lsa_flush_as (ospf, lsa);
1625:
1626: /* DISCARD from LSDB */
1627: }
1628: return 0;
1629: }
1630:
1631: static void
1632: ospf_abr_remove_unapproved_translates (struct ospf *ospf)
1633: {
1634: struct route_node *rn;
1635: struct ospf_lsa *lsa;
1636:
1637: /* All AREA PROCESS should have APPROVED necessary LSAs */
1638: /* Remove any left over and not APPROVED */
1639: if (IS_DEBUG_OSPF_NSSA)
1640: zlog_debug ("ospf_abr_remove_unapproved_translates(): Start");
1641:
1642: LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
1643: ospf_abr_remove_unapproved_translates_apply (ospf, lsa);
1644:
1645: if (IS_DEBUG_OSPF_NSSA)
1646: zlog_debug ("ospf_abr_remove_unapproved_translates(): Stop");
1647: }
1648:
1649: static void
1650: ospf_abr_remove_unapproved_summaries (struct ospf *ospf)
1651: {
1652: struct listnode *node;
1653: struct ospf_area *area;
1654: struct route_node *rn;
1655: struct ospf_lsa *lsa;
1656:
1657: if (IS_DEBUG_OSPF_EVENT)
1658: zlog_debug ("ospf_abr_remove_unapproved_summaries(): Start");
1659:
1660: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1661: {
1662: if (IS_DEBUG_OSPF_EVENT)
1663: zlog_debug ("ospf_abr_remove_unapproved_summaries(): "
1664: "looking at area %s", inet_ntoa (area->area_id));
1665:
1666: LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
1667: if (ospf_lsa_is_self_originated (ospf, lsa))
1668: if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1669: ospf_lsa_flush_area (lsa, area);
1670:
1671: LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
1672: if (ospf_lsa_is_self_originated (ospf, lsa))
1673: if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
1674: ospf_lsa_flush_area (lsa, area);
1675: }
1676:
1677: if (IS_DEBUG_OSPF_EVENT)
1678: zlog_debug ("ospf_abr_remove_unapproved_summaries(): Stop");
1679: }
1680:
1681: static void
1682: ospf_abr_manage_discard_routes (struct ospf *ospf)
1683: {
1684: struct listnode *node, *nnode;
1685: struct route_node *rn;
1686: struct ospf_area *area;
1687: struct ospf_area_range *range;
1688:
1689: for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
1690: for (rn = route_top (area->ranges); rn; rn = route_next (rn))
1691: if ((range = rn->info) != NULL)
1692: if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
1693: {
1694: if (range->specifics)
1695: ospf_add_discard_route (ospf->new_table, area,
1696: (struct prefix_ipv4 *) &rn->p);
1697: else
1698: ospf_delete_discard_route ((struct prefix_ipv4 *) &rn->p);
1699: }
1700: }
1701:
1702: /* This is the function taking care about ABR NSSA, i.e. NSSA
1703: Translator, -LSA aggregation and flooding. For all NSSAs
1704:
1705: Any SELF-AS-LSA is in the Type-5 LSDB and Type-7 LSDB. These LSA's
1706: are refreshed from the Type-5 LSDB, installed into the Type-7 LSDB
1707: with the P-bit set.
1708:
1709: Any received Type-5s are legal for an ABR, else illegal for IR.
1710: Received Type-7s are installed, by area, with incoming P-bit. They
1711: are flooded; if the Elected NSSA Translator, then P-bit off.
1712:
1713: Additionally, this ABR will place "translated type-7's" into the
1714: Type-5 LSDB in order to keep track of APPROVAL or not.
1715:
1716: It will scan through every area, looking for Type-7 LSAs with P-Bit
1717: SET. The Type-7's are either AS-FLOODED & 5-INSTALLED or
1718: AGGREGATED. Later, the AGGREGATED LSAs are AS-FLOODED &
1719: 5-INSTALLED.
1720:
1721: 5-INSTALLED is into the Type-5 LSDB; Any UNAPPROVED Type-5 LSAs
1722: left over are FLUSHED and DISCARDED.
1723:
1724: For External Calculations, any NSSA areas use the Type-7 AREA-LSDB,
1725: any ABR-non-NSSA areas use the Type-5 GLOBAL-LSDB. */
1726:
1727: static void
1728: ospf_abr_nssa_task (struct ospf *ospf) /* called only if any_nssa */
1729: {
1730: if (IS_DEBUG_OSPF_NSSA)
1731: zlog_debug ("Check for NSSA-ABR Tasks():");
1732:
1733: if (! IS_OSPF_ABR (ospf))
1734: return;
1735:
1736: if (! ospf->anyNSSA)
1737: return;
1738:
1739: /* Each area must confirm TranslatorRole */
1740: if (IS_DEBUG_OSPF_NSSA)
1741: zlog_debug ("ospf_abr_nssa_task(): Start");
1742:
1743: /* For all Global Entries flagged "local-translate", unset APPROVED */
1744: if (IS_DEBUG_OSPF_NSSA)
1745: zlog_debug ("ospf_abr_nssa_task(): unapprove translates");
1746:
1747: ospf_abr_unapprove_translates (ospf);
1748:
1749: /* RESET all Ranges in every Area, same as summaries */
1750: if (IS_DEBUG_OSPF_NSSA)
1751: zlog_debug ("ospf_abr_nssa_task(): NSSA initialize aggregates");
1752: ospf_abr_prepare_aggregates (ospf); /*TURNED OFF just for now */
1753:
1754: /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or
1755: * Aggregate as Type-7
1756: * Install or Approve in Type-5 Global LSDB
1757: */
1758: if (IS_DEBUG_OSPF_NSSA)
1759: zlog_debug ("ospf_abr_nssa_task(): process translates");
1760: ospf_abr_process_nssa_translates (ospf);
1761:
1762: /* Translate/Send any "ranged" aggregates, and also 5-Install and
1763: * Approve
1764: * Scan Type-7's for aggregates, translate to Type-5's,
1765: * Install/Flood/Approve
1766: */
1767: if (IS_DEBUG_OSPF_NSSA)
1768: zlog_debug("ospf_abr_nssa_task(): send NSSA aggregates");
1769: ospf_abr_send_nssa_aggregates (ospf); /*TURNED OFF FOR NOW */
1770:
1771: /* Send any NSSA defaults as Type-5
1772: *if (IS_DEBUG_OSPF_NSSA)
1773: * zlog_debug ("ospf_abr_nssa_task(): announce nssa defaults");
1774: *ospf_abr_announce_nssa_defaults (ospf);
1775: * havnt a clue what above is supposed to do.
1776: */
1777:
1778: /* Flush any unapproved previous translates from Global Data Base */
1779: if (IS_DEBUG_OSPF_NSSA)
1780: zlog_debug ("ospf_abr_nssa_task(): remove unapproved translates");
1781: ospf_abr_remove_unapproved_translates (ospf);
1782:
1783: ospf_abr_manage_discard_routes (ospf); /* same as normal...discard */
1784:
1785: if (IS_DEBUG_OSPF_NSSA)
1786: zlog_debug ("ospf_abr_nssa_task(): Stop");
1787: }
1788:
1789: /* This is the function taking care about ABR stuff, i.e.
1790: summary-LSA origination and flooding. */
1791: void
1792: ospf_abr_task (struct ospf *ospf)
1793: {
1794: if (IS_DEBUG_OSPF_EVENT)
1795: zlog_debug ("ospf_abr_task(): Start");
1796:
1797: if (ospf->new_table == NULL || ospf->new_rtrs == NULL)
1798: {
1799: if (IS_DEBUG_OSPF_EVENT)
1800: zlog_debug ("ospf_abr_task(): Routing tables are not yet ready");
1801: return;
1802: }
1803:
1804: if (IS_DEBUG_OSPF_EVENT)
1805: zlog_debug ("ospf_abr_task(): unapprove summaries");
1806: ospf_abr_unapprove_summaries (ospf);
1807:
1808: if (IS_DEBUG_OSPF_EVENT)
1809: zlog_debug ("ospf_abr_task(): prepare aggregates");
1810: ospf_abr_prepare_aggregates (ospf);
1811:
1812: if (IS_OSPF_ABR (ospf))
1813: {
1814: if (IS_DEBUG_OSPF_EVENT)
1815: zlog_debug ("ospf_abr_task(): process network RT");
1816: ospf_abr_process_network_rt (ospf, ospf->new_table);
1817:
1818: if (IS_DEBUG_OSPF_EVENT)
1819: zlog_debug ("ospf_abr_task(): process router RT");
1820: ospf_abr_process_router_rt (ospf, ospf->new_rtrs);
1821:
1822: if (IS_DEBUG_OSPF_EVENT)
1823: zlog_debug ("ospf_abr_task(): announce aggregates");
1824: ospf_abr_announce_aggregates (ospf);
1825:
1826: if (IS_DEBUG_OSPF_EVENT)
1827: zlog_debug ("ospf_abr_task(): announce stub defaults");
1828: ospf_abr_announce_stub_defaults (ospf);
1829: }
1830:
1831: if (IS_DEBUG_OSPF_EVENT)
1832: zlog_debug ("ospf_abr_task(): remove unapproved summaries");
1833: ospf_abr_remove_unapproved_summaries (ospf);
1834:
1835: ospf_abr_manage_discard_routes (ospf);
1836:
1837: if (IS_DEBUG_OSPF_EVENT)
1838: zlog_debug ("ospf_abr_task(): Stop");
1839: }
1840:
1841: static int
1842: ospf_abr_task_timer (struct thread *thread)
1843: {
1844: struct ospf *ospf = THREAD_ARG (thread);
1845:
1846: ospf->t_abr_task = 0;
1847:
1848: if (IS_DEBUG_OSPF_EVENT)
1849: zlog_debug ("Running ABR task on timer");
1850:
1851: ospf_check_abr_status (ospf);
1852: ospf_abr_nssa_check_status (ospf);
1853:
1854: ospf_abr_task (ospf);
1855: ospf_abr_nssa_task (ospf); /* if nssa-abr, then scan Type-7 LSDB */
1856:
1857: return 0;
1858: }
1859:
1860: void
1861: ospf_schedule_abr_task (struct ospf *ospf)
1862: {
1863: if (IS_DEBUG_OSPF_EVENT)
1864: zlog_debug ("Scheduling ABR task");
1865:
1866: if (ospf->t_abr_task == NULL)
1867: ospf->t_abr_task = thread_add_timer (master, ospf_abr_task_timer,
1868: ospf, OSPF_ABR_TASK_DELAY);
1869: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>