summaryrefslogtreecommitdiff
path: root/pimd/pim_ifchannel.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_ifchannel.c')
-rw-r--r--pimd/pim_ifchannel.c121
1 files changed, 70 insertions, 51 deletions
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index f4fe609605..735df82581 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING; if not, write to the
- Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- MA 02110-1301 USA
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#include <zebra.h>
@@ -148,7 +147,6 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
/* 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.
@@ -179,6 +177,10 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
pim_upstream_update_join_desired(ch->upstream);
}
+ /* upstream is common across ifchannels, check if upstream's
+ ifchannel list is empty before deleting upstream_del
+ ref count will take care of it.
+ */
pim_upstream_del(ch->upstream, __PRETTY_FUNCTION__);
ch->upstream = NULL;
@@ -200,6 +202,9 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
hash_release(pim_ifp->pim_ifchannel_hash, ch);
listnode_delete(pim_ifchannel_list, ch);
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug ("%s: ifchannel entry %s is deleted ", __PRETTY_FUNCTION__, ch->sg_str);
+
pim_ifchannel_free(ch);
}
@@ -571,14 +576,18 @@ pim_ifchannel_add(struct interface *ifp,
listnode_add_sort(up->ifchannels, ch);
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug ("%s: ifchannel %s is created ", __PRETTY_FUNCTION__, ch->sg_str);
+
return ch;
}
-static void ifjoin_to_noinfo(struct pim_ifchannel *ch)
+static void ifjoin_to_noinfo(struct pim_ifchannel *ch, bool ch_del)
{
pim_forward_stop(ch);
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
- delete_on_noinfo(ch);
+ if (ch_del)
+ delete_on_noinfo(ch);
}
static int on_ifjoin_expiry_timer(struct thread *t)
@@ -589,7 +598,7 @@ static int on_ifjoin_expiry_timer(struct thread *t)
ch->t_ifjoin_expiry_timer = NULL;
- ifjoin_to_noinfo(ch);
+ ifjoin_to_noinfo(ch, true);
/* ch may have been deleted */
return 0;
@@ -613,10 +622,6 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
pim_ifp = ifp->info;
send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
- //ch->ifjoin_state transition to NOINFO
- ifjoin_to_noinfo(ch);
- /* from here ch may have been deleted */
-
if (send_prune_echo)
{
struct pim_rpf rpf;
@@ -625,6 +630,23 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
rpf.rpf_addr.u.prefix4 = pim_ifp->primary_address;
pim_jp_agg_single_upstream_send(&rpf, ch->upstream, 0);
}
+ /* If SGRpt flag is set on ifchannel, Trigger SGRpt
+ message on RP path upon prune timer expiry.
+ */
+ if (PIM_IF_FLAG_TEST_S_G_RPT (ch->flags))
+ {
+ if (ch->upstream)
+ pim_upstream_update_join_desired(ch->upstream);
+ /*
+ ch->ifjoin_state transition to NOINFO state
+ ch_del is set to 0 for not deleteing from here.
+ Holdtime expiry (ch_del set to 1) delete the entry.
+ */
+ ifjoin_to_noinfo(ch, false);
+ }
+ else
+ ifjoin_to_noinfo(ch, true);
+ /* from here ch may have been deleted */
}
else
{
@@ -801,7 +823,7 @@ void pim_ifchannel_join_add(struct interface *ifp,
(ch->upstream->parent->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) &&
!(ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR))
{
- pim_upstream_ref (ch->upstream, PIM_UPSTREAM_FLAG_MASK_SRC_LHR);
+ pim_upstream_ref (ch->upstream, PIM_UPSTREAM_FLAG_MASK_SRC_LHR, __PRETTY_FUNCTION__);
pim_upstream_keep_alive_timer_start (ch->upstream, qpim_keep_alive_time);
}
break;
@@ -855,9 +877,8 @@ void pim_ifchannel_join_add(struct interface *ifp,
}
if (holdtime != 0xFFFF) {
- THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
- on_ifjoin_expiry_timer,
- ch, holdtime);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
}
@@ -895,8 +916,10 @@ void pim_ifchannel_prune(struct interface *ifp,
case PIM_IFJOIN_NOINFO:
if (source_flags & PIM_ENCODE_RPT_BIT)
{
- PIM_IF_FLAG_SET_S_G_RPT(ch->flags);
- ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
+ if (!(source_flags & PIM_ENCODE_WC_BIT))
+ PIM_IF_FLAG_SET_S_G_RPT(ch->flags);
+
+ ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
if (listcount(pim_ifp->pim_neighbor_list) > 1)
jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp);
else
@@ -907,12 +930,11 @@ void pim_ifchannel_prune(struct interface *ifp,
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
THREAD_OFF(ch->t_ifjoin_expiry_timer);
- THREAD_TIMER_MSEC_ON(master, ch->t_ifjoin_prune_pending_timer,
- on_ifjoin_prune_pending_timer,
- ch, jp_override_interval_msec);
- THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
- on_ifjoin_expiry_timer,
- ch, holdtime);
+ thread_add_timer_msec(master, on_ifjoin_prune_pending_timer, ch,
+ jp_override_interval_msec,
+ &ch->t_ifjoin_prune_pending_timer);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
pim_upstream_update_join_desired(ch->upstream);
}
break;
@@ -932,17 +954,16 @@ void pim_ifchannel_prune(struct interface *ifp,
be taken not to use "ch" afterwards since it would be
deleted. */
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- THREAD_TIMER_MSEC_ON(master, ch->t_ifjoin_prune_pending_timer,
- on_ifjoin_prune_pending_timer,
- ch, jp_override_interval_msec);
+ thread_add_timer_msec(master, on_ifjoin_prune_pending_timer, ch,
+ jp_override_interval_msec,
+ &ch->t_ifjoin_prune_pending_timer);
break;
case PIM_IFJOIN_PRUNE:
if (source_flags & PIM_ENCODE_RPT_BIT)
{
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
- on_ifjoin_expiry_timer,
- ch, holdtime);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
case PIM_IFJOIN_PRUNE_TMP:
@@ -950,9 +971,8 @@ void pim_ifchannel_prune(struct interface *ifp,
{
ch->ifjoin_state = PIM_IFJOIN_PRUNE;
THREAD_OFF(ch->t_ifjoin_expiry_timer);
- THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
- on_ifjoin_expiry_timer,
- ch, holdtime);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
case PIM_IFJOIN_PRUNE_PENDING_TMP:
@@ -960,9 +980,8 @@ void pim_ifchannel_prune(struct interface *ifp,
{
ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
THREAD_OFF(ch->t_ifjoin_expiry_timer);
- THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
- on_ifjoin_expiry_timer,
- ch, holdtime);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
}
@@ -1306,7 +1325,7 @@ pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t
if (up)
{
if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: del inherit oif from up %s", __PRETTY_FUNCTION__, up->sg_str);
+ zlog_debug ("%s: SGRpt Set, del inherit oif from up %s", __PRETTY_FUNCTION__, up->sg_str);
pim_channel_del_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
}
}