summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-02-14 20:03:18 -0500
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-02-24 10:03:41 -0500
commitb7ddd2ec481969bdfcd576c52a6e99c4489ece58 (patch)
treef23e25fa222f2821a29dd2d990ebc953968c8c62
parentb5e2377cca8d2e7339927389e6f05a2f4a1e209d (diff)
pimd: Intelligently drop wrvifwhole packets in some cases
Suppose we have this (*,G) IIF = swp1 OIL: swp3 (S,G) IIF = swp2 OIL: swp3 swp4 There exists situations where we can receive the mcast packet for (S,G) on both swp1 and swp2. In this case the packet received on swp1 will be sent from the kernel to us as a WRVIF and WRVIFWHOLE. As per normal, WRVIF packet processing handles the assert case so we know we have not received the packet on a downstream interface, so no assert. The WRVIFWHOLE packet processing can then check to see if it received the packet as a result of the (*,G) mroute from upstream. If we have then we can safely drop the packet. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
-rw-r--r--pimd/pim_mroute.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index 4fae5b3ca5..ae5d0e9891 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -351,7 +351,7 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
struct pim_upstream *up;
- //struct prefix_sg star_g;
+ struct prefix_sg star_g;
struct prefix_sg sg;
struct channel_oil *oil;
@@ -367,9 +367,10 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
ch->sg_str, ifp->name);
return -1;
}
-#if 0
+
star_g = sg;
star_g.src.s_addr = INADDR_ANY;
+#if 0
ch = pim_ifchannel_find(ifp, &star_g);
if (ch)
{
@@ -383,11 +384,22 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
up = pim_upstream_find (&sg);
if (up)
{
+ struct pim_upstream *parent;
struct pim_nexthop source;
struct pim_rpf *rpf = RP (sg.grp);
if (!rpf || !rpf->source_nexthop.interface)
return 0;
+ /*
+ * If we have received a WRVIFWHOLE and are at this
+ * point, we could be receiving the packet on the *,G
+ * tree, let's check and if so we can safely drop
+ * it.
+ */
+ parent = pim_upstream_find (&star_g);
+ if (parent && parent->rpf.source_nexthop.interface == ifp)
+ return 0;
+
pim_ifp = rpf->source_nexthop.interface->info;
memset (&source, 0, sizeof (source));