diff options
| author | Kaushik <kaushiknath.null@gmail.com> | 2021-03-25 04:29:51 -0700 | 
|---|---|---|
| committer | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2021-06-04 07:23:10 -0300 | 
| commit | ad500b22b5fc3bc34009b7212c7c3b2f6c4375aa (patch) | |
| tree | f24f206101ffcbfc968ad97fd54a71b94c134ccb /ospf6d/ospf6_spf.c | |
| parent | 10ddcc321a59de099ee357fd5cca229a8c3110bf (diff) | |
ospf6d: Support for nssa in ospfv3
The following is implemented.
1. Configuring area as NSSA.
2. Generating Type 7 LSA.
3. Conversion of Type 7 to Type 5 ( Default Behavior).
4. NSSA ABR selection.
Reviewed-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Co-authored-by: Kaushik <kaushiknath.null@gmail.com>
Co-authored-by: Soman K.S <somanks@gmail.com>
Signed-off-by: Kaushik <kaushiknath.null@gmail.com>
Diffstat (limited to 'ospf6d/ospf6_spf.c')
| -rw-r--r-- | ospf6d/ospf6_spf.c | 185 | 
1 files changed, 185 insertions, 0 deletions
diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 7652d71c59..1d32844fec 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -37,11 +37,13 @@  #include "ospf6_area.h"  #include "ospf6_proto.h"  #include "ospf6_abr.h" +#include "ospf6_asbr.h"  #include "ospf6_spf.h"  #include "ospf6_intra.h"  #include "ospf6_interface.h"  #include "ospf6d.h"  #include "ospf6_abr.h" +#include "ospf6_nssa.h"  DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_VERTEX, "OSPF6 vertex"); @@ -640,6 +642,9 @@ static int ospf6_spf_calculation_thread(struct thread *t)  		areas_processed++;  	} +	/* External LSA calculation */ +	ospf6_ase_calculate_timer_add(ospf6); +  	if (ospf6_is_router_abr(ospf6))  		ospf6_abr_defaults_to_stub(ospf6); @@ -1105,3 +1110,183 @@ void ospf6_remove_temp_router_lsa(struct ospf6_area *area)  		ospf6_lsdb_remove(lsa, area->temp_router_lsa_lsdb);  	}  } + +int ospf6_ase_calculate_route(struct ospf6 *ospf6, struct ospf6_lsa *lsa, +			      struct ospf6_area *area) +{ +	struct ospf6_route *route, *old; +	struct ospf6_as_external_lsa *external; +	struct prefix prefix; +	void (*hook_add)(struct ospf6_route *) = NULL; +	void (*hook_remove)(struct ospf6_route *) = NULL; + +	assert(lsa); + +	if (IS_OSPF6_DEBUG_SPF(PROCESS)) +		zlog_debug("%s :  start", __func__); + +	if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7) +		if (IS_OSPF6_DEBUG_SPF(PROCESS)) +			zlog_debug("%s: Processing Type-7", __func__); + +	/* Stay away from any Local Translated Type-7 LSAs */ +	if (CHECK_FLAG(lsa->flag, OSPF6_LSA_LOCAL_XLT)) { +		if (IS_OSPF6_DEBUG_SPF(PROCESS)) +			zlog_debug("%s: Rejecting Local translated LSA", +				   __func__); +		return 0; +	} + +	external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( +		lsa->header); +	prefix.family = AF_INET6; +	prefix.prefixlen = external->prefix.prefix_length; +	ospf6_prefix_in6_addr(&prefix.u.prefix6, external, &external->prefix); + +	if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL) { +		hook_add = ospf6->route_table->hook_add; +		hook_remove = ospf6->route_table->hook_remove; +		ospf6->route_table->hook_add = NULL; +		ospf6->route_table->hook_remove = NULL; + +		old = ospf6_route_lookup(&prefix, ospf6->route_table); +		if (old) { +			if (IS_OSPF6_DEBUG_SPF(PROCESS)) +				zlog_debug("%s : remove external route %pFX", +					   __func__, &prefix); +			old->flag = OSPF6_ROUTE_REMOVE; +		} + +		if (!OSPF6_LSA_IS_MAXAGE(lsa)) +			ospf6_asbr_lsa_add(lsa); + +		ospf6->route_table->hook_add = hook_add; +		ospf6->route_table->hook_remove = hook_remove; + +		route = ospf6_route_lookup(&prefix, ospf6->route_table); +		if (route == NULL) { +			if (IS_OSPF6_DEBUG_SPF(PROCESS)) +				zlog_debug("%s : no external route %pFX", +					   __func__, &prefix); +			return 0; +		} + +		if (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE) +		    && (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD) +			|| (old == route))) { +			UNSET_FLAG(route->flag, OSPF6_ROUTE_REMOVE); +			UNSET_FLAG(route->flag, OSPF6_ROUTE_ADD); +		} + +		if (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE)) +			ospf6_route_remove(route, ospf6->route_table); +		else if (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD) +			 || CHECK_FLAG(route->flag, OSPF6_ROUTE_CHANGE)) { +			if (hook_add) { +				if (IS_OSPF6_DEBUG_SPF(PROCESS)) +					zlog_debug( +						"%s: add external route %pFX", +						__func__, &prefix); +				(*hook_add)(route); +			} +			route->flag = 0; +		} +	} else if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7) { +		hook_add = area->route_table->hook_add; +		hook_remove = area->route_table->hook_remove; +		area->route_table->hook_add = NULL; +		area->route_table->hook_remove = NULL; + +		old = ospf6_route_lookup(&prefix, area->route_table); +		if (old) { +			if (IS_OSPF6_DEBUG_SPF(PROCESS)) +				zlog_debug( +					"%s: set remove flag nssa route %pFX, area %s", +					__func__, &prefix, area->name); +			old->flag = OSPF6_ROUTE_REMOVE; +		} + +		if (!OSPF6_LSA_IS_MAXAGE(lsa)) +			ospf6_asbr_lsa_add(lsa); + +		area->route_table->hook_add = hook_add; +		area->route_table->hook_remove = hook_remove; + +		route = ospf6_route_lookup(&prefix, area->route_table); +		if (route == NULL) { +			if (IS_OSPF6_DEBUG_SPF(PROCESS)) +				zlog_debug("%s : no route %pFX, area %s", +					   __func__, &prefix, area->name); +			return 0; +		} + +		if (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE) +		    && (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD) +			|| (old == route))) { +			UNSET_FLAG(route->flag, OSPF6_ROUTE_REMOVE); +			UNSET_FLAG(route->flag, OSPF6_ROUTE_ADD); +		} + +		if (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE)) { +			if (IS_OSPF6_DEBUG_SPF(PROCESS)) +				zlog_debug("%s : remove route %pFX, area %s", +					   __func__, &prefix, area->name); +			ospf6_route_remove(route, area->route_table); +		} else if (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD) +			   || CHECK_FLAG(route->flag, OSPF6_ROUTE_CHANGE)) { +			if (hook_add) { +				if (IS_OSPF6_DEBUG_SPF(PROCESS)) +					zlog_debug( +						"%s: add nssa route %pFX, area %s", +						__func__, &prefix, area->name); +				(*hook_add)(route); +			} +			ospf6_abr_check_translate_nssa(area, lsa); +			route->flag = 0; +		} +	} +	return 0; +} + +static int ospf6_ase_calculate_timer(struct thread *t) +{ +	struct ospf6 *ospf6; +	struct ospf6_lsa *lsa; +	struct listnode *node, *nnode; +	struct ospf6_area *area; +	uint16_t type; + +	ospf6 = THREAD_ARG(t); +	ospf6->t_ase_calc = NULL; + +	/* Calculate external route for each AS-external-LSA */ +	type = htons(OSPF6_LSTYPE_AS_EXTERNAL); +	for (ALL_LSDB_TYPED(ospf6->lsdb, type, lsa)) +		ospf6_ase_calculate_route(ospf6, lsa, NULL); + +	/*  This version simple adds to the table all NSSA areas  */ +	if (ospf6->anyNSSA) { +		for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, area)) { +			if (IS_OSPF6_DEBUG_SPF(PROCESS)) +				zlog_debug("%s : looking at area %s", __func__, +					   area->name); + +			if (IS_OSPF6_DEBUG_SPF(PROCESS)) { +				type = htons(OSPF6_LSTYPE_TYPE_7); +				for (ALL_LSDB_TYPED(area->lsdb, type, lsa)) +					ospf6_ase_calculate_route(ospf6, lsa, +								  area); +			} +		} +	} +	return 0; +} + +void ospf6_ase_calculate_timer_add(struct ospf6 *ospf6) +{ +	if (ospf6 == NULL) +		return; + +	thread_add_timer(master, ospf6_ase_calculate_timer, ospf6, +			 OSPF6_ASE_CALC_INTERVAL, &ospf6->t_ase_calc); +}  | 
