From d36a6a19d996240f8b8c2a960b181fa14522dc09 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Mon, 16 Aug 2021 21:35:27 -0300 Subject: [PATCH 1/9] ospf6d: always unset the E-bit on NSSA ABRs RFC 3101 - Section 2.1 says: "(..) Interfaces associated with an NSSA will not send or receive Type-5 LSAs on that interface but may send and receive Type-7 LSAs. Therefore, if the N-bit is set in the options field, the E-bit must be clear." If the E-bit isn't cleared on an NSSA ABR, that will cause hello packets to be dropped (due to parameters mismatch), which will prevent the ABR from forming adjacencies with others routers in the NSSA area. This problem didn't affect the existing NSSA topotest by chance of luck. In that topotest, in the NSSA ABR, the NSSA area is configured before any interface is associated to it. That caused ospf6_check_and_set_router_abr() to return false, leading to the unsetting of the E-bit. With this fix, the order in which areas/interfaces are configured shouldn't matter because the E-bit will always be unset on NSSA areas. Signed-off-by: Renato Westphal --- ospf6d/ospf6_nssa.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ospf6d/ospf6_nssa.c b/ospf6d/ospf6_nssa.c index 470a5b1338..636a77c39d 100644 --- a/ospf6d/ospf6_nssa.c +++ b/ospf6d/ospf6_nssa.c @@ -1203,8 +1203,7 @@ static void ospf6_check_and_originate_type7_lsa(struct ospf6_area *area) static void ospf6_area_nssa_update(struct ospf6_area *area) { if (IS_AREA_NSSA(area)) { - if (!ospf6_check_and_set_router_abr(area->ospf6)) - OSPF6_OPT_CLEAR(area->options, OSPF6_OPT_E); + OSPF6_OPT_CLEAR(area->options, OSPF6_OPT_E); area->ospf6->anyNSSA++; OSPF6_OPT_SET(area->options, OSPF6_OPT_N); area->NSSATranslatorRole = OSPF6_NSSA_ROLE_CANDIDATE; @@ -1212,8 +1211,7 @@ static void ospf6_area_nssa_update(struct ospf6_area *area) if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER)) zlog_debug("Normal area for if %s", area->name); OSPF6_OPT_CLEAR(area->options, OSPF6_OPT_N); - if (ospf6_check_and_set_router_abr(area->ospf6)) - OSPF6_OPT_SET(area->options, OSPF6_OPT_E); + OSPF6_OPT_SET(area->options, OSPF6_OPT_E); area->ospf6->anyNSSA--; area->NSSATranslatorState = OSPF6_NSSA_TRANSLATE_DISABLED; } From bb257321b21904cdb8a86f01476d8a07b8059b07 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 18 Aug 2021 17:59:40 -0300 Subject: [PATCH 2/9] ospf6d: don't delete area when NSSA is unconfigured Once NSSA is unconfigured, the OSPF area should still be operational as a normal area instead of being deleted. Signed-off-by: Renato Westphal --- ospf6d/ospf6_nssa.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ospf6d/ospf6_nssa.c b/ospf6d/ospf6_nssa.c index 636a77c39d..ccba78b7c5 100644 --- a/ospf6d/ospf6_nssa.c +++ b/ospf6d/ospf6_nssa.c @@ -1238,8 +1238,6 @@ static void ospf6_area_nssa_update(struct ospf6_area *area) if (IS_OSPF6_DEBUG_NSSA) zlog_debug("Normal area %s", area->name); ospf6_nssa_flush_area(area); - ospf6_area_disable(area); - ospf6_area_delete(area); } } From ccfffce4a06cf4cc7f50a33dbe5313edc8cf9d60 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 18 Aug 2021 17:59:58 -0300 Subject: [PATCH 3/9] ospf6d: fix flushing of all LSAs when NSSA is unconfigured Once NSSA is unconfigured on an area, all self-originated Type-7 LSAs need to be flushed. The existing code was iterating over the LSDB in the wrong way, causing ospf6_nssa_flush_area() to flush LSAs of all types. Use the ALL_LSDB_TYPED_ADVRTR macro to perform the intended iteration correctly. Signed-off-by: Renato Westphal --- ospf6d/ospf6_nssa.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ospf6d/ospf6_nssa.c b/ospf6d/ospf6_nssa.c index ccba78b7c5..7782dd8774 100644 --- a/ospf6d/ospf6_nssa.c +++ b/ospf6d/ospf6_nssa.c @@ -1130,18 +1130,17 @@ static void ospf6_nssa_flush_area(struct ospf6_area *area) uint16_t type; struct ospf6_lsa *lsa = NULL, *type5 = NULL; struct ospf6 *ospf6 = area->ospf6; - const struct route_node *rt = NULL; if (IS_OSPF6_DEBUG_NSSA) zlog_debug("%s: area %s", __func__, area->name); /* Flush the NSSA LSA */ type = htons(OSPF6_LSTYPE_TYPE_7); - rt = ospf6_lsdb_head(area->lsdb_self, 0, type, ospf6->router_id, &lsa); - while (lsa) { + for (ALL_LSDB_TYPED_ADVRTR(area->lsdb, type, ospf6->router_id, lsa)) { lsa->header->age = htons(OSPF_LSA_MAXAGE); SET_FLAG(lsa->flag, OSPF6_LSA_FLUSH); ospf6_flood(NULL, lsa); + /* Flush the translated LSA */ if (ospf6_check_and_set_router_abr(ospf6)) { type = htons(OSPF6_LSTYPE_AS_EXTERNAL); @@ -1155,7 +1154,6 @@ static void ospf6_nssa_flush_area(struct ospf6_area *area) ospf6_flood(NULL, type5); } } - lsa = ospf6_lsdb_next(rt, lsa); } } From dd551b9d1f78b5856d9b6fbc5abfa5e1d31d2775 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 18 Aug 2021 18:40:07 -0300 Subject: [PATCH 4/9] ospf6d: flush external LSAs when NSSA is configured Signed-off-by: Renato Westphal --- ospf6d/ospf6_asbr.c | 4 ++-- ospf6d/ospf6_nssa.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 2b11d89a31..92f9f06942 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -1307,9 +1307,9 @@ void ospf6_asbr_remove_externals_from_area(struct ospf6_area *oa) struct ospf6 *ospf6 = oa->ospf6; const struct route_node *iterend; - /* skip if router is in other non-stub areas */ + /* skip if router is in other non-stub/non-NSSA areas */ for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, area)) - if (!IS_AREA_STUB(area)) + if (!IS_AREA_STUB(area) && !IS_AREA_NSSA(area)) return; /* if router is only in a stub area then purge AS-External LSAs */ diff --git a/ospf6d/ospf6_nssa.c b/ospf6d/ospf6_nssa.c index 7782dd8774..cda92054a2 100644 --- a/ospf6d/ospf6_nssa.c +++ b/ospf6d/ospf6_nssa.c @@ -1218,6 +1218,9 @@ static void ospf6_area_nssa_update(struct ospf6_area *area) if (IS_AREA_NSSA(area)) { OSPF6_ROUTER_LSA_SCHEDULE(area); + /* Flush external LSAs. */ + ospf6_asbr_remove_externals_from_area(area); + /* Check if router is ABR */ if (ospf6_check_and_set_router_abr(area->ospf6)) { if (IS_OSPF6_DEBUG_NSSA) From 6df89791ba287a81c947dfb9fbdcd1c4a51db89b Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 18 Aug 2021 21:38:18 -0300 Subject: [PATCH 5/9] ospf6d: remove incorrect debug guard Also, update the ospf6_topo2 topotest since the expected output was wrong. With this fix, NSSA routes will be created on r2 ("redistribute connected"), and NSSA routes appear in the routing table as regular external routes. Signed-off-by: Renato Westphal --- ospf6d/ospf6_spf.c | 9 +++------ tests/topotests/ospf6_topo2/test_ospf6_topo2.py | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 4e7a7146eb..1412298802 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -1250,12 +1250,9 @@ static int ospf6_ase_calculate_timer(struct thread *t) 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); - } + type = htons(OSPF6_LSTYPE_TYPE_7); + for (ALL_LSDB_TYPED(area->lsdb, type, lsa)) + ospf6_ase_calculate_route(ospf6, lsa, area); } } return 0; diff --git a/tests/topotests/ospf6_topo2/test_ospf6_topo2.py b/tests/topotests/ospf6_topo2/test_ospf6_topo2.py index 0fe5228ce6..b6c8cf3e75 100644 --- a/tests/topotests/ospf6_topo2/test_ospf6_topo2.py +++ b/tests/topotests/ospf6_topo2/test_ospf6_topo2.py @@ -199,7 +199,7 @@ def test_ospfv3_expected_route_types(): { "numberOfIntraAreaRoutes": 1, "numberOfInterAreaRoutes": 2, - "numberOfExternal1Routes": 0, + "numberOfExternal1Routes": 4, "numberOfExternal2Routes": 0, }, ) From 9142948e39f331231d05e68306c94a51db36c820 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 18 Aug 2021 23:07:10 -0300 Subject: [PATCH 6/9] ospf6d: fix logging of border router routes The prefix of routes to border routers consists of two pieces of information embedded in a single struct (prefix.u.lp): struct prefix { uint8_t family; uint16_t prefixlen; union { [snip] struct { struct in_addr id; struct in_addr adv_router; } lp; } u __attribute__((aligned(8))); }; As such, using prefix2str() (or the %pFX format specifier) isn't correct when logging such routes. This commit adds a few special cases here and there to handle OSPF6_DEST_TYPE_ROUTER routes differently. It'd probably be a good idea to add a helper function to handle all cases in a single place, but that can be left for a second moment. Signed-off-by: Renato Westphal --- ospf6d/ospf6_abr.c | 30 +++++++++++++++++++++++++----- ospf6d/ospf6_route.c | 6 ++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index 69be807c13..650262f1ae 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -172,9 +172,19 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, uint16_t type; int is_debug = 0; - if (IS_OSPF6_DEBUG_ABR) - zlog_debug("%s : start area %s, route %pFX", __func__, - area->name, &route->prefix); + if (IS_OSPF6_DEBUG_ABR) { + char buf[BUFSIZ]; + + if (route->type == OSPF6_DEST_TYPE_ROUTER) + inet_ntop(AF_INET, + &ADV_ROUTER_IN_PREFIX(&route->prefix), buf, + sizeof(buf)); + else + prefix2str(&route->prefix, buf, sizeof(buf)); + + zlog_debug("%s : start area %s, route %s", __func__, area->name, + buf); + } if (route->type == OSPF6_DEST_TYPE_ROUTER) summary_table = area->summary_router; @@ -684,8 +694,18 @@ void ospf6_abr_originate_summary(struct ospf6_route *route, struct ospf6 *ospf6) struct ospf6_area *oa; struct ospf6_route *range = NULL; - if (IS_OSPF6_DEBUG_ABR) - zlog_debug("%s: route %pFX", __func__, &route->prefix); + if (IS_OSPF6_DEBUG_ABR) { + char buf[BUFSIZ]; + + if (route->type == OSPF6_DEST_TYPE_ROUTER) + inet_ntop(AF_INET, + &ADV_ROUTER_IN_PREFIX(&route->prefix), buf, + sizeof(buf)); + else + prefix2str(&route->prefix, buf, sizeof(buf)); + + zlog_debug("%s: route %s", __func__, buf); + } if (route->type == OSPF6_DEST_TYPE_NETWORK) { oa = ospf6_area_lookup(route->path.area_id, ospf6); diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index cd3139d28a..13003b4151 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -667,6 +667,9 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route, if (route->type == OSPF6_DEST_TYPE_LINKSTATE) ospf6_linkstate_prefix2str(&route->prefix, buf, sizeof(buf)); + else if (route->type == OSPF6_DEST_TYPE_ROUTER) + inet_ntop(AF_INET, &ADV_ROUTER_IN_PREFIX(&route->prefix), buf, + sizeof(buf)); else prefix2str(&route->prefix, buf, sizeof(buf)); @@ -899,6 +902,9 @@ void ospf6_route_remove(struct ospf6_route *route, if (route->type == OSPF6_DEST_TYPE_LINKSTATE) ospf6_linkstate_prefix2str(&route->prefix, buf, sizeof(buf)); + else if (route->type == OSPF6_DEST_TYPE_ROUTER) + inet_ntop(AF_INET, &ADV_ROUTER_IN_PREFIX(&route->prefix), buf, + sizeof(buf)); else prefix2str(&route->prefix, buf, sizeof(buf)); From 0c293b92eeefeb37203fb0e8565c77a77fc189b0 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 19 Aug 2021 12:14:47 -0300 Subject: [PATCH 7/9] ospf6d: do not allow an area to be stub and NSSA at the same time That should not be allowed under any circumstance. Signed-off-by: Renato Westphal --- ospf6d/ospf6_area.c | 7 ++++++- ospf6d/ospf6_area.h | 1 + ospf6d/ospf6_nssa.c | 5 ++++- ospf6d/ospf6_nssa.h | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 0f1f061225..098132b1f6 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -189,6 +189,9 @@ static void ospf6_area_stub_update(struct ospf6_area *area) static int ospf6_area_stub_set(struct ospf6 *ospf6, struct ospf6_area *area) { if (!IS_AREA_STUB(area)) { + /* Disable NSSA first. */ + ospf6_area_nssa_unset(ospf6, area); + SET_FLAG(area->flag, OSPF6_AREA_STUB); ospf6_area_stub_update(area); } @@ -196,7 +199,7 @@ static int ospf6_area_stub_set(struct ospf6 *ospf6, struct ospf6_area *area) return 1; } -static void ospf6_area_stub_unset(struct ospf6 *ospf6, struct ospf6_area *area) +void ospf6_area_stub_unset(struct ospf6 *ospf6, struct ospf6_area *area) { if (IS_AREA_STUB(area)) { UNSET_FLAG(area->flag, OSPF6_AREA_STUB); @@ -1266,6 +1269,8 @@ DEFUN(ospf6_area_nssa, ospf6_area_nssa_cmd, return CMD_WARNING_CONFIG_FAILED; } + ospf6_area_no_summary_unset(ospf6, area); + return CMD_SUCCESS; } diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h index dd4d019015..b2a275d745 100644 --- a/ospf6d/ospf6_area.h +++ b/ospf6d/ospf6_area.h @@ -154,6 +154,7 @@ extern void ospf6_area_delete(struct ospf6_area *); extern struct ospf6_area *ospf6_area_lookup(uint32_t, struct ospf6 *); extern struct ospf6_area *ospf6_area_lookup_by_area_id(uint32_t area_id); +extern void ospf6_area_stub_unset(struct ospf6 *ospf6, struct ospf6_area *area); extern void ospf6_area_enable(struct ospf6_area *); extern void ospf6_area_disable(struct ospf6_area *); diff --git a/ospf6d/ospf6_nssa.c b/ospf6d/ospf6_nssa.c index cda92054a2..10b7d2d9f6 100644 --- a/ospf6d/ospf6_nssa.c +++ b/ospf6d/ospf6_nssa.c @@ -1198,7 +1198,7 @@ static void ospf6_check_and_originate_type7_lsa(struct ospf6_area *area) } -static void ospf6_area_nssa_update(struct ospf6_area *area) +void ospf6_area_nssa_update(struct ospf6_area *area) { if (IS_AREA_NSSA(area)) { OSPF6_OPT_CLEAR(area->options, OSPF6_OPT_E); @@ -1246,6 +1246,9 @@ int ospf6_area_nssa_set(struct ospf6 *ospf6, struct ospf6_area *area) { if (!IS_AREA_NSSA(area)) { + /* Disable stub first. */ + ospf6_area_stub_unset(ospf6, area); + SET_FLAG(area->flag, OSPF6_AREA_NSSA); if (IS_OSPF6_DEBUG_NSSA) zlog_debug("area %s nssa set", area->name); diff --git a/ospf6d/ospf6_nssa.h b/ospf6d/ospf6_nssa.h index a171d76d44..454bdd7fe2 100644 --- a/ospf6d/ospf6_nssa.h +++ b/ospf6d/ospf6_nssa.h @@ -61,6 +61,7 @@ extern struct ospf6_lsa *ospf6_translated_nssa_originate(struct ospf6_area *, extern void ospf6_asbr_nssa_redist_task(struct ospf6 *ospf6); extern void ospf6_schedule_abr_task(struct ospf6 *ospf6); +extern void ospf6_area_nssa_update(struct ospf6_area *area); void ospf6_asbr_prefix_readvertise(struct ospf6 *ospf6); extern void ospf6_nssa_lsa_originate(struct ospf6_route *route, struct ospf6_area *area); From 6c4892c08367a68631fc94c2edd2dc0f924c036c Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 21 Aug 2021 18:45:22 -0300 Subject: [PATCH 8/9] tests: enable more debugs in the ospf6_topo2 topotest Enable more debugs to facilitate troubleshooting whenever a problem happens. Signed-off-by: Renato Westphal --- tests/topotests/ospf6_topo2/r1/ospf6d.conf | 25 ++++++++++++++++++++++ tests/topotests/ospf6_topo2/r2/ospf6d.conf | 25 ++++++++++++++++++++++ tests/topotests/ospf6_topo2/r3/ospf6d.conf | 25 ++++++++++++++++++++++ tests/topotests/ospf6_topo2/r4/ospf6d.conf | 25 ++++++++++++++++++++++ 4 files changed, 100 insertions(+) diff --git a/tests/topotests/ospf6_topo2/r1/ospf6d.conf b/tests/topotests/ospf6_topo2/r1/ospf6d.conf index c403fcd8dc..2e465e6d1f 100644 --- a/tests/topotests/ospf6_topo2/r1/ospf6d.conf +++ b/tests/topotests/ospf6_topo2/r1/ospf6d.conf @@ -1,3 +1,28 @@ +debug ospf6 lsa router +debug ospf6 lsa router originate +debug ospf6 lsa router examine +debug ospf6 lsa router flooding +debug ospf6 lsa as-external +debug ospf6 lsa as-external originate +debug ospf6 lsa as-external examine +debug ospf6 lsa as-external flooding +debug ospf6 lsa intra-prefix +debug ospf6 lsa intra-prefix originate +debug ospf6 lsa intra-prefix examine +debug ospf6 lsa intra-prefix flooding +debug ospf6 border-routers +debug ospf6 zebra +debug ospf6 interface +debug ospf6 neighbor +debug ospf6 flooding +debug ospf6 gr helper +debug ospf6 spf process +debug ospf6 route intra-area +debug ospf6 route inter-area +debug ospf6 abr +debug ospf6 asbr +debug ospf6 nssa +! interface r1-eth0 ipv6 ospf6 hello-interval 2 ipv6 ospf6 dead-interval 10 diff --git a/tests/topotests/ospf6_topo2/r2/ospf6d.conf b/tests/topotests/ospf6_topo2/r2/ospf6d.conf index e88e965c78..4a1d10693d 100644 --- a/tests/topotests/ospf6_topo2/r2/ospf6d.conf +++ b/tests/topotests/ospf6_topo2/r2/ospf6d.conf @@ -1,3 +1,28 @@ +debug ospf6 lsa router +debug ospf6 lsa router originate +debug ospf6 lsa router examine +debug ospf6 lsa router flooding +debug ospf6 lsa as-external +debug ospf6 lsa as-external originate +debug ospf6 lsa as-external examine +debug ospf6 lsa as-external flooding +debug ospf6 lsa intra-prefix +debug ospf6 lsa intra-prefix originate +debug ospf6 lsa intra-prefix examine +debug ospf6 lsa intra-prefix flooding +debug ospf6 border-routers +debug ospf6 zebra +debug ospf6 interface +debug ospf6 neighbor +debug ospf6 flooding +debug ospf6 gr helper +debug ospf6 spf process +debug ospf6 route intra-area +debug ospf6 route inter-area +debug ospf6 abr +debug ospf6 asbr +debug ospf6 nssa +! interface r2-eth0 ipv6 ospf6 hello-interval 2 ipv6 ospf6 dead-interval 10 diff --git a/tests/topotests/ospf6_topo2/r3/ospf6d.conf b/tests/topotests/ospf6_topo2/r3/ospf6d.conf index aaef00d5bb..5faeb70e56 100644 --- a/tests/topotests/ospf6_topo2/r3/ospf6d.conf +++ b/tests/topotests/ospf6_topo2/r3/ospf6d.conf @@ -1,3 +1,28 @@ +debug ospf6 lsa router +debug ospf6 lsa router originate +debug ospf6 lsa router examine +debug ospf6 lsa router flooding +debug ospf6 lsa as-external +debug ospf6 lsa as-external originate +debug ospf6 lsa as-external examine +debug ospf6 lsa as-external flooding +debug ospf6 lsa intra-prefix +debug ospf6 lsa intra-prefix originate +debug ospf6 lsa intra-prefix examine +debug ospf6 lsa intra-prefix flooding +debug ospf6 border-routers +debug ospf6 zebra +debug ospf6 interface +debug ospf6 neighbor +debug ospf6 flooding +debug ospf6 gr helper +debug ospf6 spf process +debug ospf6 route intra-area +debug ospf6 route inter-area +debug ospf6 abr +debug ospf6 asbr +debug ospf6 nssa +! interface r3-eth0 ipv6 ospf6 hello-interval 2 ipv6 ospf6 dead-interval 10 diff --git a/tests/topotests/ospf6_topo2/r4/ospf6d.conf b/tests/topotests/ospf6_topo2/r4/ospf6d.conf index 813c0abff2..04d763f6a8 100644 --- a/tests/topotests/ospf6_topo2/r4/ospf6d.conf +++ b/tests/topotests/ospf6_topo2/r4/ospf6d.conf @@ -1,3 +1,28 @@ +debug ospf6 lsa router +debug ospf6 lsa router originate +debug ospf6 lsa router examine +debug ospf6 lsa router flooding +debug ospf6 lsa as-external +debug ospf6 lsa as-external originate +debug ospf6 lsa as-external examine +debug ospf6 lsa as-external flooding +debug ospf6 lsa intra-prefix +debug ospf6 lsa intra-prefix originate +debug ospf6 lsa intra-prefix examine +debug ospf6 lsa intra-prefix flooding +debug ospf6 border-routers +debug ospf6 zebra +debug ospf6 interface +debug ospf6 neighbor +debug ospf6 flooding +debug ospf6 gr helper +debug ospf6 spf process +debug ospf6 route intra-area +debug ospf6 route inter-area +debug ospf6 abr +debug ospf6 asbr +debug ospf6 nssa +! interface r4-eth0 ipv6 ospf6 hello-interval 2 ipv6 ospf6 dead-interval 10 From aea082d5788beea758113797e41ef7152470ca2f Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Mon, 23 Aug 2021 18:22:20 -0300 Subject: [PATCH 9/9] ospf6d: further validate NSSA ASBR routes used for route computation Add missing sanity check specified in the NSSA RFC. Signed-off-by: Renato Westphal --- ospf6d/ospf6_asbr.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 92f9f06942..acecf90023 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -570,6 +570,22 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa) &asbr_id); return; } + + /* + * RFC 3101 - Section 2.5: + * "For a Type-7 LSA the matching routing table entry must + * specify an intra-area path through the LSA's originating + * NSSA". + */ + if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7 + && (asbr_entry->path.area_id != oa->area_id + || asbr_entry->path.type != OSPF6_PATH_TYPE_INTRA)) { + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) + zlog_debug( + "Intra-area route to NSSA ASBR not found: %pFX", + &asbr_id); + return; + } } /* Check the forwarding address */