mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 20:13:53 +00:00
pimd: Fix possible double free of upstream
Fix possible double free of upstream and in addition add some debug code to help find where the problem is coming from. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
3506072736
commit
e5905a3bc3
@ -127,7 +127,7 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
|
|||||||
pim_upstream_update_join_desired(ch->upstream);
|
pim_upstream_update_join_desired(ch->upstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
pim_upstream_del(ch->upstream);
|
pim_upstream_del(ch->upstream, __PRETTY_FUNCTION__);
|
||||||
ch->upstream = NULL;
|
ch->upstream = NULL;
|
||||||
|
|
||||||
THREAD_OFF(ch->t_ifjoin_expiry_timer);
|
THREAD_OFF(ch->t_ifjoin_expiry_timer);
|
||||||
@ -365,7 +365,7 @@ pim_ifchannel_add(struct interface *ifp,
|
|||||||
pim_ifp = ifp->info;
|
pim_ifp = ifp->info;
|
||||||
zassert(pim_ifp);
|
zassert(pim_ifp);
|
||||||
|
|
||||||
up = pim_upstream_add(sg, NULL, flags);
|
up = pim_upstream_add(sg, NULL, flags, __PRETTY_FUNCTION__);
|
||||||
if (!up) {
|
if (!up) {
|
||||||
zlog_err("%s: could not attach upstream (S,G)=%s on interface %s",
|
zlog_err("%s: could not attach upstream (S,G)=%s on interface %s",
|
||||||
__PRETTY_FUNCTION__,
|
__PRETTY_FUNCTION__,
|
||||||
|
@ -136,7 +136,7 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR);
|
up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, __PRETTY_FUNCTION__);
|
||||||
if (!up) {
|
if (!up) {
|
||||||
if (PIM_DEBUG_MROUTE) {
|
if (PIM_DEBUG_MROUTE) {
|
||||||
zlog_debug("%s: Failure to add upstream information for %s",
|
zlog_debug("%s: Failure to add upstream information for %s",
|
||||||
@ -371,7 +371,7 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
|
|||||||
pim_mroute_add (oil);
|
pim_mroute_add (oil);
|
||||||
if (pim_if_connected_to_source (ifp, sg.src))
|
if (pim_if_connected_to_source (ifp, sg.src))
|
||||||
{
|
{
|
||||||
up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR);
|
up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, __PRETTY_FUNCTION__);
|
||||||
if (!up)
|
if (!up)
|
||||||
{
|
{
|
||||||
if (PIM_DEBUG_MROUTE)
|
if (PIM_DEBUG_MROUTE)
|
||||||
|
@ -333,7 +333,9 @@ pim_register_recv (struct interface *ifp,
|
|||||||
*/
|
*/
|
||||||
if (!upstream)
|
if (!upstream)
|
||||||
{
|
{
|
||||||
upstream = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM);
|
upstream = pim_upstream_add (&sg, ifp,
|
||||||
|
PIM_UPSTREAM_FLAG_MASK_SRC_STREAM,
|
||||||
|
__PRETTY_FUNCTION__);
|
||||||
if (!upstream)
|
if (!upstream)
|
||||||
{
|
{
|
||||||
zlog_warn ("Failure to create upstream state");
|
zlog_warn ("Failure to create upstream state");
|
||||||
|
@ -156,8 +156,19 @@ static void upstream_channel_oil_detach(struct pim_upstream *up)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pim_upstream_delete(struct pim_upstream *up)
|
void
|
||||||
|
pim_upstream_del(struct pim_upstream *up, const char *name)
|
||||||
{
|
{
|
||||||
|
if (PIM_DEBUG_PIM_TRACE)
|
||||||
|
{
|
||||||
|
zlog_debug ("%s: Delete (%s) ref count: %d",
|
||||||
|
name, pim_str_sg_dump (&up->sg), up->ref_count);
|
||||||
|
}
|
||||||
|
--up->ref_count;
|
||||||
|
|
||||||
|
if (up->ref_count >= 1)
|
||||||
|
return;
|
||||||
|
|
||||||
if (PIM_DEBUG_PIM_TRACE)
|
if (PIM_DEBUG_PIM_TRACE)
|
||||||
zlog_debug ("%s: %s is being deleted",
|
zlog_debug ("%s: %s is being deleted",
|
||||||
__PRETTY_FUNCTION__,
|
__PRETTY_FUNCTION__,
|
||||||
@ -548,31 +559,29 @@ struct pim_upstream *pim_upstream_find(struct prefix_sg *sg)
|
|||||||
|
|
||||||
struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
|
struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
|
||||||
struct interface *incoming,
|
struct interface *incoming,
|
||||||
int flags)
|
int flags, const char *name)
|
||||||
{
|
{
|
||||||
struct pim_upstream *up = NULL;
|
struct pim_upstream *up = NULL;
|
||||||
|
int found = 0;
|
||||||
up = pim_upstream_find(sg);
|
up = pim_upstream_find(sg);
|
||||||
if (up) {
|
if (up) {
|
||||||
++up->ref_count;
|
++up->ref_count;
|
||||||
up->flags |= flags;
|
up->flags |= flags;
|
||||||
|
found = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
up = pim_upstream_new(sg, incoming, flags);
|
up = pim_upstream_new(sg, incoming, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PIM_DEBUG_TRACE)
|
||||||
|
zlog_debug("%s(%s): (%s), found: %d: ref_count: %d",
|
||||||
|
__PRETTY_FUNCTION__, name,
|
||||||
|
pim_str_sg_dump (&up->sg), found,
|
||||||
|
up->ref_count);
|
||||||
|
|
||||||
return up;
|
return up;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pim_upstream_del(struct pim_upstream *up)
|
|
||||||
{
|
|
||||||
--up->ref_count;
|
|
||||||
|
|
||||||
if (up->ref_count < 1) {
|
|
||||||
pim_upstream_delete(up);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pim_upstream_evaluate_join_desired_interface (struct pim_upstream *up,
|
pim_upstream_evaluate_join_desired_interface (struct pim_upstream *up,
|
||||||
struct pim_ifchannel *ch)
|
struct pim_ifchannel *ch)
|
||||||
@ -885,7 +894,10 @@ pim_upstream_keep_alive_timer (struct thread *t)
|
|||||||
&up->sg, 0);
|
&up->sg, 0);
|
||||||
PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM (up->flags);
|
PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM (up->flags);
|
||||||
if (PIM_UPSTREAM_FLAG_TEST_CREATED_BY_UPSTREAM(up->flags))
|
if (PIM_UPSTREAM_FLAG_TEST_CREATED_BY_UPSTREAM(up->flags))
|
||||||
pim_upstream_del (up);
|
{
|
||||||
|
PIM_UPSTREAM_FLAG_UNSET_CREATED_BY_UPSTREAM(up->flags);
|
||||||
|
pim_upstream_del (up, __PRETTY_FUNCTION__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -116,11 +116,11 @@ struct list *pim_upstream_list;
|
|||||||
struct hash *pim_upstream_hash;
|
struct hash *pim_upstream_hash;
|
||||||
|
|
||||||
void pim_upstream_free(struct pim_upstream *up);
|
void pim_upstream_free(struct pim_upstream *up);
|
||||||
void pim_upstream_delete(struct pim_upstream *up);
|
|
||||||
struct pim_upstream *pim_upstream_find (struct prefix_sg *sg);
|
struct pim_upstream *pim_upstream_find (struct prefix_sg *sg);
|
||||||
struct pim_upstream *pim_upstream_add (struct prefix_sg *sg,
|
struct pim_upstream *pim_upstream_add (struct prefix_sg *sg,
|
||||||
struct interface *ifp, int);
|
struct interface *ifp, int flags,
|
||||||
void pim_upstream_del(struct pim_upstream *up);
|
const char *name);
|
||||||
|
void pim_upstream_del(struct pim_upstream *up, const char *name);
|
||||||
|
|
||||||
int pim_upstream_evaluate_join_desired(struct pim_upstream *up);
|
int pim_upstream_evaluate_join_desired(struct pim_upstream *up);
|
||||||
void pim_upstream_update_join_desired(struct pim_upstream *up);
|
void pim_upstream_update_join_desired(struct pim_upstream *up);
|
||||||
|
Loading…
Reference in New Issue
Block a user