Merge pull request #2173 from chiragshah6/ospfv3_dev

ospf6d: fix area border router duplicate
This commit is contained in:
Russ White 2018-05-08 20:03:48 -04:00 committed by GitHub
commit bf16dbf1de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 33 deletions

View File

@ -684,7 +684,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
{
struct prefix prefix, abr_prefix;
struct ospf6_route_table *table = NULL;
struct ospf6_route *range, *route, *old = NULL;
struct ospf6_route *range, *route, *old = NULL, *old_route;
struct ospf6_route *abr_entry;
uint8_t type = 0;
char options[3] = {0, 0, 0};
@ -695,14 +695,15 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
int is_debug = 0;
struct ospf6_inter_prefix_lsa *prefix_lsa = NULL;
struct ospf6_inter_router_lsa *router_lsa = NULL;
struct ospf6_path *path;
bool old_entry_updated = false;
memset(&prefix, 0, sizeof(prefix));
if (lsa->header->type == htons(OSPF6_LSTYPE_INTER_PREFIX)) {
if (IS_OSPF6_DEBUG_EXAMIN(INTER_PREFIX)) {
is_debug++;
zlog_debug("Examin %s in area %s", lsa->name, oa->name);
zlog_debug("%s: Examin %s in area %s",
__PRETTY_FUNCTION__, lsa->name, oa->name);
}
prefix_lsa =
@ -720,7 +721,8 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
} else if (lsa->header->type == htons(OSPF6_LSTYPE_INTER_ROUTER)) {
if (IS_OSPF6_DEBUG_EXAMIN(INTER_ROUTER)) {
is_debug++;
zlog_debug("Examin %s in area %s", lsa->name, oa->name);
zlog_debug("%s: Examin %s in area %s",
__PRETTY_FUNCTION__, lsa->name, oa->name);
}
router_lsa =
@ -768,7 +770,8 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
}
if (OSPF6_LSA_IS_MAXAGE(lsa)) {
if (is_debug)
zlog_debug("LSA is MaxAge, ignore");
zlog_debug("%s: LSA %s is MaxAge, ignore",
__PRETTY_FUNCTION__, lsa->name);
if (old)
ospf6_route_remove(old, table);
return;
@ -845,9 +848,24 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
|| CHECK_FLAG(abr_entry->flag, OSPF6_ROUTE_REMOVE)
|| !CHECK_FLAG(abr_entry->path.router_bits, OSPF6_ROUTER_BIT_B)) {
if (is_debug)
zlog_debug("ABR router entry does not exist, ignore");
if (old)
ospf6_route_remove(old, table);
zlog_debug("%s: ABR router entry does not exist, ignore",
__PRETTY_FUNCTION__);
if (old) {
if (old->type == OSPF6_DEST_TYPE_ROUTER &&
oa->intra_brouter_calc) {
if (is_debug)
zlog_debug(
"%s: intra_brouter_calc is on, skip brouter remove: %s (%p)",
__PRETTY_FUNCTION__, buf,
(void *)old);
} else {
if (is_debug)
zlog_debug("%s: remove old entry: %s %p ",
__PRETTY_FUNCTION__, buf,
(void *)old);
ospf6_route_remove(old, table);
}
}
return;
}
@ -902,11 +920,11 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
route->path.type = OSPF6_PATH_TYPE_INTER;
route->path.cost = abr_entry->path.cost + cost;
ospf6_route_copy_nexthops(route, abr_entry);
path = ospf6_path_dup(&route->path);
ospf6_copy_nexthops(path->nh_list, abr_entry->nh_list);
listnode_add_sort(route->paths, path);
/* Inter abr_entry is same as brouter.
* Avoid duplicate nexthops to brouter and its
* learnt route. i.e. use merge nexthops.
*/
ospf6_route_merge_nexthops(route, abr_entry);
/* (7) If the routes are identical, copy the next hops over to existing
route. ospf6's route table implementation will otherwise string both
@ -915,11 +933,28 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
*/
old = ospf6_route_lookup(&prefix, table);
if (old && (ospf6_route_cmp(route, old) == 0)) {
ospf6_route_merge_nexthops(old, route);
for (old_route = old; old_route; old_route = old_route->next) {
if (!ospf6_route_is_same(old_route, route) ||
(old_route->type != route->type) ||
(old_route->path.type != route->path.type))
continue;
if ((ospf6_route_cmp(route, old_route) != 0)) {
if (is_debug) {
prefix2str(&prefix, buf, sizeof(buf));
zlog_debug("%s: old %p %s cost %u new route cost %u are not same",
__PRETTY_FUNCTION__,
(void *)old_route, buf,
old_route->path.cost,
route->path.cost);
}
continue;
}
old_entry_updated = true;
ospf6_route_merge_nexthops(old, route);
if (is_debug)
zlog_debug("%s: Update route: %s old cost %u new cost %u nh count %u",
zlog_debug("%s: Update route: %s old cost %u new cost %u nh %u",
__PRETTY_FUNCTION__,
buf, old->path.cost, route->path.cost,
listcount(route->nh_list));
@ -930,9 +965,12 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
/* Delete new route */
ospf6_route_delete(route);
} else {
break;
}
if (old_entry_updated == false) {
if (is_debug)
zlog_debug("%s: Install route: %s cost %u nh count %u",
zlog_debug("%s: Install route: %s cost %u nh %u",
__PRETTY_FUNCTION__, buf, route->path.cost,
listcount(route->nh_list));
/* ospf6_ia_add_nw_route (table, &prefix, route); */

View File

@ -50,6 +50,9 @@ struct ospf6_area {
/* Area type */
int no_summary;
/* Brouter traversal protection */
int intra_brouter_calc;
/* OSPF interface list */
struct list *if_list;

View File

@ -2047,8 +2047,10 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
uint32_t brouter_id;
char brouter_name[16];
if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(oa->area_id))
zlog_info("border-router calculation for area %s", oa->name);
if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(oa->area_id) ||
IS_OSPF6_DEBUG_ROUTE(MEMORY))
zlog_info("%s: border-router calculation for area %s",
__PRETTY_FUNCTION__, oa->name);
hook_add = oa->ospf6->brouter_table->hook_add;
hook_remove = oa->ospf6->brouter_table->hook_remove;
@ -2114,6 +2116,7 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
for (brouter = ospf6_route_head(oa->ospf6->brouter_table); brouter;
brouter = nbrouter) {
/*
* brouter may have been "deleted" in the last loop iteration.
* If this is the case there is still 1 final refcount lock
@ -2122,6 +2125,8 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
* skip processing the deleted route.
*/
if (brouter->lock == 1) {
if (IS_OSPF6_DEBUG_ROUTE(MEMORY))
ospf6_brouter_debug_print(brouter);
nbrouter = ospf6_route_next(brouter);
continue;
} else {
@ -2173,8 +2178,14 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
brouter_id)
|| IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(
oa->area_id))
zlog_info("brouter %s disappears via area %s",
brouter_name, oa->name);
zlog_info("%s: brouter %s disappears via area %s",
__PRETTY_FUNCTION__, brouter_name,
oa->name);
/* This is used to protect nbrouter from removed from
* the table. For an example, ospf6_abr_examin_summary,
* removes brouters which are marked for remove.
*/
oa->intra_brouter_calc = 1;
ospf6_route_remove(brouter, oa->ospf6->brouter_table);
brouter = NULL;
} else if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_ADD)
@ -2184,8 +2195,9 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
brouter_id)
|| IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(
oa->area_id))
zlog_info("brouter %s appears via area %s",
brouter_name, oa->name);
zlog_info("%s: brouter %s appears via area %s",
__PRETTY_FUNCTION__, brouter_name,
oa->name);
/* newly added */
if (hook_add)
@ -2205,11 +2217,14 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
UNSET_FLAG(brouter->flag, OSPF6_ROUTE_ADD);
UNSET_FLAG(brouter->flag, OSPF6_ROUTE_CHANGE);
}
/* Reset for nbrouter */
oa->intra_brouter_calc = 0;
}
if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(oa->area_id))
zlog_info("border-router calculation for area %s: done",
oa->name);
if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(oa->area_id) ||
IS_OSPF6_DEBUG_ROUTE(MEMORY))
zlog_info("%s: border-router calculation for area %s: done",
__PRETTY_FUNCTION__, oa->name);
}
struct ospf6_lsa_handler router_handler = {.lh_type = OSPF6_LSTYPE_ROUTER,

View File

@ -925,10 +925,11 @@ struct ospf6_route *ospf6_route_next(struct ospf6_route *route)
struct ospf6_route *next = route->next;
if (IS_OSPF6_DEBUG_ROUTE(MEMORY))
zlog_info("%s %p: route next: %p<-[%p]->%p",
zlog_info("%s %p: route next: %p<-[%p]->%p , route ref count %u",
ospf6_route_table_name(route->table),
(void *)route->table, (void *)route->prev,
(void *)route, (void *)route->next);
(void *)route, (void *)route->next,
route->lock);
ospf6_route_unlock(route);
if (next)

View File

@ -97,7 +97,8 @@ static void ospf6_top_route_hook_remove(struct ospf6_route *route)
static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
{
if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
IS_OSPF6_DEBUG_BROUTER) {
uint32_t brouter_id;
char brouter_name[16];
@ -116,15 +117,17 @@ static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
{
if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
IS_OSPF6_DEBUG_BROUTER) {
uint32_t brouter_id;
char brouter_name[16];
brouter_id = ADV_ROUTER_IN_PREFIX(&route->prefix);
inet_ntop(AF_INET, &brouter_id, brouter_name,
sizeof(brouter_name));
zlog_debug("%s: brouter %s del with nh count %u",
__PRETTY_FUNCTION__, brouter_name,
zlog_debug("%s: brouter %p %s del with adv router %x nh %u",
__PRETTY_FUNCTION__, (void *)route, brouter_name,
route->path.origin.adv_router,
listcount(route->nh_list));
}
route->flag |= OSPF6_ROUTE_REMOVE;