From e8b7548c0d420e8e1ada7ae7db6aea14146c7b2d Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Wed, 18 Aug 2021 21:48:28 -0400 Subject: [PATCH] pimd: fix register suppress timer code Signed-off-by: Christian Hopps --- pimd/pim_instance.h | 4 ++-- pimd/pim_nb_config.c | 19 +++++++++++++++++++ pimd/pim_upstream.c | 14 +++++++++----- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h index 72c726690c..52ded08ae3 100644 --- a/pimd/pim_instance.h +++ b/pimd/pim_instance.h @@ -96,9 +96,9 @@ struct pim_router { int t_periodic; struct pim_assert_metric infinite_assert_metric; long rpf_cache_refresh_delay_msec; - int32_t register_suppress_time; + uint32_t register_suppress_time; int packet_process; - int32_t register_probe_time; + uint32_t register_probe_time; /* * What is the default vrf that we work in diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index 5940c94570..22a98f94dd 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -556,8 +556,27 @@ int pim_join_prune_interval_modify(struct nb_cb_modify_args *args) */ int pim_register_suppress_time_modify(struct nb_cb_modify_args *args) { + uint16_t value; switch (args->event) { case NB_EV_VALIDATE: + value = yang_dnode_get_uint16(args->dnode, NULL); + /* + * As soon as this is non-constant it needs to be replaced with + * a yang_dnode_get to lookup the candidate value, *not* the + * operational value. Since the code has a field assigned and + * used for this value it should have YANG/CLI to set it too, + * otherwise just use the #define! + */ + /* RFC7761: 4.11. Timer Values */ + if (value <= router->register_probe_time * 2) { + snprintf( + args->errmsg, args->errmsg_len, + "Register suppress time (%u) must be more than " + "twice the register probe time (%u).", + value, router->register_probe_time); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: break; diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 2b674b4234..d21c7b4008 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -1800,12 +1800,16 @@ void pim_upstream_start_register_stop_timer(struct pim_upstream *up, THREAD_OFF(up->t_rs_timer); if (!null_register) { - uint32_t lower = (0.5 * PIM_REGISTER_SUPPRESSION_PERIOD); - uint32_t upper = (1.5 * PIM_REGISTER_SUPPRESSION_PERIOD); - time = lower + (frr_weak_random() % (upper - lower + 1)) - - PIM_REGISTER_PROBE_PERIOD; + 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 = PIM_REGISTER_PROBE_PERIOD; + time = router->register_probe_time; if (PIM_DEBUG_PIM_TRACE) { zlog_debug( -- 2.39.5