]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: External LSA lookup in LSDB failed in a specific scenario 6460/head
authorrgirada <rgirada@vmware.com>
Mon, 25 May 2020 17:20:41 +0000 (10:20 -0700)
committerrgirada <rgirada@vmware.com>
Fri, 29 May 2020 11:24:28 +0000 (04:24 -0700)
Description:
OSPF uses an algo to generate unique LSIDs when route updates
exists with same adrress and different masklens. It genearates
the unique LSIDs by masking its hostbits.
Ex :
Rt1 : 10.0.0.0/32 - LSID : 10.0.0.0
Rt2 : 10.0.0.0/16 - LSID : 10.0.255.255
Rt3 : 10.0.0.0/24 - LSID : 10.0.0.255

Observed an issue with external LSAs when such routes originated.
If the first route (with actual address as LSID) is got deleted,
the routes with same addresss(different msaks) are failed
to get LSA pointers  from LSDB due to current fetching API design.
api : ospf_external_info_find_lsa

Here , it is allowing to look up the LSA with address specific
unique LSID (address with host bits set ex: 10.0.255.255) only
if the LSA exists where LSID as actual address of the route
(ex: 10.0.0.0 ) which is not expected and cauing for other issues.

Fix:
Corrected this logic, by looking up the LSA with unique LSID first
if it doesn’t exist then It is allowing to look up the LSDB with LSID
as address of the route.

Signed-off-by: Rajesh Girada <rgirada@vmware.com>
ospfd/ospf_asbr.c

index 3682b4cdd3728fea77c0ed6d94eb0fd40c8f0f9b..1480b0e3914bbf6b0efeb4693450e05bb5064801 100644 (file)
@@ -213,25 +213,35 @@ struct ospf_lsa *ospf_external_info_find_lsa(struct ospf *ospf,
        struct as_external_lsa *al;
        struct in_addr mask, id;
 
-       lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
-                                    p->prefix, ospf->router_id);
-
-       if (!lsa)
-               return NULL;
-
-       al = (struct as_external_lsa *)lsa->data;
+       /* Fisrt search the lsdb with address specifc LSID
+        * where all the host bits are set, if there a matched
+        * LSA, return.
+        * Ex: For route 10.0.0.0/16, LSID is 10.0.255.255
+        * If no lsa with above LSID, use received address as
+        * LSID and check if any LSA in LSDB.
+        * If LSA found, check if the mask is same b/w the matched
+        * LSA and received prefix, if same then it is the LSA for
+        * this prefix.
+        * Ex: For route 10.0.0.0/16, LSID is 10.0.0.0
+        */
 
        masklen2ip(p->prefixlen, &mask);
+       id.s_addr = p->prefix.s_addr | (~mask.s_addr);
+       lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, OSPF_AS_EXTERNAL_LSA, id,
+                                    ospf->router_id);
+       if (lsa)
+               return lsa;
 
-       if (mask.s_addr != al->mask.s_addr) {
-               id.s_addr = p->prefix.s_addr | (~mask.s_addr);
-               lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
-                                            id, ospf->router_id);
-               if (!lsa)
-                       return NULL;
+       lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
+                                    p->prefix, ospf->router_id);
+
+       if (lsa) {
+               al = (struct as_external_lsa *)lsa->data;
+               if (mask.s_addr == al->mask.s_addr)
+                       return lsa;
        }
 
-       return lsa;
+       return NULL;
 }