With reference to the ospfd in the Quagga 0.96.5 release:
It seems to me that there is a possible bug in the opaque module:
In ospf_opaque.c, there is a function named "register_opaque_info_per_id".
This is called when an opaque client wants to originate a new opaque LSA.
Upon registration, the corresponding LSA is locked by this registration
function in the statement
oipi->lsa = ospf_lsa_lock (new);
If the client wants to flush the opaque LSA, the call sequence is as
follows:
=> ospf_apiserver_handle_delete_request (struct ospf_apiserver *apiserv,
struct msg *msg)
....
=> ospf_opaque_lsa_flush_schedule (old);
....
....
/* Disassociate internal control information with the given lsa.
*/
oipi->lsa = NULL;
free_opaque_info_per_id ((void *) oipi);
which I assume is the reverse action of what the registration function
did.
However, due to the statement "oipi->lsa = NULL;" the LSA is not
unlocked within the function
"free_opaque_info_per_id".
Consequently, the LSA is not freed after the LSA maxage actions are
carried out. What I experience,
is dangling" LSAs in memory with lsa->lock = 1 and with no reference to
the LSDB.
Have I misunderstood something ?
Regards Gunnar Stigen
re are the free_opaque_info_per_id (void *val)
{
static struct opaque_info_per_id *
register_opaque_info_per_id (struct opaque_info_per_type *oipt,
struct ospf_lsa *new)
{
struct opaque_info_per_id *oipi;
if ((oipi = XCALLOC (MTYPE_OPAQUE_INFO_PER_ID,
sizeof (struct opaque_info_per_id))) == NULL)
{
zlog_warn ("register_opaque_info_per_id: XMALLOC: %s", strerror
(errno));
goto out;
}
oipi->opaque_id = GET_OPAQUE_ID (ntohl (new->data->id.s_addr));
oipi->t_opaque_lsa_self = NULL;
oipi->opqctl_type = oipt;
oipi->lsa = ospf_lsa_lock (new);
listnode_add (oipt->id_list, oipi);
out:
return oipi;
}
static void
free_opaque_info_per_id (void *val)
{
struct opaque_info_per_id *oipi = (struct opaque_info_per_id *) val;
OSPF_TIMER_OFF (oipi->t_opaque_lsa_self);
if (oipi->lsa != NULL)
ospf_lsa_unlock (oipi->lsa);
XFREE (MTYPE_OPAQUE_INFO_PER_ID, oipi);
return;
}
It seems to me that there is a possible bug in the opaque module:
In ospf_opaque.c, there is a function named "register_opaque_info_per_id".
This is called when an opaque client wants to originate a new opaque LSA.
Upon registration, the corresponding LSA is locked by this registration
function in the statement
oipi->lsa = ospf_lsa_lock (new);
If the client wants to flush the opaque LSA, the call sequence is as
follows:
=> ospf_apiserver_handle_delete_request (struct ospf_apiserver *apiserv,
struct msg *msg)
....
=> ospf_opaque_lsa_flush_schedule (old);
....
....
/* Disassociate internal control information with the given lsa.
*/
oipi->lsa = NULL;
free_opaque_info_per_id ((void *) oipi);
which I assume is the reverse action of what the registration function
did.
However, due to the statement "oipi->lsa = NULL;" the LSA is not
unlocked within the function
"free_opaque_info_per_id".
Consequently, the LSA is not freed after the LSA maxage actions are
carried out. What I experience,
is dangling" LSAs in memory with lsa->lock = 1 and with no reference to
the LSDB.
Have I misunderstood something ?
Regards Gunnar Stigen
re are the free_opaque_info_per_id (void *val)
{
static struct opaque_info_per_id *
register_opaque_info_per_id (struct opaque_info_per_type *oipt,
struct ospf_lsa *new)
{
struct opaque_info_per_id *oipi;
if ((oipi = XCALLOC (MTYPE_OPAQUE_INFO_PER_ID,
sizeof (struct opaque_info_per_id))) == NULL)
{
zlog_warn ("register_opaque_info_per_id: XMALLOC: %s", strerror
(errno));
goto out;
}
oipi->opaque_id = GET_OPAQUE_ID (ntohl (new->data->id.s_addr));
oipi->t_opaque_lsa_self = NULL;
oipi->opqctl_type = oipt;
oipi->lsa = ospf_lsa_lock (new);
listnode_add (oipt->id_list, oipi);
out:
return oipi;
}
static void
free_opaque_info_per_id (void *val)
{
struct opaque_info_per_id *oipi = (struct opaque_info_per_id *) val;
OSPF_TIMER_OFF (oipi->t_opaque_lsa_self);
if (oipi->lsa != NULL)
ospf_lsa_unlock (oipi->lsa);
XFREE (MTYPE_OPAQUE_INFO_PER_ID, oipi);
return;
}