#include "pim_ssm.h"
#include "pim_rp.h"
-RB_GENERATE(pim_ifchannel_rb, pim_ifchannel,
- pim_ifp_rb, pim_ifchannel_compare);
+RB_GENERATE(pim_ifchannel_rb, pim_ifchannel, pim_ifp_rb, pim_ifchannel_compare);
int pim_ifchannel_compare(const struct pim_ifchannel *ch1,
const struct pim_ifchannel *ch2)
}
}
-void pim_ifchannel_free(struct pim_ifchannel *ch)
-{
- XFREE(MTYPE_PIM_IFCHANNEL, ch);
-}
-
void pim_ifchannel_delete(struct pim_ifchannel *ch)
{
struct pim_interface *pim_ifp;
mask = PIM_OIF_FLAG_PROTO_IGMP;
/* SGRpt entry could have empty oil */
- if (ch->upstream->channel_oil)
- pim_channel_del_oif(ch->upstream->channel_oil,
- ch->interface, mask);
+ pim_channel_del_oif(ch->upstream->channel_oil, ch->interface,
+ mask);
/*
* Do we have any S,G's that are inheriting?
* Nuke from on high too.
pim_ifchannel_remove_children(ch);
if (ch->sources)
- list_delete_and_null(&ch->sources);
+ list_delete(&ch->sources);
listnode_delete(ch->upstream->ifchannels, ch);
ifchannel list is empty before deleting upstream_del
ref count will take care of it.
*/
- pim_upstream_del(pim_ifp->pim, ch->upstream, __PRETTY_FUNCTION__);
+ if (ch->upstream->ref_count > 0)
+ pim_upstream_del(pim_ifp->pim, ch->upstream,
+ __PRETTY_FUNCTION__);
+
+ else
+ zlog_warn("%s: Avoiding deletion of upstream with ref_count %d "
+ "from ifchannel(%s): %s", __PRETTY_FUNCTION__,
+ ch->upstream->ref_count, ch->interface->name,
+ ch->sg_str);
+
ch->upstream = NULL;
THREAD_OFF(ch->t_ifjoin_expiry_timer);
zlog_debug("%s: ifchannel entry %s is deleted ",
__PRETTY_FUNCTION__, ch->sg_str);
- pim_ifchannel_free(ch);
+ XFREE(MTYPE_PIM_IFCHANNEL, ch);
}
void pim_ifchannel_delete_all(struct interface *ifp)
pim_ifp = ifp->info;
ch = XCALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch));
- if (!ch) {
- zlog_warn(
- "%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s",
- __PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name);
- return NULL;
- }
ch->flags = 0;
if ((source_flags & PIM_ENCODE_RPT_BIT)
up = pim_upstream_add(pim_ifp->pim, sg, NULL, up_flags,
__PRETTY_FUNCTION__, ch);
- if (!up) {
- zlog_err(
- "%s: could not attach upstream (S,G)=%s on interface %s",
- __PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name);
-
- if (ch->parent)
- listnode_delete(ch->parent->sources, ch);
-
- pim_ifchannel_remove_children(ch);
- if (ch->sources)
- list_delete_and_null(&ch->sources);
-
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
- THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- THREAD_OFF(ch->t_ifassert_timer);
-
- RB_REMOVE(pim_ifchannel_rb, &pim_ifp->ifchannel_rb, ch);
- XFREE(MTYPE_PIM_IFCHANNEL, ch);
- return NULL;
- }
ch->upstream = up;
listnode_add_sort(up->ifchannels, ch);
ch = THREAD_ARG(t);
if (PIM_DEBUG_TRACE)
- zlog_debug("%s: IFCHANNEL%s %s Prune Pending Timer Popped",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump(&ch->sg),
- pim_ifchannel_ifjoin_name(ch->ifjoin_state,
- ch->flags));
+ zlog_debug(
+ "%s: IFCHANNEL%s %s Prune Pending Timer Popped",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&ch->sg),
+ pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
if (ch->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING) {
ifp = ch->interface;
rpf.source_nexthop.interface = ifp;
rpf.rpf_addr.u.prefix4 =
pim_ifp->primary_address;
- pim_jp_agg_single_upstream_send(&rpf,
- ch->upstream,
- 0);
+ pim_jp_agg_single_upstream_send(
+ &rpf, ch->upstream, 0);
}
ifjoin_to_noinfo(ch, true);
ch->upstream);
pim_jp_agg_single_upstream_send(&parent->rpf,
- parent,
- true);
+ parent, true);
}
}
/* from here ch may have been deleted */
/* PIM enabled on interface? */
pim_ifp = ifp->info;
- if (!pim_ifp)
+ if (!pim_ifp) {
+ if (PIM_DEBUG_EVENTS)
+ zlog_debug("%s:%s Expected pim interface setup for %s",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(sg), ifp->name);
return 0;
- if (!PIM_IF_TEST_PIM(pim_ifp->options))
+ }
+
+ if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
+ if (PIM_DEBUG_EVENTS)
+ zlog_debug("%s:%s PIM is not configured on this interface %s",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(sg), ifp->name);
return 0;
+ }
pim = pim_ifp->pim;
ch = pim_ifchannel_add(ifp, sg, 0, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP);
if (!ch) {
+ if (PIM_DEBUG_EVENTS)
+ zlog_debug("%s:%s Unable to add ifchannel",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(sg));
return 0;
}
struct channel_oil *c_oil = child->channel_oil;
struct pim_ifchannel *chchannel =
pim_ifchannel_find(ifp, &child->sg);
- struct pim_interface *pim_ifp = ifp->info;
+
+ pim_ifp = ifp->info;
if (PIM_DEBUG_EVENTS)
zlog_debug("%s %s: Prune(S,G)=%s(%s) from %s",
if (child->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING_TMP)
THREAD_OFF(child->t_ifjoin_prune_pending_timer);
THREAD_OFF(child->t_ifjoin_expiry_timer);
- struct pim_upstream *parent =
- child->upstream->parent;
+ struct pim_upstream *parent = child->upstream->parent;
PIM_IF_FLAG_UNSET_S_G_RPT(child->flags);
child->ifjoin_state = PIM_IFJOIN_NOINFO;
if (I_am_RP(pim, child->sg.grp)) {
pim_channel_add_oif(
child->upstream->channel_oil,
- ch->interface,
- PIM_OIF_FLAG_PROTO_STAR);
- pim_upstream_switch(
- pim, child->upstream,
- PIM_UPSTREAM_JOINED);
+ ch->interface, PIM_OIF_FLAG_PROTO_STAR);
+ pim_upstream_switch(pim, child->upstream,
+ PIM_UPSTREAM_JOINED);
pim_jp_agg_single_upstream_send(
- &child->upstream->rpf,
- child->upstream, true);
+ &child->upstream->rpf, child->upstream,
+ true);
}
if (parent)
- pim_jp_agg_single_upstream_send(
- &parent->rpf,
- parent, true);
+ pim_jp_agg_single_upstream_send(&parent->rpf,
+ parent, true);
delete_on_noinfo(child);
break;