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; diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 8670359610..881226683c 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -3897,6 +3897,10 @@ static void ospf_ls_upd_queue_send(struct ospf_interface *oi, zlog_debug("listcount = %d, [%s]dst %s", listcount(update), IF_NAME(oi), inet_ntoa(addr)); + /* Check that we have really something to process */ + if (listcount(update) == 0) + return; + op = ospf_ls_upd_packet_new(update, oi); /* Prepare OSPF common header. */