diff options
| -rw-r--r-- | ospf6d/ospf6_abr.c | 30 | ||||
| -rw-r--r-- | ospf6d/ospf6_area.c | 7 | ||||
| -rw-r--r-- | ospf6d/ospf6_area.h | 1 | ||||
| -rw-r--r-- | ospf6d/ospf6_asbr.c | 20 | ||||
| -rw-r--r-- | ospf6d/ospf6_nssa.c | 22 | ||||
| -rw-r--r-- | ospf6d/ospf6_nssa.h | 1 | ||||
| -rw-r--r-- | ospf6d/ospf6_route.c | 6 | ||||
| -rw-r--r-- | ospf6d/ospf6_spf.c | 9 | ||||
| -rw-r--r-- | tests/topotests/ospf6_topo2/r1/ospf6d.conf | 25 | ||||
| -rw-r--r-- | tests/topotests/ospf6_topo2/r2/ospf6d.conf | 25 | ||||
| -rw-r--r-- | tests/topotests/ospf6_topo2/r3/ospf6d.conf | 25 | ||||
| -rw-r--r-- | tests/topotests/ospf6_topo2/r4/ospf6d.conf | 25 | ||||
| -rw-r--r-- | tests/topotests/ospf6_topo2/test_ospf6_topo2.py | 2 |
13 files changed, 172 insertions, 26 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_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_asbr.c b/ospf6d/ospf6_asbr.c index 2b11d89a31..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 */ @@ -1307,9 +1323,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 470a5b1338..10b7d2d9f6 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); } } @@ -1200,11 +1198,10 @@ 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)) { - 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 +1209,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; } @@ -1222,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) @@ -1240,8 +1239,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); } } @@ -1249,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); 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)); 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/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 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, }, ) |
