summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2016-11-03 15:56:39 +0100
committerDonald Sharp <sharpd@cumulusnetworks.com>2016-12-22 02:26:13 +0100
commit3a66b17b6934cc733668e17498e0e88eb9f8f25c (patch)
tree7c02afaea1f39e8f77a7161a00ef1dc279cecf4e
parentpimd: Add ability to set SPTBIT on a S,G stream (diff)
downloadfrr-3a66b17b6934cc733668e17498e0e88eb9f8f25c.tar.xz
frr-3a66b17b6934cc733668e17498e0e88eb9f8f25c.zip
pimd: Abstract setting of the spt bit a bit more
Allow the spt bit to be set appropriately from multiple places. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to '')
-rw-r--r--pimd/pim_mroute.c3
-rw-r--r--pimd/pim_upstream.c111
-rw-r--r--pimd/pim_upstream.h2
3 files changed, 81 insertions, 35 deletions
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index d0afb124a..467fc45b9 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -357,8 +357,7 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
pim_upstream_inherited_olist (up);
if (!up->channel_oil->installed)
pim_mroute_add (up->channel_oil);
- //Send S bit down the join.
- up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ pim_upstream_set_sptbit (up, ifp);
}
else
{
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index fdfa28317..a070e92e4 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -1029,6 +1029,83 @@ pim_upstream_is_sg_rpt (struct pim_upstream *up)
return 0;
}
+/*
+ * After receiving a packet set SPTbit:
+ * void
+ * Update_SPTbit(S,G,iif) {
+ * if ( iif == RPF_interface(S)
+ * AND JoinDesired(S,G) == TRUE
+ * AND ( DirectlyConnected(S) == TRUE
+ * OR RPF_interface(S) != RPF_interface(RP(G))
+ * OR inherited_olist(S,G,rpt) == NULL
+ * OR ( ( RPF'(S,G) == RPF'(*,G) ) AND
+ * ( RPF'(S,G) != NULL ) )
+ * OR ( I_Am_Assert_Loser(S,G,iif) ) {
+ * Set SPTbit(S,G) to TRUE
+ * }
+ * }
+ */
+void
+pim_upstream_set_sptbit (struct pim_upstream *up, struct interface *incoming)
+{
+ struct pim_rpf *grpf = NULL;
+
+ // iif == RPF_interfvace(S)
+ if (up->rpf.source_nexthop.interface != incoming)
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: Incoming Interface: %s is different than RPF_interface(S) %s",
+ __PRETTY_FUNCTION__, incoming->name, up->rpf.source_nexthop.interface->name);
+ return;
+ }
+
+ // AND JoinDesired(S,G) == TRUE
+ // FIXME
+
+ // DirectlyConnected(S) == TRUE
+ if (pim_if_connected_to_source (up->rpf.source_nexthop.interface, up->sg.src))
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: %s is directly connected to the source", __PRETTY_FUNCTION__,
+ pim_str_sg_dump (&up->sg));
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ // OR RPF_interface(S) != RPF_interface(RP(G))
+ grpf = RP(up->sg.grp);
+ if (!grpf || up->rpf.source_nexthop.interface != grpf->source_nexthop.interface)
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: %s RPF_interface(S) != RPF_interface(RP(G))",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&up->sg));
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ // OR inherited_olist(S,G,rpt) == NULL
+ if (pim_upstream_is_sg_rpt(up) && pim_upstream_empty_inherited_olist(up))
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: %s OR inherited_olist(S,G,rpt) == NULL", __PRETTY_FUNCTION__,
+ pim_str_sg_dump (&up->sg));
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ // OR ( ( RPF'(S,G) == RPF'(*,G) ) AND
+ // ( RPF'(S,G) != NULL ) )
+ if (up->parent && pim_rpf_is_same (&up->rpf, &up->parent->rpf))
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: %s RPF'(S,G) is the same as RPF'(*,G)", __PRETTY_FUNCTION__,
+ pim_str_sg_dump (&up->sg));
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ return;
+}
const char *
pim_upstream_state2str (enum pim_upstream_state join_state)
@@ -1321,39 +1398,7 @@ pim_upstream_sg_running (void *arg)
return;
}
- // AND JoinDesired(S,G) == TRUE
- // FIXME
-
- if (pim_if_connected_to_source (up->rpf.source_nexthop.interface, up->sg.src))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: %s is directly connected to the source", __PRETTY_FUNCTION__,
- pim_str_sg_dump (&up->sg));
- up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
- return;
- }
-
- // OR inherited_olist(S,G,rpt) == NULL
- if (pim_upstream_is_sg_rpt(up) && pim_upstream_empty_inherited_olist(up))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: %s OR inherited_olist(S,G,rpt) == NULL", __PRETTY_FUNCTION__,
- pim_str_sg_dump (&up->sg));
- up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
- return;
- }
-
- // OR ( ( RPF'(S,G) == RPF'(*,G) ) AND
- // ( RPF'(S,G) != NULL ) )
- if (up->parent && pim_rpf_is_same (&up->rpf, &up->parent->rpf))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: %s RPF'(S,G) is the same as RPF'(*,G)", __PRETTY_FUNCTION__,
- pim_str_sg_dump (&up->sg));
- up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
- return;
- }
-
+ pim_upstream_set_sptbit (up, up->rpf.source_nexthop.interface);
return;
}
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index 46aaef39b..a91a9ae37 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -146,6 +146,8 @@ int pim_upstream_switch_to_spt_desired (struct prefix_sg *sg);
#define SwitchToSptDesired(sg) pim_upstream_switch_to_spt_desired (sg)
int pim_upstream_is_sg_rpt (struct pim_upstream *up);
+void pim_upstream_set_sptbit (struct pim_upstream *up, struct interface *incoming);
+
void pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_register);
void pim_upstream_send_join (struct pim_upstream *up);