summaryrefslogtreecommitdiff
path: root/ospfd/ospf_opaque.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_opaque.c')
-rw-r--r--ospfd/ospf_opaque.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 1c586d252c..009fd997ea 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -75,6 +75,7 @@ static void ospf_opaque_funclist_init(void);
static void ospf_opaque_funclist_term(void);
static void free_opaque_info_per_type(void *val);
static void free_opaque_info_per_id(void *val);
+static void free_opaque_info_owner(void *val);
static int ospf_opaque_lsa_install_hook(struct ospf_lsa *lsa);
static int ospf_opaque_lsa_delete_hook(struct ospf_lsa *lsa);
@@ -439,9 +440,11 @@ void ospf_delete_opaque_functab(u_char lsa_type, u_char opaque_type)
if (functab->opaque_type == opaque_type) {
/* Cleanup internal control information, if it
* still remains. */
- if (functab->oipt != NULL)
+ if (functab->oipt != NULL) {
free_opaque_info_per_type(
functab->oipt);
+ free_opaque_info_owner(functab->oipt);
+ }
/* Dequeue listnode entry from the list. */
listnode_delete(funclist, functab);
@@ -572,6 +575,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab,
top = ospf_lookup_by_vrf_id(new->vrf_id);
if (new->area != NULL && (top = new->area->ospf) == NULL) {
free_opaque_info_per_type((void *)oipt);
+ free_opaque_info_owner(oipt);
oipt = NULL;
goto out; /* This case may not exist. */
}
@@ -583,6 +587,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab,
"register_opaque_info_per_type: Unexpected LSA-type(%u)",
new->data->type);
free_opaque_info_per_type((void *)oipt);
+ free_opaque_info_owner(oipt);
oipt = NULL;
goto out; /* This case may not exist. */
}
@@ -600,6 +605,35 @@ out:
return oipt;
}
+/* Remove "oipt" from its owner's self-originated LSA list. */
+static void free_opaque_info_owner(void *val)
+{
+ struct opaque_info_per_type *oipt = (struct opaque_info_per_type *)val;
+
+ switch (oipt->lsa_type) {
+ case OSPF_OPAQUE_LINK_LSA: {
+ struct ospf_interface *oi =
+ (struct ospf_interface *)(oipt->owner);
+ listnode_delete(oi->opaque_lsa_self, oipt);
+ break;
+ }
+ case OSPF_OPAQUE_AREA_LSA: {
+ struct ospf_area *area = (struct ospf_area *)(oipt->owner);
+ listnode_delete(area->opaque_lsa_self, oipt);
+ break;
+ }
+ case OSPF_OPAQUE_AS_LSA: {
+ struct ospf *top = (struct ospf *)(oipt->owner);
+ listnode_delete(top->opaque_lsa_self, oipt);
+ break;
+ }
+ default:
+ zlog_warn("free_opaque_info_owner: Unexpected LSA-type(%u)",
+ oipt->lsa_type);
+ break; /* This case may not exist. */
+ }
+}
+
static void free_opaque_info_per_type(void *val)
{
struct opaque_info_per_type *oipt = (struct opaque_info_per_type *)val;