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);
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);
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. */
}
"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. */
}
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;