From d4a53d583c56462864b2fce08b1cf94493c041ab Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 12 Jul 2003 21:30:57 +0000 Subject: 2003-07-12 Paul Jakma * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks. --- ospfd/ospf_abr.c | 324 +++++++++++++++++++++++++++------------------- ospfd/ospf_asbr.h | 25 ++-- ospfd/ospf_dump.c | 5 +- ospfd/ospf_flood.c | 10 +- ospfd/ospf_lsa.c | 373 ++++++++++++++++++++++++++++++++++++++++++++++------- ospfd/ospf_lsa.h | 12 +- ospfd/ospf_te.c | 18 +-- ospfd/ospfd.c | 2 +- ospfd/ospfd.h | 13 +- 9 files changed, 568 insertions(+), 214 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 8991bd71..92282514 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -50,7 +50,6 @@ #include "ospfd/ospf_ase.h" #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_dump.h" - struct ospf_area_range * ospf_area_range_new (struct prefix_ipv4 *p) @@ -123,8 +122,9 @@ ospf_area_range_lookup (struct ospf_area *area, struct prefix_ipv4 *p) } struct ospf_area_range * -ospf_area_range_lookup_next (struct ospf_area *area, struct in_addr *range_net, - int first) +ospf_area_range_lookup_next (struct ospf_area *area, + struct in_addr *range_net, + int first) { struct route_node *rn; struct prefix_ipv4 p; @@ -375,7 +375,7 @@ ospf_abr_nssa_am_elected (struct ospf_area *area) if (IS_ROUTER_LSA_NT (rlsa)) { if (IS_DEBUG_OSPF_NSSA) - zlog_info ("ospf_abr_nssa_am_elected: ", + zlog_info ("ospf_abr_nssa_am_elected: " "router %s asserts Nt", inet_ntoa (lsa->data->id) ); return 0; @@ -426,7 +426,7 @@ ospf_abr_nssa_check_status (struct ospf *ospf) if (IS_DEBUG_OSPF (nssa, NSSA)) zlog_info ("ospf_abr_nssa_check_status: " "not ABR"); - area->NSSATranslatorState = OSPF_NSSA_STATE_DISABLED; + area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; continue; } @@ -438,7 +438,7 @@ ospf_abr_nssa_check_status (struct ospf *ospf) if (IS_DEBUG_OSPF (nssa, NSSA)) zlog_info ("ospf_abr_nssa_check_status: " "never translate"); - area->NSSATranslatorState = OSPF_NSSA_STATE_DISABLED; + area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; continue; case OSPF_NSSA_ROLE_ALWAYS: @@ -449,21 +449,21 @@ ospf_abr_nssa_check_status (struct ospf *ospf) if (IS_DEBUG_OSPF (nssa, NSSA)) zlog_info ("ospf_abr_nssa_check_status: " "translate always"); - area->NSSATranslatorState = OSPF_NSSA_STATE_ENABLED; + area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED; continue; case OSPF_NSSA_ROLE_CANDIDATE: /* We are a candidate for Translation */ if (ospf_abr_nssa_am_elected (area) > 0 ) { - area->NSSATranslatorState = OSPF_NSSA_STATE_ENABLED; + area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED; if (IS_DEBUG_OSPF (nssa, NSSA)) zlog_info ("ospf_abr_nssa_check_status: " "elected translator"); } else { - area->NSSATranslatorState = OSPF_NSSA_STATE_DISABLED; + area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; if (IS_DEBUG_OSPF (nssa, NSSA)) zlog_info ("ospf_abr_nssa_check_status: " "not elected"); @@ -619,52 +619,88 @@ int ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa) { /* Incoming Type-7 or later aggregated Type-7 + * + * LSA is skipped if P-bit is off. + * LSA is aggregated if within range. + * + * The Type-7 is translated, Installed/Approved as a Type-5 into + * global LSDB, then Flooded through AS + * + * Later, any Unapproved Translated Type-5's are flushed/discarded + */ - LSA is skipped if P-bit is off. - LSA is aggregated if within range. - - The Type-7 is translated, Installed/Approved as a Type-5 into - global LSDB, then Flooded through AS - - Later, any Unapproved Translated Type-5's are flushed/discarded */ - - struct ospf_lsa *dup; + struct ospf_lsa *old = NULL, + *new = NULL; + struct as_external_lsa *ext7; + struct prefix_ipv4 p; if (! CHECK_FLAG (lsa->data->options, OSPF_OPTION_NP)) { if (IS_DEBUG_OSPF_NSSA) - zlog_info ("ospf_abr_nssa(): P-bit off, NO Translation"); - return 0; + zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation", + inet_ntoa (lsa->data->id)); + return 1; } - + if (IS_DEBUG_OSPF_NSSA) - zlog_info ("ospf_abr_nssa(): TRANSLATING 7 to 5"); + zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5", + inet_ntoa (lsa->data->id)); - /* No more P-bit. */ - /* UNSET_FLAG (lsa->data->options, OSPF_OPTION_NP); */ + ext7 = (struct as_external_lsa *)(lsa->data); + p.prefix = lsa->data->id; + p.prefixlen = ip_masklen (ext7->mask); + + if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION) + { + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, " + "Forward address is 0, NO Translation", + inet_ntoa (lsa->data->id)); + return 1; + } + + /* try find existing AS-External LSA for this prefix */ + + old = ospf_external_info_find_lsa (area->ospf, &p); + + if (old) + { + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("ospf_abr_translate_nssa(): " + "found old translated LSA Id %s, refreshing", + inet_ntoa (old->data->id)); + + /* refresh */ + new = ospf_translated_nssa_refresh (area->ospf, lsa, old); + if (!new) + { + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("ospf_abr_translate_nssa(): " + "could not refresh translated LSA Id %s", + inet_ntoa (old->data->id)); + } + } + else + { + /* no existing external route for this LSA Id + * originate translated LSA + */ + + if ((new = ospf_translated_nssa_originate (area->ospf, lsa)) + == NULL) + { + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("ospf_abr_translate_nssa(): Could not translate " + "Type-7 for %s to Type-5", + inet_ntoa (lsa->data->id)); + return 1; + } + } /* Area where Aggregate testing will be inserted, just like summary advertisements */ /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */ - /* Follow thru here means no aggregation */ - dup = ospf_lsa_dup (lsa); /* keep LSDB intact, lock = 1 */ - - SET_FLAG (dup->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */ - SET_FLAG (dup->flags, OSPF_LSA_APPROVED); /* So, do not remove it */ - - dup->data->type = OSPF_AS_EXTERNAL_LSA; /* make Type-5 */ - - ospf_lsa_checksum (dup->data); - - ospf_lsa_install (area->ospf, NULL, dup); /* Install this Type-5 into LSDB, Lock = 2. */ - - ospf_flood_through_as (area->ospf, NULL, dup); /* flood non-NSSA/STUB areas */ - - /* This translated Type-5 will go to all non-NSSA areas connected to - this ABR; The Type-5 could come from any of the NSSA's connected - to this ABR. */ - return 0; } @@ -686,51 +722,52 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost, if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_announce_network_to_area(): Start"); - old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA, p, - area->ospf->router_id); + old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA, + (struct prefix_ipv4 *) p, + area->ospf->router_id); if (old) { if (IS_DEBUG_OSPF_EVENT) - zlog_info ("ospf_abr_announce_network_to_area(): old summary found"); - sl = (struct summary_lsa *) old->data; + zlog_info ("ospf_abr_announce_network_to_area(): old summary found"); - if (IS_DEBUG_OSPF_EVENT) - zlog_info ("ospf_abr_announce_network_to_area(): " - "old metric: %d, new metric: %d", - GET_METRIC (sl->metric), cost); - } + sl = (struct summary_lsa *) old->data; - if (old && (GET_METRIC (sl->metric) == cost)) - { if (IS_DEBUG_OSPF_EVENT) - zlog_info ("ospf_abr_announce_network_to_area(): " - "old summary approved"); - SET_FLAG (old->flags, OSPF_LSA_APPROVED); + zlog_info ("ospf_abr_announce_network_to_area(): " + "old metric: %d, new metric: %d", + GET_METRIC (sl->metric), cost); + + if (GET_METRIC (sl->metric) == cost) + { + /* unchanged. simply reapprove it */ + if (IS_DEBUG_OSPF_EVENT) + zlog_info ("ospf_abr_announce_network_to_area(): " + "old summary approved"); + SET_FLAG (old->flags, OSPF_LSA_APPROVED); + } + else + { + /* LSA is changed, refresh it */ + if (IS_DEBUG_OSPF_EVENT) + zlog_info ("ospf_abr_announce_network_to_area(): " + "refreshing summary"); + set_metric (old, cost); + lsa = ospf_summary_lsa_refresh (area->ospf, old); + /* This will flood through area. */ + } } else { if (IS_DEBUG_OSPF_EVENT) - zlog_info ("ospf_abr_announce_network_to_area(): " - "creating new summary"); - if (old) - { - - set_metric (old, cost); - lsa = ospf_summary_lsa_refresh (area->ospf, old); - /* This will flood through area. */ - } - else - { - lsa = ospf_summary_lsa_originate (p, cost, area); - /* This will flood through area. */ - } + zlog_info ("ospf_abr_announce_network_to_area(): " + "creating new summary"); + lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, cost, area); + /* This will flood through area. */ - SET_FLAG (lsa->flags, OSPF_LSA_APPROVED); if (IS_DEBUG_OSPF_EVENT) - zlog_info ("ospf_abr_announce_network_to_area(): " - "flooding new version of summary"); - + zlog_info ("ospf_abr_announce_network_to_area(): " + "flooding new version of summary"); } if (IS_DEBUG_OSPF_EVENT) @@ -757,7 +794,7 @@ ospf_abr_nexthops_belong_to_area (struct ospf_route *or, } int -ospf_abr_should_accept (struct prefix *p, struct ospf_area *area) +ospf_abr_should_accept (struct prefix_ipv4 *p, struct ospf_area *area) { if (IMPORT_NAME (area)) { @@ -774,7 +811,7 @@ ospf_abr_should_accept (struct prefix *p, struct ospf_area *area) int ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or, - struct prefix *p) + struct prefix_ipv4 *p) { if (PREFIX_NAME_IN (area)) { @@ -790,7 +827,7 @@ ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or, int ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or, - struct prefix *p) + struct prefix_ipv4 *p) { if (PREFIX_NAME_OUT (area)) { @@ -806,16 +843,14 @@ ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or, void ospf_abr_announce_network (struct ospf *ospf, - struct route_node *n, struct ospf_route *or) + struct prefix_ipv4 *p, struct ospf_route *or) { struct ospf_area_range *range; struct ospf_area *area, *or_area; - struct prefix_ipv4 *p; listnode node; if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_announce_network(): Start"); - p = (struct prefix_ipv4 *) &n->p; or_area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id); assert (or_area); @@ -834,7 +869,7 @@ ospf_abr_announce_network (struct ospf *ospf, if (ospf_abr_nexthops_belong_to_area (or, area)) continue; - if (!ospf_abr_should_accept (&n->p, area)) + if (!ospf_abr_should_accept (p, area)) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_announce_network(): " @@ -843,7 +878,7 @@ ospf_abr_announce_network (struct ospf *ospf, continue; } - if (!ospf_abr_plist_in_check (area, or, &n->p)) + if (!ospf_abr_plist_in_check (area, or, p)) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_announce_network(): " @@ -873,23 +908,23 @@ ospf_abr_announce_network (struct ospf *ospf, } if (or->path_type == OSPF_PATH_INTRA_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_info ("ospf_abr_announce_network(): " - "this is intra-area route to %s/%d", - inet_ntoa (p->prefix), p->prefixlen); - if ((range = ospf_area_range_match (or_area, p)) && - !ospf_area_is_transit (area)) - ospf_abr_update_aggregate (range, or); - else - ospf_abr_announce_network_to_area (p, or->cost, area); - } + { + if (IS_DEBUG_OSPF_EVENT) + zlog_info ("ospf_abr_announce_network(): " + "this is intra-area route to %s/%d", + inet_ntoa (p->prefix), p->prefixlen); + if ((range = ospf_area_range_match (or_area, p)) + && !ospf_area_is_transit (area)) + ospf_abr_update_aggregate (range, or); + else + ospf_abr_announce_network_to_area (p, or->cost, area); + } } } int ospf_abr_should_announce (struct ospf *ospf, - struct prefix *p, struct ospf_route *or) + struct prefix_ipv4 *p, struct ospf_route *or) { struct ospf_area *area; @@ -933,17 +968,17 @@ ospf_abr_process_nssa_translates (struct ospf *ospf) area = getdata (node); if (! area->NSSATranslatorState) - continue; /* skip if not translator */ + continue; /* skip if not translator */ if (area->external_routing != OSPF_AREA_NSSA) - continue; /* skip if not Nssa Area */ + continue; /* skip if not Nssa Area */ if (IS_DEBUG_OSPF_NSSA) - zlog_info ("ospf_abr_process_nssa_translates(): " - "looking at area %s", inet_ntoa (area->area_id)); + zlog_info ("ospf_abr_process_nssa_translates(): " + "looking at area %s", inet_ntoa (area->area_id)); LSDB_LOOP (NSSA_LSDB (area), rn, lsa) - ospf_abr_translate_nssa (area, lsa); + ospf_abr_translate_nssa (area, lsa); } if (IS_DEBUG_OSPF_NSSA) @@ -1004,7 +1039,7 @@ ospf_abr_process_network_rt (struct ospf *ospf, } if (or->path_type == OSPF_PATH_INTRA_AREA && - !ospf_abr_should_announce (ospf, &rn->p, or)) + !ospf_abr_should_announce (ospf, (struct prefix_ipv4 *) &rn->p, or)) { if (IS_DEBUG_OSPF_EVENT) zlog_info("ospf_abr_process_network_rt(): denied by export-list"); @@ -1012,7 +1047,7 @@ ospf_abr_process_network_rt (struct ospf *ospf, } if (or->path_type == OSPF_PATH_INTRA_AREA && - !ospf_abr_plist_out_check (area, or, &rn->p)) + !ospf_abr_plist_out_check (area, or, (struct prefix_ipv4 *) &rn->p)) { if (IS_DEBUG_OSPF_EVENT) zlog_info("ospf_abr_process_network_rt(): denied by prefix-list"); @@ -1043,7 +1078,7 @@ ospf_abr_process_network_rt (struct ospf *ospf, if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_network_rt(): announcing"); - ospf_abr_announce_network (ospf, rn, or); + ospf_abr_announce_network (ospf, &rn->p, or); } if (IS_DEBUG_OSPF_EVENT) @@ -1136,7 +1171,7 @@ ospf_abr_announce_rtr (struct ospf *ospf, if (area->external_routing != OSPF_AREA_DEFAULT) { if (IS_DEBUG_OSPF_EVENT) - zlog_info ("ospf_abr_announce_network(): " + zlog_info ("ospf_abr_announce_rtr(): " "area %s doesn't support external routing", inet_ntoa(area->area_id)); continue; @@ -1283,7 +1318,13 @@ ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */ LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) - UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); + { + UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("ospf_abr_unapprove_translates(): " + "approved unset on link id %s", + inet_ntoa (lsa->data->id)); + } if (IS_DEBUG_OSPF_NSSA) zlog_info ("ospf_abr_unapprove_translates(): Stop"); @@ -1304,13 +1345,29 @@ ospf_abr_unapprove_summaries (struct ospf *ospf) for (node = listhead (ospf->areas); node; nextnode (node)) { area = getdata (node); + if (IS_DEBUG_OSPF_EVENT) + zlog_info ("ospf_abr_unapprove_summaries(): " + "considering area %s", + inet_ntoa (area->area_id)); LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) - if (ospf_lsa_is_self_originated (ospf, lsa)) - UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); + if (ospf_lsa_is_self_originated (ospf, lsa)) + { + if (IS_DEBUG_OSPF_EVENT) + zlog_info ("ospf_abr_unapprove_summaries(): " + "approved unset on summary link id %s", + inet_ntoa (lsa->data->id)); + UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); + } LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) - if (ospf_lsa_is_self_originated (ospf, lsa)) - UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); + if (ospf_lsa_is_self_originated (ospf, lsa)) + { + if (IS_DEBUG_OSPF_EVENT) + zlog_info ("ospf_abr_unapprove_summaries(): " + "approved unset on asbr-summary link id %s", + inet_ntoa (lsa->data->id)); + UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); + } } if (IS_DEBUG_OSPF_EVENT) @@ -1349,7 +1406,7 @@ ospf_abr_announce_aggregates (struct ospf *ospf) struct ospf_area *area, *ar; struct ospf_area_range *range; struct route_node *rn; - struct prefix_ipv4 p; + struct prefix p; listnode node, n; if (IS_DEBUG_OSPF_EVENT) @@ -1375,18 +1432,18 @@ ospf_abr_announce_aggregates (struct ospf *ospf) } p.family = AF_INET; - p.prefix = range->addr; + p.u.prefix4 = range->addr; p.prefixlen = range->masklen; if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_announce_aggregates():" " this is range: %s/%d", - inet_ntoa (p.prefix), p.prefixlen); + inet_ntoa (p.u.prefix4), p.prefixlen); if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) { p.family = AF_INET; - p.prefix = range->subst_addr; + p.u.prefix4 = range->subst_addr; p.prefixlen = range->subst_masklen; } @@ -1504,7 +1561,6 @@ ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */ { listnode node; struct ospf_area *area; - struct prefix_ipv4 p; if (! IS_OSPF_ABR (ospf)) return; @@ -1512,10 +1568,6 @@ ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */ if (IS_DEBUG_OSPF_NSSA) zlog_info ("ospf_abr_announce_stub_defaults(): Start"); - p.family = AF_INET; - p.prefix.s_addr = OSPF_DEFAULT_DESTINATION; - p.prefixlen = 0; - for (node = listhead (ospf->areas); node; nextnode (node)) { area = getdata (node); @@ -1536,7 +1588,7 @@ ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */ zlog_info ("ospf_abr_announce_nssa_defaults(): " "announcing 0.0.0.0/0 to this nssa"); /* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */ - ospf_abr_announce_network_to_area (&p, area->default_cost, area); + /*ospf_abr_announce_network_to_area (&p, area->default_cost, area);*/ } } } @@ -1563,22 +1615,26 @@ ospf_abr_announce_stub_defaults (struct ospf *ospf) { area = getdata (node); if (IS_DEBUG_OSPF_EVENT) - zlog_info ("ospf_abr_announce_stub_defaults(): looking at area %s", - inet_ntoa (area->area_id)); + zlog_info ("ospf_abr_announce_stub_defaults(): looking at area %s", + inet_ntoa (area->area_id)); + if ( (area->external_routing != OSPF_AREA_STUB) #ifdef HAVE_NSSA - if (area->external_routing != OSPF_AREA_STUB) -#else /* ! HAVE_NSSA */ - if (area->external_routing == OSPF_AREA_DEFAULT) + && (area->external_routing != OSPF_AREA_NSSA) #endif /* HAVE_NSSA */ - continue; + ) + continue; if (OSPF_IS_AREA_BACKBONE (area)) - continue; /* Sanity Check */ + continue; /* Sanity Check */ + + if (area->no_summary) + continue; if (IS_DEBUG_OSPF_EVENT) - zlog_info ("ospf_abr_announce_stub_defaults(): " - "announcing 0.0.0.0/0 to this area"); + zlog_info ("ospf_abr_announce_stub_defaults(): " + "announcing 0.0.0.0/0 to area %s", + inet_ntoa (area->area_id)); ospf_abr_announce_network_to_area (&p, area->default_cost, area); } @@ -1751,10 +1807,12 @@ ospf_abr_nssa_task (struct ospf *ospf) /* called only if any_nssa */ zlog_info("ospf_abr_nssa_task(): send NSSA aggregates"); ospf_abr_send_nssa_aggregates (ospf); /*TURNED OFF FOR NOW */ - /* Send any NSSA defaults as Type-5 */ - if (IS_DEBUG_OSPF_NSSA) - zlog_info ("ospf_abr_nssa_task(): announce nssa defaults"); - ospf_abr_announce_nssa_defaults (ospf); + /* Send any NSSA defaults as Type-5 + *if (IS_DEBUG_OSPF_NSSA) + * zlog_info ("ospf_abr_nssa_task(): announce nssa defaults"); + *ospf_abr_announce_nssa_defaults (ospf); + * havnt a clue what above is supposed to do. + */ /* Flush any unapproved previous translates from Global Data Base */ if (IS_DEBUG_OSPF_NSSA) @@ -1832,10 +1890,12 @@ ospf_abr_task_timer (struct thread *thread) zlog_info ("Running ABR task on timer"); ospf_check_abr_status (ospf); +#ifdef HAVE_NSSA + ospf_abr_nssa_check_status (ospf); +#endif /* HAVE_NSSA */ ospf_abr_task (ospf); #ifdef HAVE_NSSA - ospf_abr_nssa_check_status (ospf); ospf_abr_nssa_task (ospf); /* if nssa-abr, then scan Type-7 LSDB */ #endif /* HAVE_NSSA */ diff --git a/ospfd/ospf_asbr.h b/ospfd/ospf_asbr.h index f368246d..34947747 100644 --- a/ospfd/ospf_asbr.h +++ b/ospfd/ospf_asbr.h @@ -54,22 +54,27 @@ struct external_info #define OSPF_ASBR_CHECK_DELAY 30 -void ospf_external_route_remove (struct prefix_ipv4 *p); +void ospf_external_route_remove (struct ospf *, struct prefix_ipv4 *); struct external_info *ospf_external_info_new (u_char); -void ospf_reset_route_map_set_values (struct route_map_set_values *values); -int ospf_route_map_set_compare (struct route_map_set_values *values1, - struct route_map_set_values *values2); -struct external_info *ospf_external_info_add (u_char, struct prefix_ipv4, - unsigned int, struct in_addr); +void ospf_reset_route_map_set_values (struct route_map_set_values *); +int ospf_route_map_set_compare (struct route_map_set_values *, + struct route_map_set_values *); +struct external_info *ospf_external_info_add (u_char, + struct prefix_ipv4, + unsigned int, + struct in_addr); void ospf_external_info_delete (u_char, struct prefix_ipv4); -struct external_info *ospf_external_info_lookup (u_char, struct prefix_ipv4 *); - -void ospf_asbr_status_update (u_char); +struct external_info *ospf_external_info_lookup (u_char, + struct prefix_ipv4 *); +struct ospf_route *ospf_external_route_lookup (struct ospf *, + struct prefix_ipv4 *); +void ospf_asbr_status_update (struct ospf *, u_char); void ospf_redistribute_withdraw (u_char); void ospf_asbr_check (); void ospf_schedule_asbr_check (); void ospf_asbr_route_install_lsa (struct ospf_lsa *); -struct ospf_lsa *ospf_external_info_find_lsa (struct prefix_ipv4 *p); +struct ospf_lsa *ospf_external_info_find_lsa (struct ospf *, + struct prefix_ipv4 *p); #endif /* _ZEBRA_OSPF_ASBR_H */ diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index f563fb89..fe75a960 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -425,8 +425,7 @@ ospf_as_external_lsa_dump (struct stream *s, u_int16_t length) int i; al = (struct as_external_lsa *) STREAM_PNT (s); - - zlog_info (" AS-external-LSA"); + zlog_info (" %s", ospf_lsa_type_msg[al->header.type].str); zlog_info (" Network Mask %s", inet_ntoa (al->mask)); size = ntohs (al->header.length) - OSPF_LSA_HEADER_SIZE -4; @@ -563,7 +562,7 @@ ospf_packet_ls_upd_dump (struct stream *s, u_int16_t length) break; #ifdef HAVE_NSSA case OSPF_AS_NSSA_LSA: - /* XXX */ + ospf_as_external_lsa_dump (s, length); break; #endif /* HAVE_NSSA */ #ifdef HAVE_OPAQUE_LSA diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 1c8cbbf5..fc6ab137 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -185,12 +185,18 @@ ospf_process_self_originated_lsa (struct ospf *ospf, case OSPF_AS_EXTERNAL_LSA : #ifdef HAVE_NSSA case OSPF_AS_NSSA_LSA: + if ( (new->data->type == OSPF_AS_EXTERNAL_LSA) + && CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)) + { + ospf_translated_nssa_refresh (ospf, NULL, new); + return; + } #endif /* HAVE_NSSA */ ei = ospf_external_info_check (new); if (ei) - ospf_external_lsa_refresh (ospf, new, ei, LSA_REFRESH_FORCE); + ospf_external_lsa_refresh (ospf, new, ei, LSA_REFRESH_FORCE); else - ospf_lsa_flush_as (ospf, new); + ospf_lsa_flush_as (ospf, new); break; #ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_AREA_LSA: diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 915f0fa7..18ab140a 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -449,12 +449,13 @@ router_lsa_flags (struct ospf_area *area) SET_FLAG (flags, ROUTER_LSA_BORDER); #ifdef HAVE_NSSA /* If Area is NSSA and we are both ABR and unconditional translator, - * set Nt bit + * set Nt bit to inform other routers. */ - SET_FLAG (flags, ROUTER_LSA_NT); + if ( (area->external_routing == OSPF_AREA_NSSA) + && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS)) + SET_FLAG (flags, ROUTER_LSA_NT); #endif /* HAVE_NSSA */ } - return flags; } @@ -742,13 +743,12 @@ ospf_router_lsa_new (struct ospf_area *area) #ifdef HAVE_NSSA /* Set LSA common header fields. */ - lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_NSSA_GET (area), - OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id); + lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area), #else /* ! HAVE_NSSA */ /* Set LSA common header fields. */ lsa_header_set (s, LSA_OPTIONS_GET (area), - OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id); #endif /* HAVE_NSSA */ + OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id); /* Set router-LSA body fields. */ ospf_router_lsa_body_set (s, area); @@ -1626,10 +1626,17 @@ void ospf_install_flood_nssa (struct ospf *ospf, struct ospf_lsa *lsa, struct external_info *ei) { - struct ospf_lsa *new2; + struct ospf_lsa *new; struct as_external_lsa *extlsa; listnode node; + /* LSA may be a Type-5 originated via translation of a Type-7 LSA + * which originated from an NSSA area. In which case it should not be + * flooded back to NSSA areas. + */ + if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) + return; + /* NSSA Originate or Refresh (If anyNSSA) LSA is self-originated. And just installed as Type-5. @@ -1654,14 +1661,14 @@ ospf_install_flood_nssa (struct ospf *ospf, continue; /* make lsa duplicate, lock=1 */ - new2 = ospf_lsa_dup (lsa); - new2->area = area; - new2->data->type = OSPF_AS_NSSA_LSA; + new = ospf_lsa_dup (lsa); + new->area = area; + new->data->type = OSPF_AS_NSSA_LSA; /* set P-bit if not ABR */ if (! IS_OSPF_ABR (ospf)) { - SET_FLAG(new2->data->options, OSPF_OPTION_NP); + SET_FLAG(new->data->options, OSPF_OPTION_NP); /* set non-zero FWD ADDR @@ -1678,8 +1685,8 @@ ospf_install_flood_nssa (struct ospf *ospf, no type-7 LSA's with the P-bit set should originate from this router. */ - /* kevinm: not updating lsa anymore, just new2 */ - extlsa = (struct as_external_lsa *)(new2->data); + /* kevinm: not updating lsa anymore, just new */ + extlsa = (struct as_external_lsa *)(new->data); if (extlsa->e[0].fwd_addr.s_addr == 0) extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */ @@ -1688,19 +1695,252 @@ ospf_install_flood_nssa (struct ospf *ospf, { if (IS_DEBUG_OSPF_NSSA) zlog_info ("LSA[Type-7]: Could not build FWD-ADDR"); - ospf_lsa_discard(new2); + ospf_lsa_discard(new); return; } } /* Re-calculate checksum. */ - ospf_lsa_checksum (new2->data); + ospf_lsa_checksum (new->data); /* install also as Type-7 */ - ospf_lsa_install (ospf, NULL, new2); /* Remove Old, Lock New = 2 */ + ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */ /* will send each copy, lock=2+n */ - ospf_flood_through_as (ospf, NULL, new2); /* all attached NSSA's, no AS/STUBs */ + ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */ + } +} + +struct ospf_lsa * +ospf_lsa_translated_nssa_new (struct ospf *ospf, + struct ospf_lsa *type7) +{ + + struct ospf_lsa *new; + struct as_external_lsa *ext, *extnew; + struct external_info ei; + + ext = (struct as_external_lsa *)(type7->data); + + /* need external_info struct, fill in bare minimum */ + ei.p.family = AF_INET; + ei.p.prefix = type7->data->id; + ei.p.prefixlen = ip_masklen (ext->mask); + ei.type = ZEBRA_ROUTE_OSPF; + ei.nexthop = ext->header.adv_router; + ei.route_map_set.metric = -1; + ei.route_map_set.metric_type = -1; + ei.tag = 0; + + if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL) + { + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("ospf_nssa_translate_originate(): Could not originate " + "Translated Type-5 for %s", + inet_ntoa (ei.p.prefix)); + return NULL; + } + + extnew = (struct as_external_lsa *)(new->data); + + /* copy over Type-7 data to new */ + extnew->e[0].tos = ext->e[0].tos; + extnew->e[0].route_tag = ext->e[0].route_tag; + extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr; + new->data->ls_seqnum = type7->data->ls_seqnum; + + /* add translated flag, checksum and lock new lsa */ + SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */ + ospf_lsa_checksum (new->data); + new = ospf_lsa_lock (new); + + return new; +} + +/* compare type-5 to type-7 + * -1: err, 0: same, 1: different + */ +int +ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5) +{ + + struct as_external_lsa *e5 = (struct as_external_lsa *)t5, + *e7 = (struct as_external_lsa *)t7; + + + /* sanity checks */ + if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA) + && (t7->data->type == OSPF_AS_NSSA_LSA))) + return -1; + + if (t5->data->id.s_addr != t7->data->id.s_addr) + return -1; + + if (t5->data->ls_seqnum != t7->data->ls_seqnum) + return LSA_REFRESH_FORCE; + + if (e5->mask.s_addr != e7->mask.s_addr) + return LSA_REFRESH_FORCE; + + if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr) + return LSA_REFRESH_FORCE; + + if (e5->e[0].route_tag != e7->e[0].route_tag) + return LSA_REFRESH_FORCE; + + if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric)) + return LSA_REFRESH_FORCE; + + return LSA_REFRESH_IF_CHANGED; +} + +/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */ +struct ospf_lsa * +ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7) +{ + struct ospf_lsa *new; + struct as_external_lsa *extnew; + + /* we cant use ospf_external_lsa_originate() as we need to set + * the OSPF_LSA_LOCAL_XLT flag, must originate by hand + */ + + if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL) + { + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("ospf_translated_nssa_originate(): Could not translate " + "Type-7, Id %s, to Type-5", + inet_ntoa (type7->data->id)); + return NULL; + } + + extnew = (struct as_external_lsa *)new; + + if (IS_DEBUG_OSPF_NSSA) + { + zlog_info ("ospf_translated_nssa_originate(): " + "translated Type 7, installed:"); + ospf_lsa_header_dump (new->data); + zlog_info (" Network mask: %d",ip_masklen (extnew->mask)); + zlog_info (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr)); + } + + if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL) + { + if (IS_DEBUG_OSPF_NSSA); + zlog_warn ("ospf_lsa_translated_nssa_originate(): " + "Could not install LSA " + "id %s", inet_ntoa (type7->data->id)); + return NULL; + } + + ospf->lsa_originate_count++; + ospf_flood_through_as (ospf, NULL, new); + + return new; +} + +/* Refresh Translated from NSSA AS-external-LSA. */ +struct ospf_lsa * +ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7, + struct ospf_lsa *type5) +{ + struct ospf_lsa *new = NULL; + + /* Sanity checks. */ + assert (type7 || type5); + if (type7) + assert (type7->data); + if (type5) + assert (type5->data); + assert (ospf->anyNSSA); + + /* get required data according to what has been given */ + if (type7 && type5 == NULL) + { + /* find the translated Type-5 for this Type-7 */ + struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data); + struct prefix_ipv4 p = + { + .prefix = type7->data->id, + .prefixlen = ip_masklen (ext->mask), + .family = AF_INET, + }; + + type5 = ospf_external_info_find_lsa (ospf, &p); + } + else if (type5 && type7 == NULL) + { + /* find the type-7 from which supplied type-5 was translated, + * ie find first type-7 with same LSA Id. + */ + listnode ln; + struct route_node *rn; + struct ospf_lsa *lsa; + struct ospf_area *area; + + LIST_LOOP (ospf->areas, area, ln) + { + if (area->external_routing != OSPF_AREA_NSSA + && !type7) + continue; + + LSDB_LOOP (NSSA_LSDB(area), rn, lsa) + { + if (lsa->data->id.s_addr == type5->data->id.s_addr) + { + type7 = lsa; + break; + } + } + } } + + /* do we have type7? */ + if (!type7) + { + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("ospf_translated_nssa_refresh(): no Type-7 found for " + "Type-5 LSA Id %s", + inet_ntoa (type7->data->id)); + return NULL; + } + + /* do we have valid translated type5? */ + if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) ) + { + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("ospf_translated_nssa_refresh(): No translated Type-5 " + "found for Type-7 with Id %s", + inet_ntoa (type7->data->id)); + return NULL; + } + + /* Delete LSA from neighbor retransmit-list. */ + ospf_ls_retransmit_delete_nbr_as (ospf, type5); + + /* create new translated LSA */ + if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL) + { + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("ospf_translated_nssa_refresh(): Could not translate " + "Type-7 for %s to Type-5", + inet_ntoa (type7->data->id)); + return NULL; + } + + if ( !(new = ospf_lsa_install (ospf, NULL, new)) ) + { + if (IS_DEBUG_OSPF_NSSA) + zlog_info ("ospf_translated_nssa_refresh(): Could not install " + "translated LSA, Id %s", + inet_ntoa (new->data->id)); + return NULL; + } + + /* Flood LSA through area. */ + ospf_flood_through_as (ospf, NULL, new); + + return new; } #endif /* HAVE_NSSA */ @@ -1781,7 +2021,9 @@ ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei) #ifdef HAVE_NSSA /* If there is any attached NSSA, do special handling */ - if (ospf->anyNSSA) + if (ospf->anyNSSA && + /* stay away from translated LSAs! */ + !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT))) ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */ #endif /* HAVE_NSSA */ @@ -1933,10 +2175,11 @@ ospf_external_lsa_flush (struct ospf *ospf, return; } #ifdef HAVE_NSSA - /* If LSA is selforiginated and there is NSSA area, flush - * Type-7 LSA's at first. */ - - if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)) + /* If LSA is selforiginated, not a translated LSA, and there is + * NSSA area, flush Type-7 LSA's at first. + */ + if (IS_LSA_SELF(lsa) && (ospf->anyNSSA) + && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))) ospf_nssa_lsa_flush (ospf, p); #endif /* HAVE_NSSA */ @@ -2035,13 +2278,22 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa, /* Check the AS-external-LSA should be originated. */ if (!ospf_redistribute_check (ospf, ei, &changed)) { + if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) + zlog_warn ("LSA[Type%d:%s]: Could not be refreshed, " + "redist check fail", + lsa->data->type, inet_ntoa (lsa->data->id)); ospf_external_lsa_flush (ospf, ei->type, &ei->p, ei->ifindex, ei->nexthop); return; } if (!changed && !force) - return; + { + if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) + zlog_info ("LSA[Type%d:%s]: Not refreshed, not changed/forced", + lsa->data->type, inet_ntoa (lsa->data->id)); + return; + } /* Delete LSA from neighbor retransmit-list. */ ospf_ls_retransmit_delete_nbr_as (ospf, lsa); @@ -2074,18 +2326,22 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa, #ifdef HAVE_NSSA /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */ - if (ospf->anyNSSA) + if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT))) ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */ #endif /* HAVE_NSSA */ - /* Register slef-originated LSA to refresh queue. */ - ospf_refresher_register_lsa (ospf, new); + /* Register self-originated LSA to refresh queue. + * Translated LSAs should not be registered, but refreshed upon + * refresh of the Type-7 + */ + if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) ) + ospf_refresher_register_lsa (ospf, new); /* Debug logging. */ if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) { zlog_info ("LSA[Type%d:%s]: AS-external-LSA refresh", - new->data->type, inet_ntoa (new->data->id)); + new->data->type, inet_ntoa (new->data->id)); ospf_lsa_header_dump (new->data); } @@ -2115,15 +2371,15 @@ ospf_router_lsa_install (struct ospf *ospf, /* Set router-LSA refresh timer. */ OSPF_TIMER_OFF (area->t_router_lsa_self); OSPF_AREA_TIMER_ON (area->t_router_lsa_self, - ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME); + ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME); /* Set self-originated router-LSA. */ ospf_lsa_unlock (area->router_lsa_self); area->router_lsa_self = ospf_lsa_lock (new); if (IS_DEBUG_OSPF (lsa, LSA_INSTALL)) - zlog_info("LSA[Type%d]: ID %s is self-originated", - new->data->type, inet_ntoa (new->data->id)); + zlog_info("LSA[Type%d]: ID %s is self-originated", + new->data->type, inet_ntoa (new->data->id)); } return new; @@ -2245,18 +2501,31 @@ ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new, */ if (!IS_LSA_SELF (new)) - ospf_ase_incremental_update (ospf, new); + ospf_ase_incremental_update (ospf, new); } #ifdef HAVE_NSSA - /* There is no point to register selforiginate Type-7 LSA for - * refreshing. We rely on refreshing Type-5 LSA's */ - if (IS_LSA_SELF (new) && (new->data->type == OSPF_AS_NSSA_LSA)) - return new; + if (new->data->type == OSPF_AS_NSSA_LSA) + { + /* There is no point to register selforiginate Type-7 LSA for + * refreshing. We rely on refreshing Type-5 LSA's + */ + if (IS_LSA_SELF (new)) + return new; + else + { + /* Try refresh type-5 translated LSA for this LSA, if one exists. + * New translations will be taken care of by the abr_task. + */ + ospf_translated_nssa_refresh (ospf, new, NULL); + } + } #endif /* HAVE_NSSA */ - /* Register self-originated LSA to refresh queue. */ - if (IS_LSA_SELF (new)) + /* Register self-originated LSA to refresh queue. + * Leave Translated LSAs alone + */ + if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) ) ospf_refresher_register_lsa (ospf, new); return new; @@ -2408,10 +2677,11 @@ ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi, new = ospf_opaque_lsa_install (lsa, rt_recalc); break; #endif /* HAVE_OPAQUE_LSA */ - default: /* NSSA, or type-6,8,9....nothing special */ #ifdef HAVE_NSSA + case OSPF_AS_NSSA_LSA: new = ospf_external_lsa_install (ospf, lsa, rt_recalc); #endif /* HAVE_NSSA */ + default: /* type-6,8,9....nothing special */ break; } @@ -2813,6 +3083,7 @@ ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type, return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id); break; case OSPF_AS_EXTERNAL_LSA: + case OSPF_AS_NSSA_LSA: #ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_LINK_LSA: case OSPF_OPAQUE_AREA_LSA: @@ -3287,11 +3558,18 @@ ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa) ospf_summary_asbr_lsa_refresh (ospf, lsa); break; case OSPF_AS_EXTERNAL_LSA: +#ifdef HAVE_NSSA + /* Translated from NSSA Type-5s are refreshed when + * from refresh of Type-7 - do not refresh these directly. + */ + if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) + break; +#endif /* HAVE_NSSA */ ei = ospf_external_info_check (lsa); if (ei) - ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE); + ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE); else - ospf_lsa_flush_as (ospf, lsa); + ospf_lsa_flush_as (ospf, lsa); break; #ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_LINK_LSA: @@ -3335,14 +3613,16 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa) % (OSPF_LSA_REFRESHER_SLOTS); if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_info ("LSA[Refresh]: lsa with age %d added to index %d", - LS_AGE (lsa), index); + zlog_info ("LSA[Refresh]: lsa %s with age %d added to index %d", + inet_ntoa (lsa->data->id), LS_AGE (lsa), index); if (!ospf->lsa_refresh_queue.qs[index]) ospf->lsa_refresh_queue.qs[index] = list_new (); listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa)); lsa->refresh_list = index; if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_info ("LSA[Refresh]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", lsa, index); + zlog_info ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): " + "setting refresh_list on lsa %p (slod %d)", + inet_ntoa (lsa->data->id), lsa, index); } } @@ -3392,7 +3672,8 @@ ospf_lsa_refresh_walker (struct thread *t) i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS) { if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh index %d", i); + zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): " + "refresh index %d", i); refresh_list = ospf->lsa_refresh_queue.qs [i]; @@ -3407,7 +3688,9 @@ ospf_lsa_refresh_walker (struct thread *t) next = node->next; if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", lsa, i); + zlog_info ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): " + "refresh lsa %p (slot %d)", + inet_ntoa (lsa->data->id), lsa, i); list_delete_node (refresh_list, node); ospf_lsa_unlock (lsa); diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 54c88d46..c5541c85 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -277,7 +277,9 @@ struct ospf_lsa *ospf_external_lsa_originate (struct ospf *, struct external_inf int ospf_external_lsa_originate_timer (struct thread *); struct ospf_lsa *ospf_lsa_lookup (struct ospf_area *, u_int32_t, struct in_addr, struct in_addr); -struct ospf_lsa *ospf_lsa_lookup_by_id (struct ospf_area *,u_int32_t, struct in_addr); +struct ospf_lsa *ospf_lsa_lookup_by_id (struct ospf_area *, + u_int32_t, + struct in_addr); struct ospf_lsa *ospf_lsa_lookup_by_header (struct ospf_area *, struct lsa_header *); int ospf_lsa_more_recent (struct ospf_lsa *, struct ospf_lsa *); @@ -319,10 +321,10 @@ int metric_value (struct ospf *, u_char); #ifdef HAVE_NSSA struct in_addr ospf_get_nssa_ip (struct ospf_area *); -#endif /* HAVE NSSA */ - -#ifdef HAVE_NSSA -struct in_addr ospf_get_nssa_ip (struct ospf_area *); +int ospf_translated_nssa_compare (struct ospf_lsa *, struct ospf_lsa *); +struct ospf_lsa *ospf_translated_nssa_refresh (struct ospf *, struct ospf_lsa *, + struct ospf_lsa *); +struct ospf_lsa *ospf_translated_nssa_originate (struct ospf *, struct ospf_lsa *); #endif #endif /* _ZEBRA_OSPF_LSA_H */ diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index aedac32a..0d455ec7 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -414,8 +414,8 @@ set_linkparams_link_id (struct ospf_interface *oi, struct mpls_te_link *lp) { case OSPF_IFTYPE_POINTOPOINT: /* Take the router ID of the neighbor. */ - if (((nbr = ospf_nbr_lookup_ptop (oi->nbrs, oi->area->top->router_id))) - && (nbr->state == NSM_Full)) + if ((nbr = ospf_nbr_lookup_ptop (oi)) + && nbr->state == NSM_Full) { lp->link_id.value = nbr->router_id; done = 1; @@ -429,7 +429,7 @@ set_linkparams_link_id (struct ospf_interface *oi, struct mpls_te_link *lp) if (nbr->state == NSM_Full || (IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi)) - && ospf_nbr_count (oi->nbrs, NSM_Full) > 0)) + && ospf_nbr_count (oi, NSM_Full) > 0)) { lp->link_id.value = DR (oi); done = 1; @@ -628,7 +628,7 @@ ospf_mpls_te_ism_change (struct ospf_interface *oi, int old_state) zlog_warn ("ospf_mpls_te_ism_change: Cannot get linkparams from OI(%s)?", IF_NAME (oi)); goto out; } - if (oi->area == NULL || oi->area->top == NULL) + if (oi->area == NULL || oi->area->ospf == NULL) { zlog_warn ("ospf_mpls_te_ism_change: Cannot refer to OSPF from OI(%s)?", IF_NAME (oi)); @@ -879,7 +879,7 @@ ospf_mpls_te_lsa_new (struct ospf_area *area, struct mpls_te_link *lp) options = LSA_OPTIONS_GET (area); #ifdef HAVE_NSSA - options |= LSA_NSSA_GET (area); + options |= LSA_OPTIONS_NSSA_GET (area); #endif /* HAVE_NSSA */ options |= OSPF_OPTION_O; /* Don't forget this :-) */ @@ -891,7 +891,7 @@ ospf_mpls_te_lsa_new (struct ospf_area *area, struct mpls_te_link *lp) zlog_info ("LSA[Type%d:%s]: Create an Opaque-LSA/MPLS-TE instance", lsa_type, inet_ntoa (lsa_id)); /* Set opaque-LSA header fields. */ - lsa_header_set (s, options, lsa_type, lsa_id); + lsa_header_set (s, options, lsa_type, lsa_id, area->ospf->router_id); /* Set opaque-LSA body fields. */ ospf_mpls_te_lsa_body_set (s, lp); @@ -939,7 +939,7 @@ ospf_mpls_te_lsa_originate1 (struct ospf_area *area, struct mpls_te_link *lp) } /* Install this LSA into LSDB. */ - if (ospf_lsa_install (NULL/*oi*/, new) == NULL) + if (ospf_lsa_install (area->ospf, NULL/*oi*/, new) == NULL) { zlog_warn ("ospf_mpls_te_lsa_originate1: ospf_lsa_install() ?"); ospf_lsa_free (new); @@ -950,7 +950,7 @@ ospf_mpls_te_lsa_originate1 (struct ospf_area *area, struct mpls_te_link *lp) lp->flags |= LPFLG_LSA_ENGAGED; /* Update new LSA origination count. */ - area->top->lsa_originate_count++; + area->ospf->lsa_originate_count++; /* Flood new LSA through area. */ ospf_flood_through_area (area, NULL/*nbr*/, new); @@ -1059,7 +1059,7 @@ ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa) /* Install this LSA into LSDB. */ /* Given "lsa" will be freed in the next function. */ - if (ospf_lsa_install (NULL/*oi*/, new) == NULL) + if (ospf_lsa_install (area->ospf, NULL/*oi*/, new) == NULL) { zlog_warn ("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?"); ospf_lsa_free (new); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index cec8903c..4418c777 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -1122,7 +1122,7 @@ ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id) /* set NSSA area defaults */ area->no_summary = 0; area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE; - area->NSSATranslatorState = OSPF_NSSA_STATE_DISABLED; + area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT; return 1; diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index ca9d9a9f..23a83ff7 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -344,11 +344,11 @@ struct ospf_area u_char NSSATranslatorRole; /* NSSA configured role */ #define OSPF_NSSA_ROLE_NEVER 0 -#define OSPF_NSSA_ROLE_ALWAYS 1 -#define OSPF_NSSA_ROLE_CANDIDATE 2 +#define OSPF_NSSA_ROLE_CANDIDATE 1 +#define OSPF_NSSA_ROLE_ALWAYS 2 u_char NSSATranslatorState; /* NSSA operational role */ -#define OSPF_NSSA_STATE_DISABLED 0 -#define OSPF_NSSA_STATE_ENABLED 2 +#define OSPF_NSSA_TRANSLATE_DISABLED 0 +#define OSPF_NSSA_TRANSLATE_ENABLED 1 int NSSATranslatorStabilityInterval; u_char transit; /* TransitCapability. */ @@ -474,9 +474,8 @@ struct ospf_nbr_nbma #define LSA_OPTIONS_GET(area) \ (((area)->external_routing == OSPF_AREA_DEFAULT) ? OSPF_OPTION_E : 0) #ifdef HAVE_NSSA -#define LSA_NSSA_GET(area) \ - (((area)->external_routing == OSPF_AREA_NSSA) ? \ - (area)->NSSATranslatorState : 0) +#define LSA_OPTIONS_NSSA_GET(area) \ + (((area)->external_routing == OSPF_AREA_NSSA) ? OSPF_OPTION_NP : 0) #endif /* HAVE_NSSA */ #define OSPF_TIMER_ON(T,F,V) \ -- cgit v1.2.1