]> git.proxmox.com Git - mirror_frr.git/commitdiff
ospf6d: fix loop in ABRs
authorChirag Shah <chirag@cumulusnetworks.com>
Tue, 27 Mar 2018 22:28:14 +0000 (15:28 -0700)
committerChirag Shah <chirag@cumulusnetworks.com>
Thu, 29 Mar 2018 17:13:32 +0000 (10:13 -0700)
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>
ospf6d/ospf6_abr.c
ospf6d/ospf6_intra.c
ospf6d/ospf6_route.c

index 163f2dbffd489fb4c3330ba30791fd91421549ce..01b8055b6609b154f1bf4c670f4b0d9ed40770df 100644 (file)
@@ -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
index 1872c6bd361229defd0c2377d10e6e98ddfc6142..581a899bcd529f9382761d06af3ff7d8eca7edde 100644 (file)
@@ -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)) {
index 4d436792dc0a7f105962cf259fe669e05a132d5c..67b9b9df969cb5c82457c8abf2b9e43aca0e97df 100644 (file)
@@ -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;
 }