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