pimd: Fix RP shenanigans

The RP was not properly handling the series of events:

1) When a WRVIFWHOLE is received if we are the RP,
send a pim register stop to the FHR.

2) When a register was received we were sending
a join (S,G) towards the S, then a immediate prune (S,G)
followed by another join (S,G).  Just send the first join

3) Save whom we received the S,G register from so we
can use it later

4) Allow a join timer to restart itself instead
of causing a crash.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2016-08-10 16:16:22 -04:00
parent 90d82769a8
commit 8e38a2cfcc
5 changed files with 19 additions and 4 deletions

View File

@ -26,6 +26,7 @@
#include "prefix.h"
#include "pimd.h"
#include "pim_rpf.h"
#include "pim_mroute.h"
#include "pim_oil.h"
#include "pim_str.h"
@ -345,6 +346,17 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
if (PIM_DEBUG_MROUTE)
zlog_debug ("If channel: %p", ch);
up = pim_upstream_find (&sg);
if (up)
{
struct pim_nexthop source;
//No if channel, but upstream we are at the RP.
pim_nexthop_lookup (&source, up->upstream_register, NULL);
pim_register_stop_send(source.interface, &sg, up->upstream_register);
//Send S bit down the join.
return 0;
}
up = pim_upstream_add (&sg, ifp);
if (!up)

View File

@ -44,7 +44,7 @@
struct thread *send_test_packet_timer = NULL;
static void
void
pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg,
struct in_addr originator)
{
@ -321,6 +321,7 @@ pim_register_recv (struct interface *ifp,
{
upstream = pim_upstream_add (&sg, ifp);
upstream->upstream_register = src_addr;
pim_rp_set_upstream_addr (&upstream->upstream_addr, sg.src, sg.grp);
pim_nexthop_lookup (&upstream->rpf.source_nexthop,
upstream->upstream_addr, NULL);
@ -328,7 +329,8 @@ pim_register_recv (struct interface *ifp,
upstream->sg.src = sg.src;
upstream->rpf.rpf_addr = upstream->rpf.source_nexthop.mrib_nexthop_addr;
pim_upstream_switch (upstream, PIM_UPSTREAM_PRUNE);
//pim_upstream_switch (upstream, PIM_UPSTREAM_PRUNE);
upstream->join_state = PIM_UPSTREAM_PRUNE;
}

View File

@ -43,5 +43,6 @@ int pim_register_recv (struct interface *ifp,
uint8_t *tlv_buf, int tlv_buf_size);
void pim_register_send (const uint8_t *buf, int buf_size, struct pim_rpf *rpg, int null_register);
void pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg, struct in_addr originator);
#endif

View File

@ -225,8 +225,7 @@ static void join_timer_start(struct pim_upstream *up)
pim_str_sg_dump (&up->sg));
}
zassert(!up->t_join_timer);
THREAD_OFF (up->t_join_timer);
THREAD_TIMER_ON(master, up->t_join_timer,
on_join_timer,
up, qpim_t_periodic);

View File

@ -90,6 +90,7 @@ struct pim_upstream {
struct pim_upstream *parent;
int fhr;
struct in_addr upstream_addr;/* Who we are talking to */
struct in_addr upstream_register; /*Who we received a register from*/
struct prefix_sg sg; /* (S,G) group key */
uint32_t flags;
struct channel_oil *channel_oil;