summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_spf.c
diff options
context:
space:
mode:
authorKaushik <kaushiknath.null@gmail.com>2021-03-25 04:29:51 -0700
committerRafael Zalamena <rzalamena@opensourcerouting.org>2021-06-04 07:23:10 -0300
commitad500b22b5fc3bc34009b7212c7c3b2f6c4375aa (patch)
treef24f206101ffcbfc968ad97fd54a71b94c134ccb /ospf6d/ospf6_spf.c
parent10ddcc321a59de099ee357fd5cca229a8c3110bf (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.c185
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);
+}