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