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);  | 
