pimd: fix null register before aging out reg-stop

It looks like the code was trying to do this with the null_register
parameter on pim_upstream_start_register_stop_timer(), but that didn't
quite work right.  Restructure a bit to get it right.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
(cherry picked from commit dce38da806)
This commit is contained in:
David Lamparter 2023-04-17 11:47:08 +02:00 committed by Mergify
parent 905c9230fd
commit 20c7a92378
3 changed files with 49 additions and 23 deletions

View File

@ -109,12 +109,12 @@ static void pim_reg_stop_upstream(struct pim_instance *pim,
up->reg_state = PIM_REG_PRUNE; up->reg_state = PIM_REG_PRUNE;
pim_channel_del_oif(up->channel_oil, pim->regiface, pim_channel_del_oif(up->channel_oil, pim->regiface,
PIM_OIF_FLAG_PROTO_PIM, __func__); PIM_OIF_FLAG_PROTO_PIM, __func__);
pim_upstream_start_register_stop_timer(up, 0); pim_upstream_start_register_probe_timer(up);
pim_vxlan_update_sg_reg_state(pim, up, false); pim_vxlan_update_sg_reg_state(pim, up, false);
break; break;
case PIM_REG_JOIN_PENDING: case PIM_REG_JOIN_PENDING:
up->reg_state = PIM_REG_PRUNE; up->reg_state = PIM_REG_PRUNE;
pim_upstream_start_register_stop_timer(up, 0); pim_upstream_start_register_probe_timer(up);
return; return;
} }
} }

View File

@ -1686,6 +1686,8 @@ const char *pim_reg_state2str(enum pim_reg_state reg_state, char *state_str,
return state_str; return state_str;
} }
static void pim_upstream_start_register_stop_timer(struct pim_upstream *up);
static void pim_upstream_register_stop_timer(struct event *t) static void pim_upstream_register_stop_timer(struct event *t)
{ {
struct pim_interface *pim_ifp; struct pim_interface *pim_ifp;
@ -1733,7 +1735,7 @@ static void pim_upstream_register_stop_timer(struct event *t)
return; return;
} }
up->reg_state = PIM_REG_JOIN_PENDING; up->reg_state = PIM_REG_JOIN_PENDING;
pim_upstream_start_register_stop_timer(up, 1); pim_upstream_start_register_stop_timer(up);
if (((up->channel_oil->cc.lastused / 100) if (((up->channel_oil->cc.lastused / 100)
> pim->keep_alive_time) > pim->keep_alive_time)
@ -1751,34 +1753,59 @@ static void pim_upstream_register_stop_timer(struct event *t)
} }
} }
void pim_upstream_start_register_stop_timer(struct pim_upstream *up, static void pim_upstream_start_register_stop_timer(struct pim_upstream *up)
int null_register)
{ {
uint32_t time; uint32_t time;
EVENT_OFF(up->t_rs_timer); EVENT_OFF(up->t_rs_timer);
if (!null_register) { time = router->register_probe_time;
uint32_t lower = (0.5 * router->register_suppress_time);
uint32_t upper = (1.5 * router->register_suppress_time);
time = lower + (frr_weak_random() % (upper - lower + 1));
/* Make sure we don't wrap around */
if (time >= router->register_probe_time)
time -= router->register_probe_time;
else
time = 0;
} else
time = router->register_probe_time;
if (PIM_DEBUG_PIM_TRACE) { if (PIM_DEBUG_PIM_TRACE)
zlog_debug( zlog_debug("%s: (S,G)=%s Starting upstream register stop timer %d",
"%s: (S,G)=%s Starting upstream register stop timer %d", __func__, up->sg_str, time);
__func__, up->sg_str, time);
}
event_add_timer(router->master, pim_upstream_register_stop_timer, up, event_add_timer(router->master, pim_upstream_register_stop_timer, up,
time, &up->t_rs_timer); time, &up->t_rs_timer);
} }
static void pim_upstream_register_probe_timer(struct event *t)
{
struct pim_upstream *up = EVENT_ARG(t);
if (!up->rpf.source_nexthop.interface ||
!up->rpf.source_nexthop.interface->info) {
if (PIM_DEBUG_PIM_REG)
zlog_debug("cannot send Null register for %pSG, no path to RP",
&up->sg);
} else
pim_null_register_send(up);
pim_upstream_start_register_stop_timer(up);
}
void pim_upstream_start_register_probe_timer(struct pim_upstream *up)
{
uint32_t time;
EVENT_OFF(up->t_rs_timer);
uint32_t lower = (0.5 * router->register_suppress_time);
uint32_t upper = (1.5 * router->register_suppress_time);
time = lower + (frr_weak_random() % (upper - lower + 1));
/* Make sure we don't wrap around */
if (time >= router->register_probe_time)
time -= router->register_probe_time;
else
time = 0;
if (PIM_DEBUG_PIM_TRACE)
zlog_debug("%s: (S,G)=%s Starting upstream register stop null probe timer %d",
__func__, up->sg_str, time);
event_add_timer(router->master, pim_upstream_register_probe_timer, up,
time, &up->t_rs_timer);
}
int pim_upstream_inherited_olist_decide(struct pim_instance *pim, int pim_upstream_inherited_olist_decide(struct pim_instance *pim,
struct pim_upstream *up) struct pim_upstream *up)
{ {

View File

@ -331,8 +331,7 @@ int pim_upstream_is_sg_rpt(struct pim_upstream *up);
void pim_upstream_set_sptbit(struct pim_upstream *up, void pim_upstream_set_sptbit(struct pim_upstream *up,
struct interface *incoming); struct interface *incoming);
void pim_upstream_start_register_stop_timer(struct pim_upstream *up, void pim_upstream_start_register_probe_timer(struct pim_upstream *up);
int null_register);
void pim_upstream_send_join(struct pim_upstream *up); void pim_upstream_send_join(struct pim_upstream *up);