summaryrefslogtreecommitdiff
path: root/pimd/pim_upstream.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_upstream.c')
-rw-r--r--pimd/pim_upstream.c155
1 files changed, 82 insertions, 73 deletions
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index dd6eab9cfe..f949dd0257 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.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>
@@ -78,9 +77,17 @@ pim_upstream_remove_children (struct pim_upstream *up)
while (!list_isempty (up->sources))
{
child = listnode_head (up->sources);
- child->parent = NULL;
listnode_delete (up->sources, child);
+ if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags))
+ {
+ PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
+ child = pim_upstream_del(child, __PRETTY_FUNCTION__);
+ }
+ if (child)
+ child->parent = NULL;
}
+ list_delete(up->sources);
+ up->sources = NULL;
}
/*
@@ -149,10 +156,14 @@ void pim_upstream_free(struct pim_upstream *up)
static void upstream_channel_oil_detach(struct pim_upstream *up)
{
- if (up->channel_oil) {
- pim_channel_oil_del(up->channel_oil);
- up->channel_oil = NULL;
- }
+ if (up->channel_oil)
+ {
+ /* Detaching from channel_oil, channel_oil may exist post del,
+ but upstream would not keep reference of it
+ */
+ pim_channel_oil_del(up->channel_oil);
+ up->channel_oil = NULL;
+ }
}
struct pim_upstream *
@@ -163,7 +174,7 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
if (PIM_DEBUG_TRACE)
zlog_debug ("%s(%s): Delete %s ref count: %d , flags: %d c_oil ref count %d (Pre decrement)",
- __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count, up->flags,
+ __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count, up->flags,
up->channel_oil->oil_ref_count);
--up->ref_count;
@@ -195,25 +206,11 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
}
pim_upstream_remove_children (up);
- pim_mroute_del (up->channel_oil, __PRETTY_FUNCTION__);
- upstream_channel_oil_detach(up);
-
if (up->sources)
- {
- struct listnode *node, *nnode;
- struct pim_upstream *child;
- for (ALL_LIST_ELEMENTS (up->sources, node, nnode, child))
- {
- if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags))
- {
- PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
- pim_upstream_del(child, __PRETTY_FUNCTION__);
- }
- }
-
- list_delete (up->sources);
- }
+ list_delete (up->sources);
up->sources = NULL;
+ pim_mroute_del (up->channel_oil, __PRETTY_FUNCTION__);
+ upstream_channel_oil_detach(up);
list_delete (up->ifchannels);
up->ifchannels = NULL;
@@ -223,11 +220,10 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
into pim_upstream_free() because the later is
called by list_delete_all_node()
*/
- if (up->parent)
- {
- listnode_delete (up->parent->sources, up);
- up->parent = NULL;
- }
+ if (up->parent && up->parent->sources)
+ listnode_delete (up->parent->sources, up);
+ up->parent = NULL;
+
listnode_delete (pim_upstream_list, up);
hash_release (pim_upstream_hash, up);
@@ -340,9 +336,8 @@ join_timer_start(struct pim_upstream *up)
else
{
THREAD_OFF (up->t_join_timer);
- THREAD_TIMER_ON(master, up->t_join_timer,
- on_join_timer,
- up, qpim_t_periodic);
+ thread_add_timer(master, on_join_timer, up, qpim_t_periodic,
+ &up->t_join_timer);
}
pim_jp_agg_upstream_verification (up, true);
}
@@ -371,9 +366,8 @@ static void pim_upstream_join_timer_restart_msec(struct pim_upstream *up,
}
THREAD_OFF(up->t_join_timer);
- THREAD_TIMER_MSEC_ON(master, up->t_join_timer,
- on_join_timer,
- up, interval_msec);
+ thread_add_timer_msec(master, on_join_timer, up, interval_msec,
+ &up->t_join_timer);
}
void pim_upstream_join_suppress(struct pim_upstream *up,
@@ -538,13 +532,14 @@ pim_upstream_switch(struct pim_upstream *up,
{
enum pim_upstream_state old_state = up->join_state;
- if (PIM_DEBUG_PIM_EVENTS) {
- zlog_debug("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",
+ if (PIM_DEBUG_PIM_EVENTS)
+ {
+ zlog_debug ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",
__PRETTY_FUNCTION__,
up->sg_str,
pim_upstream_state2str (up->join_state),
pim_upstream_state2str (new_state));
- }
+ }
up->join_state = new_state;
if (old_state != new_state)
@@ -584,7 +579,17 @@ pim_upstream_switch(struct pim_upstream *up,
if (old_state == PIM_UPSTREAM_JOINED)
pim_msdp_up_join_state_changed(up);
- pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */);
+ /* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT */
+ if (pim_upstream_is_sg_rpt(up) && up->parent)
+ {
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug ("%s: *,G IIF %s S,G IIF %s ", __PRETTY_FUNCTION__,
+ up->parent->rpf.source_nexthop.interface->name,
+ up->rpf.source_nexthop.interface->name);
+ pim_jp_agg_single_upstream_send(&up->parent->rpf, up->parent, 1 /* (W,G) Join */);
+ }
+ else
+ pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */);
join_timer_stop(up);
}
}
@@ -717,9 +722,9 @@ pim_upstream_new (struct prefix_sg *sg,
if (PIM_DEBUG_TRACE)
{
- zlog_debug ("%s: Created Upstream %s upstream_addr %s",
+ zlog_debug ("%s: Created Upstream %s upstream_addr %s ref count %d increment",
__PRETTY_FUNCTION__, up->sg_str,
- inet_ntoa (up->upstream_addr));
+ inet_ntoa (up->upstream_addr), up->ref_count);
}
return up;
@@ -750,6 +755,9 @@ pim_upstream_find_or_add(struct prefix_sg *sg,
{
up->flags |= flags;
up->ref_count++;
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s(%s): upstream %s ref count %d increment",
+ __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count);
}
}
else
@@ -759,10 +767,13 @@ pim_upstream_find_or_add(struct prefix_sg *sg,
}
void
-pim_upstream_ref(struct pim_upstream *up, int flags)
+pim_upstream_ref(struct pim_upstream *up, int flags, const char *name)
{
up->flags |= flags;
++up->ref_count;
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s(%s): upstream %s ref count %d increment",
+ __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count);
}
struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
@@ -773,7 +784,7 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
int found = 0;
up = pim_upstream_find(sg);
if (up) {
- pim_upstream_ref(up, flags);
+ pim_upstream_ref(up, flags, name);
found = 1;
}
else {
@@ -786,10 +797,11 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
{
char buf[PREFIX2STR_BUFFER];
prefix2str (&up->rpf.rpf_addr, buf, sizeof (buf));
- zlog_debug("%s(%s): %s, iif %s found: %d: ref_count: %d",
+ zlog_debug("%s(%s): %s, iif %s (%s) found: %d: ref_count: %d",
__PRETTY_FUNCTION__, name,
- up->sg_str, buf, found,
- up->ref_count);
+ up->sg_str, buf, up->rpf.source_nexthop.interface ?
+ up->rpf.source_nexthop.interface->name : "NIL" ,
+ found, up->ref_count);
}
else
zlog_debug("%s(%s): (%s) failure to create",
@@ -1119,10 +1131,8 @@ pim_upstream_keep_alive_timer_start (struct pim_upstream *up,
zlog_debug ("kat start on %s with no stream reference", up->sg_str);
}
THREAD_OFF (up->t_ka_timer);
- THREAD_TIMER_ON (master,
- up->t_ka_timer,
- pim_upstream_keep_alive_timer,
- up, time);
+ thread_add_timer(master, pim_upstream_keep_alive_timer, up, time,
+ &up->t_ka_timer);
/* any time keepalive is started against a SG we will have to
* re-evaluate our active source database */
@@ -1146,8 +1156,8 @@ void
pim_upstream_msdp_reg_timer_start(struct pim_upstream *up)
{
THREAD_OFF(up->t_msdp_reg_timer);
- THREAD_TIMER_ON(master, up->t_msdp_reg_timer,
- pim_upstream_msdp_reg_timer, up, PIM_MSDP_REG_RXED_PERIOD);
+ thread_add_timer(master, pim_upstream_msdp_reg_timer, up,
+ PIM_MSDP_REG_RXED_PERIOD, &up->t_msdp_reg_timer);
pim_msdp_sa_local_update(up);
}
@@ -1408,9 +1418,8 @@ pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_regist
zlog_debug ("%s: (S,G)=%s Starting upstream register stop timer %d",
__PRETTY_FUNCTION__, up->sg_str, time);
}
- THREAD_TIMER_ON (master, up->t_rs_timer,
- pim_upstream_register_stop_timer,
- up, time);
+ thread_add_timer(master, pim_upstream_register_stop_timer, up, time,
+ &up->t_rs_timer);
}
int
@@ -1660,7 +1669,7 @@ pim_upstream_sg_running (void *arg)
if (PIM_DEBUG_TRACE)
zlog_debug ("source reference created on kat restart %s", up->sg_str);
- pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM);
+ pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM, __PRETTY_FUNCTION__);
PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
pim_upstream_fhr_kat_start(up);
}