summaryrefslogtreecommitdiffstats
path: root/ospfd/ospf_opaque.c
diff options
context:
space:
mode:
authorAcee <aceelindem@gmail.com>2023-11-27 14:13:03 +0100
committerAcee <aceelindem@gmail.com>2023-11-28 22:18:55 +0100
commit5993c4aef923700bd606c4d105da39a3c66523c3 (patch)
tree2124b0b5cbcc8ea60ee3539d7a048d26881fb5ed /ospfd/ospf_opaque.c
parentMerge pull request #14862 from louis-6wind/fix-ctx-iptable (diff)
downloadfrr-5993c4aef923700bd606c4d105da39a3c66523c3.tar.xz
frr-5993c4aef923700bd606c4d105da39a3c66523c3.zip
ospfd: Fix OSPF link-local opaque LSA crash and opaque memory corruption
1. When an OSPF interface is deleted, remove the references in link-local LSA. Delete the LSA from the LSDB so that the callback has accessibily to the interface prior to deletion. 2. Fix a double free for the opaque function table data structure. 3. Assure that the opaque per-type information and opaque function table structures are removed at the same time since they have back pointers to one another. 4. Add a topotest variation for the link-local opaque LSA crash. Signed-off-by: Acee <aceelindem@gmail.com>
Diffstat (limited to 'ospfd/ospf_opaque.c')
-rw-r--r--ospfd/ospf_opaque.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 27f47a6d7..86492c7b1 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -427,10 +427,12 @@ void ospf_delete_opaque_functab(uint8_t lsa_type, uint8_t opaque_type)
if (functab->oipt != NULL)
free_opaque_info_per_type(functab->oipt,
true);
- /* Dequeue listnode entry from the list. */
+ /* Dequeue listnode entry from the function table
+ * list coreesponding to the opaque LSA type.
+ * Note that the list deletion callback frees
+ * the functab entry memory.
+ */
listnode_delete(funclist, functab);
-
- XFREE(MTYPE_OSPF_OPAQUE_FUNCTAB, functab);
break;
}
}
@@ -614,6 +616,17 @@ static void free_opaque_info_per_type(struct opaque_info_per_type *oipt,
}
listnode_delete(l, oipt);
}
+
+ /*
+ * Delete the function table corresponding to the LSA type and opaque type
+ * as well. The pointer to the opaque per-type information structure in
+ * the function table structure be set to NULL to avoid recursion during
+ * deletion.
+ */
+ if (oipt->functab) {
+ oipt->functab->oipt = NULL;
+ ospf_delete_opaque_functab(oipt->lsa_type, oipt->opaque_type);
+ }
XFREE(MTYPE_OPAQUE_INFO_PER_TYPE, oipt);
return;
}
@@ -746,6 +759,44 @@ int ospf_opaque_is_owned(struct ospf_lsa *lsa)
return (oipt != NULL && lookup_opaque_info_by_id(oipt, lsa) != NULL);
}
+/*
+ * Cleanup Link-Local LSAs assocaited with an interface that is being deleted.
+ * Since these LSAs are stored in the area link state database (LSDB) as opposed
+ * to a separate per-interface, they must be deleted from the area database.
+ * Since their flooding scope is solely the deleted OSPF interface, there is no
+ * need to attempt to flush them from the routing domain. For link local LSAs
+ * originated via the OSPF server API, LSA deletion before interface deletion
+ * is required so that the callback can access the OSPF interface address.
+ */
+void ospf_opaque_type9_lsa_if_cleanup(struct ospf_interface *oi)
+{
+ struct route_node *rn;
+ struct ospf_lsdb *lsdb;
+ struct ospf_lsa *lsa;
+
+ lsdb = oi->area->lsdb;
+ LSDB_LOOP (OPAQUE_LINK_LSDB(oi->area), rn, lsa)
+ /*
+ * While the LSA shouldn't be referenced on any LSA
+ * lists since the flooding scoped is confined to the
+ * interface being deleted, clear the pointer to the
+ * deleted interface for safety's sake after it is
+ * removed from the area LSDB.
+ */
+ if (lsa->oi == oi) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("Delete Type-9 Opaque-LSA on interface delete: [opaque-type=%u, opaque-id=%x]",
+ GET_OPAQUE_TYPE(
+ ntohl(lsa->data->id.s_addr)),
+ GET_OPAQUE_ID(ntohl(
+ lsa->data->id.s_addr)));
+ ospf_lsa_lock(lsa);
+ ospf_lsdb_delete(lsdb, lsa);
+ lsa->oi = NULL;
+ ospf_lsa_unlock(&lsa);
+ }
+}
+
/*------------------------------------------------------------------------*
* Following are (vty) configuration functions for Opaque-LSAs handling.
*------------------------------------------------------------------------*/