diff options
| author | Russ White <russ@riw.us> | 2021-10-19 19:15:40 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-19 19:15:40 -0400 |
| commit | ed131d8b748c1d0a47736c4e549e15deb180b6f9 (patch) | |
| tree | 64cc873783b8648b5929780a720da18146258b49 /ospf6d/ospf6_nssa.c | |
| parent | 32c8a3c2ae48d85bd855b0ebb55c426121be843a (diff) | |
| parent | 343e16cec54cc8c6e5df389e3a20efd98e450ff1 (diff) | |
Merge pull request #9752 from opensourcerouting/ospf6d-nssa-ranges
ospf6d: add support for NSSA Type-7 address ranges
Diffstat (limited to 'ospf6d/ospf6_nssa.c')
| -rw-r--r-- | ospf6d/ospf6_nssa.c | 487 |
1 files changed, 203 insertions, 284 deletions
diff --git a/ospf6d/ospf6_nssa.c b/ospf6d/ospf6_nssa.c index c2e9b7f28a..84f014d680 100644 --- a/ospf6d/ospf6_nssa.c +++ b/ospf6d/ospf6_nssa.c @@ -49,6 +49,9 @@ #include "ospf6_asbr.h" #include "ospf6d.h" #include "ospf6_nssa.h" +#ifndef VTYSH_EXTRACT_PL +#include "ospf6d/ospf6_nssa_clippy.c" +#endif DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA, "OSPF6 LSA"); unsigned char config_debug_ospf6_nssa = 0; @@ -262,22 +265,20 @@ static void ospf6_abr_announce_aggregates(struct ospf6 *ospf6) { struct ospf6_area *area; struct ospf6_route *range; - struct listnode *node, *nnode; + struct listnode *node; if (IS_OSPF6_DEBUG_ABR) zlog_debug("ospf6_abr_announce_aggregates(): Start"); - for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, area)) { - for (range = ospf6_route_head(area->range_table); range; - range = ospf6_route_next(range)) - ospf6_abr_range_update(range, ospf6); - } - for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, area)) { if (IS_OSPF6_DEBUG_ABR) zlog_debug( "ospf_abr_announce_aggregates(): looking at area %pI4", &area->area_id); + + for (range = ospf6_route_head(area->range_table); range; + range = ospf6_route_next(range)) + ospf6_abr_range_update(range, ospf6); } if (IS_OSPF6_DEBUG_ABR) @@ -381,22 +382,18 @@ static void ospf6_abr_unapprove_translates(struct ospf6 *ospf6) { struct ospf6_lsa *lsa; uint16_t type; - struct ospf6_area *oa; - struct listnode *node; if (IS_OSPF6_DEBUG_NSSA) zlog_debug("ospf6_abr_unapprove_translates(): Start"); type = htons(OSPF6_LSTYPE_AS_EXTERNAL); - for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { - for (ALL_LSDB_TYPED(oa->lsdb, type, lsa)) { - if (CHECK_FLAG(lsa->flag, OSPF6_LSA_LOCAL_XLT)) { - SET_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED); - if (IS_OSPF6_DEBUG_NSSA) - zlog_debug( - "%s : approved unset on link id %pI4", - __func__, &lsa->header->id); - } + for (ALL_LSDB_TYPED(ospf6->lsdb, type, lsa)) { + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_LOCAL_XLT)) { + SET_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED); + if (IS_OSPF6_DEBUG_NSSA) + zlog_debug( + "%s : approved unset on link id %pI4", + __func__, &lsa->header->id); } } @@ -408,17 +405,17 @@ static void ospf6_abr_unapprove_translates(struct ospf6 *ospf6) static struct ospf6_lsa *ospf6_lsa_translated_nssa_new(struct ospf6_area *area, struct ospf6_lsa *type7) { - char *buffer; + char buffer[OSPF6_MAX_LSASIZE]; struct ospf6_lsa *lsa; struct ospf6_as_external_lsa *ext, *extnew; struct ospf6_lsa_header *lsa_header; caddr_t old_ptr, new_ptr; struct ospf6_as_external_lsa *nssa; struct prefix prefix; - struct ospf6_route *match; struct ospf6 *ospf6 = area->ospf6; ptrdiff_t tag_offset = 0; route_tag_t network_order; + struct ospf6_route *range; if (IS_OSPF6_DEBUG_NSSA) zlog_debug("%s : Start", __func__); @@ -430,7 +427,27 @@ static struct ospf6_lsa *ospf6_lsa_translated_nssa_new(struct ospf6_area *area, return NULL; } - buffer = XCALLOC(MTYPE_OSPF6_LSA, OSPF6_MAX_LSASIZE); + /* find the translated Type-5 for this Type-7 */ + nssa = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + type7->header); + prefix.family = AF_INET6; + prefix.prefixlen = nssa->prefix.prefix_length; + ospf6_prefix_in6_addr(&prefix.u.prefix6, nssa, &nssa->prefix); + + /* Check if the Type-7 LSA should be suppressed by aggregation. */ + range = ospf6_route_lookup_bestmatch(&prefix, area->nssa_range_table); + if (range && !prefix_same(&prefix, &range->prefix) + && !CHECK_FLAG(range->flag, OSPF6_ROUTE_REMOVE)) { + if (IS_OSPF6_DEBUG_NSSA) + zlog_debug( + "%s: LSA %s suppressed by range %pFX of area %s", + __func__, type7->name, &range->prefix, + area->name); + return NULL; + } + + /* prepare buffer */ + memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; extnew = (struct ospf6_as_external_lsa *)((caddr_t)lsa_header @@ -445,23 +462,6 @@ static struct ospf6_lsa *ospf6_lsa_translated_nssa_new(struct ospf6_area *area, memcpy(extnew, ext, sizeof(struct ospf6_as_external_lsa)); - /* find the translated Type-5 for this Type-7 */ - nssa = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( - type7->header); - - prefix.family = AF_INET6; - prefix.prefixlen = nssa->prefix.prefix_length; - ospf6_prefix_in6_addr(&prefix.u.prefix6, nssa, &nssa->prefix); - - /* Find the LSA from the external route */ - match = ospf6_route_lookup(&prefix, area->route_table); - if (match == NULL) { - if (IS_OSPF6_DEBUG_NSSA) - zlog_debug("%s : no matching route %pFX", __func__, - &prefix); - return NULL; - } - /* set Prefix */ memcpy(new_ptr, old_ptr, OSPF6_PREFIX_SPACE(ext->prefix.prefix_length)); ospf6_prefix_apply_mask(&extnew->prefix); @@ -542,7 +542,6 @@ struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *area, struct ospf6_lsa *type5) { struct ospf6_lsa *new = NULL; - struct ospf6_as_external_lsa *ext_lsa; struct prefix prefix; struct ospf6 *ospf6 = area->ospf6; @@ -554,27 +553,27 @@ struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *area, /* Find the AS external LSA */ if (type5 == NULL) { + struct ospf6_as_external_lsa *ext_lsa; + struct ospf6_route *match; + + /* Find the AS external LSA from Type-7 LSA */ if (IS_OSPF6_DEBUG_NSSA) zlog_debug( - "%s: No translated Type-5 found for Type-7 with Id %pI4", - __func__, &type7->header->id); + "%s: try to find translated Type-5 LSA for %s", + __func__, type7->name); - /* find the translated Type-5 for this Type-7 */ ext_lsa = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( type7->header); - prefix.family = AF_INET6; prefix.prefixlen = ext_lsa->prefix.prefix_length; ospf6_prefix_in6_addr(&prefix.u.prefix6, ext_lsa, &ext_lsa->prefix); - /* Find the AS external LSA from Type-7 LSA */ - if (IS_OSPF6_DEBUG_NSSA) - zlog_debug("%s: try to find external LSA id %d", - __func__, type7->external_lsa_id); - type5 = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), - type7->external_lsa_id, - ospf6->router_id, ospf6->lsdb); + match = ospf6_route_lookup(&prefix, ospf6->external_table); + if (match) + type5 = ospf6_lsdb_lookup( + OSPF6_LSTYPE_AS_EXTERNAL, match->path.origin.id, + ospf6->router_id, ospf6->lsdb); } if (type5) { @@ -602,6 +601,7 @@ struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *area, __func__, &type7->header->id); return NULL; } + UNSET_FLAG(new->flag, OSPF6_LSA_UNAPPROVED); } if (IS_OSPF6_DEBUG_NSSA) @@ -610,32 +610,11 @@ struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *area, return new; } -/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */ -struct ospf6_lsa *ospf6_translated_nssa_originate(struct ospf6_area *oa, - struct ospf6_lsa *type7) -{ - struct ospf6_lsa *new; - - if (ntohs(type7->header->type) != OSPF6_LSTYPE_TYPE_7) - return NULL; - - if ((new = ospf6_lsa_translated_nssa_new(oa, type7)) == NULL) { - if (IS_OSPF6_DEBUG_NSSA) - zlog_debug( - "%s : Could not translate Type-7, Id %pI4, to Type-5", - __func__, &type7->header->id); - return NULL; - } - - return new; -} - -int ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_lsa *lsa) +static void ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_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 @@ -659,7 +638,7 @@ int ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_lsa *lsa) zlog_debug( "%s : LSA Id %pI4, P-bit off, NO Translation", __func__, &lsa->header->id); - return 1; + return; } if (IS_OSPF6_DEBUG_NSSA) @@ -676,7 +655,7 @@ int ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_lsa *lsa) zlog_debug( "%s : LSA Id %pI4, Forward address is 0, NO Translation", __func__, &lsa->header->id); - return 1; + return; } /* Find the existing AS-External LSA for this prefix */ @@ -687,23 +666,13 @@ int ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_lsa *lsa) ospf6->lsdb); } - /* Check Type 5 LSA using the matching external ID */ - if (old == NULL) { - old = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), - lsa->external_lsa_id, ospf6->router_id, - ospf6->lsdb); + if (OSPF6_LSA_IS_MAXAGE(lsa)) { + if (old) + ospf6_lsa_premature_aging(old); + return; } if (old) { - /* Do not continue if type 5 LSA not approved */ - if (CHECK_FLAG(old->flag, OSPF6_LSA_UNAPPROVED)) { - if (IS_OSPF6_DEBUG_NSSA) - zlog_debug( - "%s : LSA Id %pI4 type 5 is not approved", - __func__, &old->header->id); - return 1; - } - if (IS_OSPF6_DEBUG_NSSA) zlog_debug( "%s : found old translated LSA Id %pI4, refreshing", @@ -722,16 +691,14 @@ int ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_lsa *lsa) * originate translated LSA */ - if (ospf6_translated_nssa_originate(area, lsa) == NULL) { + if (ospf6_lsa_translated_nssa_new(area, lsa) == NULL) { if (IS_OSPF6_DEBUG_NSSA) zlog_debug( "%s : Could not translate Type-7 for %pI4 to Type-5", __func__, &lsa->header->id); - return 1; + return; } } - - return 0; } static void ospf6_abr_process_nssa_translates(struct ospf6 *ospf6) @@ -751,6 +718,8 @@ static void ospf6_abr_process_nssa_translates(struct ospf6 *ospf6) zlog_debug("%s : Start", __func__); for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + if (!IS_AREA_NSSA(oa)) + continue; /* skip if not translator */ if (oa->NSSATranslatorState == OSPF6_NSSA_TRANSLATE_DISABLED) { @@ -760,13 +729,6 @@ static void ospf6_abr_process_nssa_translates(struct ospf6 *ospf6) continue; } - /* skip if not Nssa Area */ - if (!IS_AREA_NSSA(oa)) { - zlog_debug("%s area %pI4 Flag %x", __func__, - &oa->area_id, oa->flag); - continue; - } - if (IS_OSPF6_DEBUG_NSSA) zlog_debug("%s : looking at area %pI4", __func__, &oa->area_id); @@ -784,71 +746,30 @@ static void ospf6_abr_process_nssa_translates(struct ospf6 *ospf6) zlog_debug("%s : Stop", __func__); } -/* Generate translated type-5 LSA from the configured area ranges*/ -static void ospf6_abr_translate_nssa_range(struct ospf6 *ospf6) -{ - struct listnode *node, *nnode; - struct ospf6_area *oa; - struct ospf6_route *range; - struct ospf6_lsa *lsa; - - for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) { - for (range = ospf6_route_head(oa->range_table); range; - range = ospf6_route_next(range)) { - if (IS_OSPF6_DEBUG_NSSA) - zlog_debug( - "Translating range %pFX of area %pI4", - &range->prefix, &oa->area_id); - if (CHECK_FLAG(range->flag, - OSPF6_ROUTE_DO_NOT_ADVERTISE)) - continue; - - /* Find the NSSA LSA from the route */ - /* Generate and flood external LSA */ - lsa = ospf6_lsdb_lookup(OSPF6_LSTYPE_TYPE_7, - range->path.origin.id, - ospf6->router_id, oa->lsdb); - if (lsa) - ospf6_abr_translate_nssa(oa, lsa); - } - } -} - static void ospf6_abr_send_nssa_aggregates(struct ospf6 *ospf6) { struct listnode *node; struct ospf6_area *area; + struct ospf6_route *range; if (IS_OSPF6_DEBUG_NSSA) - zlog_debug("%s : Start", __func__); + zlog_debug("%s: Start", __func__); for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, area)) { if (area->NSSATranslatorState == OSPF6_NSSA_TRANSLATE_DISABLED) continue; if (IS_OSPF6_DEBUG_NSSA) - zlog_debug("%s : looking at area %pI4", __func__, + zlog_debug("%s: looking at area %pI4", __func__, &area->area_id); - ospf6_abr_translate_nssa_range(ospf6); + for (range = ospf6_route_head(area->nssa_range_table); range; + range = ospf6_route_next(range)) + ospf6_abr_range_update(range, ospf6); } if (IS_OSPF6_DEBUG_NSSA) - zlog_debug("%s : Stop", __func__); -} - -/*Flood max age LSA's for the unapproved LSA's */ -static int ospf6_abr_remove_unapproved_translates_apply(struct ospf6_lsa *lsa) -{ - if (CHECK_FLAG(lsa->flag, OSPF6_LSA_LOCAL_XLT) - && CHECK_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED)) { - zlog_debug("%s : removing unapproved translates, lsa : %s", - __func__, lsa->name); - - /* FLUSH THROUGHOUT AS */ - ospf6_lsa_premature_aging(lsa); - } - return 0; + zlog_debug("%s: Stop", __func__); } static void ospf6_abr_remove_unapproved_translates(struct ospf6 *ospf6) @@ -862,8 +783,16 @@ static void ospf6_abr_remove_unapproved_translates(struct ospf6 *ospf6) zlog_debug("ospf6_abr_remove_unapproved_translates(): Start"); type = htons(OSPF6_LSTYPE_AS_EXTERNAL); - for (ALL_LSDB_TYPED(ospf6->lsdb, type, lsa)) - ospf6_abr_remove_unapproved_translates_apply(lsa); + for (ALL_LSDB_TYPED(ospf6->lsdb, type, lsa)) { + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_LOCAL_XLT) + && CHECK_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED)) { + zlog_debug( + "%s : removing unapproved translates, lsa : %s", + __func__, lsa->name); + + ospf6_lsa_premature_aging(lsa); + } + } if (IS_OSPF6_DEBUG_NSSA) zlog_debug("ospf_abr_remove_unapproved_translates(): Stop"); @@ -948,11 +877,6 @@ void ospf6_abr_nssa_type_7_defaults(struct ospf6 *ospf6) static void ospf6_abr_nssa_task(struct ospf6 *ospf6) { - /* called only if any_nssa */ - struct ospf6_route *range; - struct ospf6_area *area; - struct listnode *node, *nnode; - if (IS_OSPF6_DEBUG_NSSA) zlog_debug("Check for NSSA-ABR Tasks():"); @@ -978,10 +902,10 @@ static void ospf6_abr_nssa_task(struct ospf6 *ospf6) ospf6_abr_unapprove_translates(ospf6); - /* RESET all Ranges in every Area, same as summaries */ + /* Originate Type-7 aggregates */ if (IS_OSPF6_DEBUG_NSSA) - zlog_debug("ospf6_abr_nssa_task(): NSSA initialize aggregates"); - ospf6_abr_range_reset_cost(ospf6); + zlog_debug("ospf6_abr_nssa_task(): send NSSA aggregates"); + ospf6_abr_send_nssa_aggregates(ospf6); /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or * Aggregate as Type-7 @@ -991,32 +915,12 @@ static void ospf6_abr_nssa_task(struct ospf6 *ospf6) zlog_debug("ospf6_abr_nssa_task(): process translates"); ospf6_abr_process_nssa_translates(ospf6); - /* Translate/Send any "ranged" aggregates, and also 5-Install and - * Approve - * Scan Type-7's for aggregates, translate to Type-5's, - * Install/Flood/Approve - */ - if (IS_OSPF6_DEBUG_NSSA) - zlog_debug("ospf6_abr_nssa_task(): send NSSA aggregates"); - ospf6_abr_send_nssa_aggregates(ospf6); /*TURNED OFF FOR NOW */ - /* Flush any unapproved previous translates from Global Data Base */ if (IS_OSPF6_DEBUG_NSSA) zlog_debug( "ospf6_abr_nssa_task(): remove unapproved translates"); ospf6_abr_remove_unapproved_translates(ospf6); - for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, area)) { - for (range = ospf6_route_head(area->range_table); range; - range = ospf6_route_next(range)) { - if (CHECK_FLAG(range->flag, - OSPF6_ROUTE_DO_NOT_ADVERTISE)) - ospf6_zebra_delete_discard(range, ospf6); - else - ospf6_zebra_add_discard(range, ospf6); - } - } - if (IS_OSPF6_DEBUG_NSSA) zlog_debug("ospf6_abr_nssa_task(): Stop"); } @@ -1063,106 +967,6 @@ int ospf6_redistribute_check(struct ospf6 *ospf6, struct ospf6_route *route, return 1; } -static void ospf6_external_lsa_refresh_type(struct ospf6 *ospf6, uint8_t type, - unsigned short instance, int force) -{ - struct ospf6_route *route; - struct ospf6_external_info *info; - struct ospf6_lsa *lsa; - - if (type == ZEBRA_ROUTE_MAX) - return; - - for (route = ospf6_route_head(ospf6->external_table); route; - route = ospf6_route_next(route)) { - info = route->route_option; - - /* Find the external LSA in the database */ - if (!is_default_prefix(&route->prefix)) { - lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), - htonl(info->id), - ospf6->router_id, ospf6->lsdb); - - if (lsa) { - THREAD_OFF(lsa->refresh); - - /* LSA is maxage, immediate refresh */ - if (OSPF6_LSA_IS_MAXAGE(lsa)) - ospf6_flood(NULL, lsa); - else - thread_add_timer(master, - ospf6_lsa_refresh, lsa, - OSPF_LS_REFRESH_TIME, - &lsa->refresh); - } else { - /* LSA not found in the database - * Verify and originate external LSA - */ - if (ospf6_redistribute_check(ospf6, route, - type)) - ospf6_as_external_lsa_originate(route, - ospf6); - } - } - } -} - -/* Refresh default route */ -static void ospf6_external_lsa_refresh_default(struct ospf6 *ospf6) -{ - struct ospf6_route *route; - struct ospf6_external_info *info; - struct ospf6_lsa *lsa; - - for (route = ospf6_route_head(ospf6->external_table); route; - route = ospf6_route_next(route)) { - if (is_default_prefix(&route->prefix)) { - info = route->route_option; - lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), - htonl(info->id), - ospf6->router_id, ospf6->lsdb); - - if (lsa) { - if (IS_OSPF6_DEBUG_NSSA) - zlog_debug( - "LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", - (void *)lsa); - if (OSPF6_LSA_IS_MAXAGE(lsa)) - ospf6_flood(NULL, lsa); - else - thread_add_timer(master, - ospf6_lsa_refresh, lsa, - OSPF_LS_REFRESH_TIME, - &lsa->refresh); - } else if (!lsa) { - if (IS_OSPF6_DEBUG_NSSA) - zlog_debug( - "LSA[Type5:0.0.0.0]: Originate AS-external-LSA"); - ospf6_as_external_lsa_originate(route, ospf6); - } - } - } -} - -/* If there's redistribution configured, we need to refresh external - * LSAs in order to install Type-7 and flood to all NSSA Areas - */ -void ospf6_asbr_nssa_redist_task(struct ospf6 *ospf6) -{ - int type; - struct ospf6_redist *red; - - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { - red = ospf6_redist_lookup(ospf6, type, 0); - if (!red) - return; - - ospf6_external_lsa_refresh_type(ospf6, type, red->instance, - LSA_REFRESH_IF_CHANGED); - } - ospf6_external_lsa_refresh_default(ospf6); -} - /* This function performs ABR related processing */ static int ospf6_abr_task_timer(struct thread *thread) { @@ -1176,7 +980,6 @@ static int ospf6_abr_task_timer(struct thread *thread) ospf6_abr_task(ospf6); /* if nssa-abr, then scan Type-7 LSDB */ ospf6_abr_nssa_task(ospf6); - ospf6_asbr_nssa_redist_task(ospf6); return 0; } @@ -1337,6 +1140,13 @@ int ospf6_area_nssa_unset(struct ospf6 *ospf6, struct ospf6_area *area) UNSET_FLAG(area->flag, OSPF6_AREA_NSSA); if (IS_OSPF6_DEBUG_NSSA) zlog_debug("area %s nssa reset", area->name); + + /* Clear the table of NSSA ranges. */ + ospf6_route_table_delete(area->nssa_range_table); + area->nssa_range_table = + OSPF6_ROUTE_TABLE_CREATE(AREA, PREFIX_RANGES); + area->nssa_range_table->scope = area; + ospf6_area_nssa_update(area); } @@ -1350,10 +1160,14 @@ static struct in6_addr *ospf6_get_nssa_fwd_addr(struct ospf6_area *oa) struct ospf6_interface *oi; for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) { - if (if_is_operative(oi->interface)) - if (oi->area && IS_AREA_NSSA(oi->area)) - return ospf6_interface_get_global_address( - oi->interface); + struct in6_addr *addr; + + if (!if_is_operative(oi->interface)) + continue; + + addr = ospf6_interface_get_global_address(oi->interface); + if (addr) + return addr; } return NULL; } @@ -1463,17 +1277,119 @@ void ospf6_abr_check_translate_nssa(struct ospf6_area *area, if (IS_OSPF6_DEBUG_NSSA) zlog_debug("%s : start", __func__); + if (!ospf6_check_and_set_router_abr(ospf6)) + return; + type5 = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), lsa->external_lsa_id, ospf6->router_id, ospf6->lsdb); - - if (ospf6_check_and_set_router_abr(ospf6) && (type5 == NULL)) { + if (!type5) { if (IS_OSPF6_DEBUG_NSSA) zlog_debug("%s : Originating type5 LSA", __func__); ospf6_lsa_translated_nssa_new(area, lsa); } } +DEFPY (area_nssa_range, + area_nssa_range_cmd, + "area <A.B.C.D|(0-4294967295)>$area nssa range X:X::X:X/M$prefix [<not-advertise$not_adv|cost (0-16777215)$cost>]", + "OSPF6 area parameters\n" + "OSPF6 area ID in IP address format\n" + "OSPF6 area ID as a decimal value\n" + "Configure OSPF6 area as nssa\n" + "Configured address range\n" + "Specify IPv6 prefix\n" + "Do not advertise\n" + "User specified metric for this range\n" + "Advertised metric for this range\n") +{ + struct ospf6_area *oa; + struct ospf6_route *range; + + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(area, oa, ospf6); + + if (!IS_AREA_NSSA(oa)) { + vty_out(vty, "%% First configure %s as an NSSA area\n", area); + return CMD_WARNING; + } + + range = ospf6_route_lookup((struct prefix *)prefix, + oa->nssa_range_table); + if (range == NULL) { + range = ospf6_route_create(ospf6); + range->type = OSPF6_DEST_TYPE_RANGE; + SET_FLAG(range->flag, OSPF6_ROUTE_NSSA_RANGE); + prefix_copy(&range->prefix, prefix); + range->path.area_id = oa->area_id; + range->path.metric_type = 2; + range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC; + range->path.origin.type = htons(OSPF6_LSTYPE_TYPE_7); + range->path.origin.id = htonl(ospf6->external_id++); + range->path.origin.adv_router = ospf6->router_id; + ospf6_route_add(range, oa->nssa_range_table); + } + + /* process "not-advertise" */ + if (not_adv) + SET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + else + UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + + /* process "cost" */ + if (!cost_str) + cost = OSPF_AREA_RANGE_COST_UNSPEC; + range->path.u.cost_config = cost; + + /* Redo summaries if required */ + if (ospf6_check_and_set_router_abr(ospf6)) + ospf6_schedule_abr_task(ospf6); + + return CMD_SUCCESS; +} + +DEFPY (no_area_nssa_range, + no_area_nssa_range_cmd, + "no area <A.B.C.D|(0-4294967295)>$area nssa range X:X::X:X/M$prefix [<not-advertise|cost (0-16777215)>]", + NO_STR + "OSPF6 area parameters\n" + "OSPF6 area ID in IP address format\n" + "OSPF6 area ID as a decimal value\n" + "Configure OSPF6 area as nssa\n" + "Configured address range\n" + "Specify IPv6 prefix\n" + "Do not advertise\n" + "User specified metric for this range\n" + "Advertised metric for this range\n") +{ + struct ospf6_area *oa; + struct ospf6_route *range; + + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(area, oa, ospf6); + + range = ospf6_route_lookup((struct prefix *)prefix, + oa->nssa_range_table); + if (range == NULL) { + vty_out(vty, "%% range %s does not exists.\n", prefix_str); + return CMD_SUCCESS; + } + + if (ospf6_check_and_set_router_abr(oa->ospf6)) { + /* Blow away the aggregated LSA and route */ + SET_FLAG(range->flag, OSPF6_ROUTE_REMOVE); + + /* Redo summaries if required */ + thread_execute(master, ospf6_abr_task_timer, ospf6, 0); + } + + ospf6_route_remove(range, oa->nssa_range_table); + + return CMD_SUCCESS; +} + DEFUN(debug_ospf6_nssa, debug_ospf6_nssa_cmd, "debug ospf6 nssa", DEBUG_STR @@ -1503,6 +1419,9 @@ void config_write_ospf6_debug_nssa(struct vty *vty) void install_element_ospf6_debug_nssa(void) { + install_element(OSPF6_NODE, &area_nssa_range_cmd); + install_element(OSPF6_NODE, &no_area_nssa_range_cmd); + install_element(ENABLE_NODE, &debug_ospf6_nssa_cmd); install_element(ENABLE_NODE, &no_debug_ospf6_nssa_cmd); install_element(CONFIG_NODE, &debug_ospf6_nssa_cmd); |
