From 64f46c22682fd4cc74084fedc0062985d1459c86 Mon Sep 17 00:00:00 2001 From: rgirada Date: Mon, 25 May 2020 10:20:41 -0700 Subject: [PATCH] ospfd: External LSA lookup in LSDB failed in a specific scenario MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- ospfd/ospf_asbr.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index 3682b4cdd3..1480b0e391 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -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; } -- 2.39.5