summaryrefslogtreecommitdiffstats
path: root/ospf6d
diff options
context:
space:
mode:
authorChirag Shah <chirag@cumulusnetworks.com>2018-03-28 00:28:14 +0200
committerChirag Shah <chirag@cumulusnetworks.com>2018-03-29 19:13:32 +0200
commit10efbdc2eb546571140eb412b5d0e6ffc3805b6a (patch)
treefa07051b8e850e9a187314fe47e36249cbdb0e1b /ospf6d
parentMerge pull request #1985 from sfionov/fpm_pb_optional_scalar (diff)
downloadfrr-10efbdc2eb546571140eb412b5d0e6ffc3805b6a.tar.xz
frr-10efbdc2eb546571140eb412b5d0e6ffc3805b6a.zip
ospf6d: fix loop in ABRs
When two routers from same area connected to backbone, intra route advertised from area x should take precedence within area x. The same route would be injected as summary lsa to area 0/y. The same LSA via second abr injected back to area x and since area 0 is lower than area x its route take precedence. Move the area check below path type and cost as both are crucial to determine best route. Ticket:CM-19627 Testing Done: Initial route generated via area 1 as Intra-Prefix LSA (2009). R1 and R2 both re advertised Inter Area Prefix LSA (Summary LSA 2003) to area 1. With the change area 1 Intra route precedence is preserved. The address of H1 from Right is reachable via ping. area 1 | area 0 R1 / \ / \ / \ H1 --Left Right \ / \ / \ / R2 area 1 | area 0 Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Diffstat (limited to 'ospf6d')
-rw-r--r--ospf6d/ospf6_abr.c4
-rw-r--r--ospf6d/ospf6_intra.c11
-rw-r--r--ospf6d/ospf6_route.c6
3 files changed, 14 insertions, 7 deletions
diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c
index 163f2dbff..01b8055b6 100644
--- a/ospf6d/ospf6_abr.c
+++ b/ospf6d/ospf6_abr.c
@@ -695,6 +695,7 @@ 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;
memset(&prefix, 0, sizeof(prefix));
@@ -900,6 +901,9 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
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);
/* (7) If the routes are identical, copy the next hops over to existing
route. ospf6's route table implementation will otherwise string both
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index 1872c6bd3..581a899bc 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -1326,6 +1326,7 @@ void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa)
char buf[PREFIX2STR_BUFFER];
struct interface *ifp;
int direct_connect = 0;
+ struct ospf6_path *path;
if (OSPF6_LSA_IS_MAXAGE(lsa))
return;
@@ -1417,9 +1418,14 @@ void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa)
ospf6_route_copy_nexthops(route, ls_entry);
}
+ path = ospf6_path_dup(&route->path);
+ ospf6_copy_nexthops(path->nh_list, route->path.nh_list);
+ listnode_add_sort(route->paths, path);
+
if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) {
prefix2str(&route->prefix, buf, sizeof(buf));
- zlog_debug(" route %s add with nh count %u", buf,
+ zlog_debug(" route %s add with cost %u nh count %u",
+ buf, route->path.cost,
listcount(route->nh_list));
}
@@ -1735,9 +1741,6 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
&& CHECK_FLAG(brouter->flag, OSPF6_ROUTE_ADD)) {
UNSET_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE);
UNSET_FLAG(brouter->flag, OSPF6_ROUTE_ADD);
- zlog_debug("%s: EVENT unset REOUTE_REMOVE and ROUTE_ADD brouter %s",
- __PRETTY_FUNCTION__, brouter_name);
- ospf6_brouter_debug_print(brouter);
}
if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE)) {
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index 4d436792d..67b9b9df9 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -460,9 +460,6 @@ int ospf6_route_cmp(struct ospf6_route *ra, struct ospf6_route *rb)
if (ra->type != rb->type)
return (ra->type - rb->type);
- if (ra->path.area_id != rb->path.area_id)
- return (ntohl(ra->path.area_id) - ntohl(rb->path.area_id));
-
if (ra->path.type != rb->path.type)
return (ra->path.type - rb->path.type);
@@ -476,6 +473,9 @@ int ospf6_route_cmp(struct ospf6_route *ra, struct ospf6_route *rb)
return (ra->path.cost - rb->path.cost);
}
+ if (ra->path.area_id != rb->path.area_id)
+ return (ntohl(ra->path.area_id) - ntohl(rb->path.area_id));
+
return 0;
}