mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
Merge ba6371f9bb
into 3dd4d417be
This commit is contained in:
commit
f6457d25c4
|
@ -179,9 +179,9 @@ PIM Routers
|
|||
|
||||
Modify the join/prune interval that pim uses to the new value. Time is
|
||||
specified in seconds. This command is vrf aware, to configure for a vrf,
|
||||
enter the vrf submode. The default time is 60 seconds. If you enter
|
||||
a value smaller than 60 seconds be aware that this can and will affect
|
||||
convergence at scale.
|
||||
enter the vrf submode. This command is also be set per-interface level.
|
||||
The default time is 60 seconds. If you enter a value smaller than 60
|
||||
seconds be aware that this can and will affect convergence at scale.
|
||||
|
||||
.. clicmd:: keep-alive-timer (1-65535)
|
||||
|
||||
|
@ -384,6 +384,23 @@ is in a vrf, enter the interface command with the vrf keyword at the end.
|
|||
|
||||
Set the pim hello and hold interval for a interface.
|
||||
|
||||
.. clicmd:: ip pim join-prune-interval (5-600)
|
||||
|
||||
Modify the join/prune interval that pim uses on this interface. Defaults
|
||||
to the globally configured value (which in turn defaults to 60 seconds.)
|
||||
If you enter a value smaller than 60 seconds be aware that this can and
|
||||
will affect convergence at scale.
|
||||
|
||||
.. clicmd:: ip pim assert-interval (1000-86400000)
|
||||
|
||||
Modify the PIM assert interval in milliseconds on this interface
|
||||
(defaults to 18000).
|
||||
|
||||
.. clicmd:: ip pim assert-override-interval (1000-86400000)
|
||||
|
||||
Modify the PIM assert override interval in milliseconds on this
|
||||
interface (defaults to 3000).
|
||||
|
||||
.. clicmd:: ip pim
|
||||
|
||||
Tell pim that we would like to use this interface to form pim neighbors
|
||||
|
|
|
@ -154,6 +154,16 @@ PIMv6 Router
|
|||
a value smaller than 60 seconds be aware that this can and will affect
|
||||
convergence at scale.
|
||||
|
||||
.. clicmd:: ip pim assert-interval (1000-86400000)
|
||||
|
||||
Modify the PIM assert interval in milliseconds on this interface
|
||||
(defaults to 18000).
|
||||
|
||||
.. clicmd:: ip pim assert-override-interval (1000-86400000)
|
||||
|
||||
Modify the PIM assert override interval in milliseconds on this
|
||||
interface (defaults to 3000).
|
||||
|
||||
.. clicmd:: keep-alive-timer (1-65535)
|
||||
|
||||
Modify the time out value for a S,G flow from 1-65535 seconds. If choosing
|
||||
|
|
|
@ -190,6 +190,40 @@ DEFPY_ATTR(no_ipv6_pim_joinprune_time,
|
|||
return ret;
|
||||
}
|
||||
|
||||
DEFPY_YANG(if_ipv6_pim_assert_interval,
|
||||
if_ipv6_pim_assert_interval_cmd,
|
||||
"[no] ipv6 pim assert-interval ![(1000-86400000)$at]",
|
||||
NO_STR
|
||||
IPV6_STR
|
||||
PIM_STR
|
||||
"Assert timer\n"
|
||||
"Milliseconds, default 180000\n")
|
||||
{
|
||||
if (no)
|
||||
nb_cli_enqueue_change(vty, "./assert-interval", NB_OP_DESTROY, NULL);
|
||||
else
|
||||
nb_cli_enqueue_change(vty, "./assert-interval", NB_OP_MODIFY, at_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
|
||||
}
|
||||
|
||||
DEFPY_YANG(if_ipv6_pim_assert_override_interval,
|
||||
if_ipv6_pim_assert_override_interval_cmd,
|
||||
"[no] ipv6 pim assert-override-interval ![(1000-86400000)$at]",
|
||||
NO_STR
|
||||
IPV6_STR
|
||||
PIM_STR
|
||||
"Assert timer\n"
|
||||
"Milliseconds, default 3000\n")
|
||||
{
|
||||
if (no)
|
||||
nb_cli_enqueue_change(vty, "./assert-override-interval", NB_OP_DESTROY, NULL);
|
||||
else
|
||||
nb_cli_enqueue_change(vty, "./assert-override-interval", NB_OP_MODIFY, at_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
|
||||
}
|
||||
|
||||
DEFPY (pim6_spt_switchover_infinity,
|
||||
pim6_spt_switchover_infinity_cmd,
|
||||
"spt-switchover infinity-and-beyond",
|
||||
|
@ -884,6 +918,23 @@ DEFPY (interface_no_ipv6_pim_hello,
|
|||
return pim_process_no_ip_pim_hello_cmd(vty);
|
||||
}
|
||||
|
||||
DEFPY_YANG(if_ipv6_pim_joinprune_time,
|
||||
if_ipv6_pim_joinprune_time_cmd,
|
||||
"[no] ipv6 pim join-prune-interval ![(5-600)$jpt]",
|
||||
NO_STR
|
||||
IPV6_STR
|
||||
PIM_STR
|
||||
"Join Prune Send Interval\n"
|
||||
"Seconds\n")
|
||||
{
|
||||
if (no)
|
||||
nb_cli_enqueue_change(vty, "./join-prune-interval", NB_OP_DESTROY, NULL);
|
||||
else
|
||||
nb_cli_enqueue_change(vty, "./join-prune-interval", NB_OP_MODIFY, jpt_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
|
||||
}
|
||||
|
||||
DEFPY (interface_ipv6_pim_activeactive,
|
||||
interface_ipv6_pim_activeactive_cmd,
|
||||
"[no] ipv6 pim active-active",
|
||||
|
@ -2974,6 +3025,7 @@ void pim_cmd_init(void)
|
|||
install_element(INTERFACE_NODE, &interface_no_ipv6_pim_drprio_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ipv6_pim_hello_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_no_ipv6_pim_hello_cmd);
|
||||
install_element(INTERFACE_NODE, &if_ipv6_pim_joinprune_time_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ipv6_pim_activeactive_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ipv6_pim_ssm_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_no_ipv6_pim_ssm_cmd);
|
||||
|
@ -2985,6 +3037,8 @@ void pim_cmd_init(void)
|
|||
install_element(INTERFACE_NODE, &interface_no_ipv6_mroute_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ipv6_mld_limits_cmd);
|
||||
install_element(INTERFACE_NODE, &no_interface_ipv6_mld_limits_cmd);
|
||||
install_element(INTERFACE_NODE, &if_ipv6_pim_assert_interval_cmd);
|
||||
install_element(INTERFACE_NODE, &if_ipv6_pim_assert_override_interval_cmd);
|
||||
|
||||
install_element(INTERFACE_NODE, &interface_ipv6_pim_use_source_cmd);
|
||||
|
||||
|
|
|
@ -543,8 +543,8 @@ static void pim_assert_timer_set(struct pim_ifchannel *ch, int interval)
|
|||
assert_timer_off(ch);
|
||||
|
||||
if (PIM_DEBUG_PIM_TRACE) {
|
||||
zlog_debug("%s: (S,G)=%s starting %u sec timer on interface %s",
|
||||
__func__, ch->sg_str, interval, ch->interface->name);
|
||||
zlog_debug("%s: (S,G)=%s starting %ums timer on interface %s", __func__, ch->sg_str,
|
||||
interval, ch->interface->name);
|
||||
}
|
||||
|
||||
event_add_timer(router->master, on_assert_timer, ch, interval,
|
||||
|
@ -553,8 +553,14 @@ static void pim_assert_timer_set(struct pim_ifchannel *ch, int interval)
|
|||
|
||||
static void pim_assert_timer_reset(struct pim_ifchannel *ch)
|
||||
{
|
||||
pim_assert_timer_set(ch,
|
||||
PIM_ASSERT_TIME - PIM_ASSERT_OVERRIDE_INTERVAL);
|
||||
struct pim_interface *pim_ifp = ch->interface->info;
|
||||
int override = pim_ifp->assert_override_msec;
|
||||
|
||||
if (override == -1)
|
||||
override = pim_ifp->assert_msec / 75 + 600;
|
||||
|
||||
/* limit to at least 0.1s to avoid excessive CPU usage */
|
||||
pim_assert_timer_set(ch, MAX(pim_ifp->assert_msec - override, 100));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -614,10 +620,12 @@ int assert_action_a1(struct pim_ifchannel *ch)
|
|||
static void assert_action_a2(struct pim_ifchannel *ch,
|
||||
struct pim_assert_metric winner_metric)
|
||||
{
|
||||
struct pim_interface *pim_ifp = ch->interface->info;
|
||||
|
||||
pim_ifassert_winner_set(ch, PIM_IFASSERT_I_AM_LOSER,
|
||||
winner_metric.ip_address, winner_metric);
|
||||
|
||||
pim_assert_timer_set(ch, PIM_ASSERT_TIME);
|
||||
pim_assert_timer_set(ch, pim_ifp->assert_msec);
|
||||
|
||||
if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER) {
|
||||
if (PIM_DEBUG_PIM_EVENTS)
|
||||
|
|
|
@ -35,8 +35,11 @@ struct pim_assert_metric {
|
|||
Holdtime field. Thus, changing the Assert Time from the default
|
||||
value is not recommended.
|
||||
*/
|
||||
#define PIM_ASSERT_OVERRIDE_INTERVAL (3) /* seconds */
|
||||
#define PIM_ASSERT_TIME (180) /* seconds */
|
||||
#define PIM_ASSERT_TIME (180000) /* milliseconds */
|
||||
/* override timer calculated as (assert / 75 + 600ms) in pim_assert.c; yields
|
||||
* spec default of 3s for 180s; (the linear add of 600ms makes much more
|
||||
* sense for relatively low values of the assert timer.)
|
||||
*/
|
||||
|
||||
#define PIM_ASSERT_METRIC_PREFERENCE_MAX (0xFFFFFFFF)
|
||||
#define PIM_ASSERT_ROUTE_METRIC_MAX (0xFFFFFFFF)
|
||||
|
|
|
@ -6063,6 +6063,55 @@ ALIAS (interface_ip_pim_neighbor_prefix_list,
|
|||
"Restrict allowed PIM neighbors\n"
|
||||
"Use prefix-list to filter neighbors\n")
|
||||
|
||||
DEFPY_YANG(interface_ip_pim_joinprune_time,
|
||||
interface_ip_pim_joinprune_time_cmd,
|
||||
"[no] ip pim join-prune-interval ![(5-600)$jpt]",
|
||||
NO_STR
|
||||
IP_STR
|
||||
"pim multicast routing\n"
|
||||
"Join Prune Send Interval\n"
|
||||
"Seconds\n")
|
||||
{
|
||||
if (no)
|
||||
nb_cli_enqueue_change(vty, "./join-prune-interval", NB_OP_DESTROY, NULL);
|
||||
else
|
||||
nb_cli_enqueue_change(vty, "./join-prune-interval", NB_OP_MODIFY, jpt_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
|
||||
}
|
||||
|
||||
DEFPY_YANG(interface_ip_pim_assert_interval, interface_ip_pim_assert_interval_cmd,
|
||||
"[no] ip pim assert-interval ![(1000-86400000)$at]",
|
||||
NO_STR
|
||||
IP_STR
|
||||
"pim multicast routing\n"
|
||||
"Assert timer\n"
|
||||
"Milliseconds, default 180000\n")
|
||||
{
|
||||
if (no)
|
||||
nb_cli_enqueue_change(vty, "./assert-interval", NB_OP_DESTROY, NULL);
|
||||
else
|
||||
nb_cli_enqueue_change(vty, "./assert-interval", NB_OP_MODIFY, at_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
|
||||
}
|
||||
|
||||
DEFPY_YANG(interface_ip_pim_assert_override, interface_ip_pim_assert_override_cmd,
|
||||
"[no] ip pim assert-override-interval ![(1000-86400000)$ao]",
|
||||
NO_STR
|
||||
IP_STR
|
||||
"pim multicast routing\n"
|
||||
"Assert override interval\n"
|
||||
"Milliseconds, default calculated as 3000\n")
|
||||
{
|
||||
if (no)
|
||||
nb_cli_enqueue_change(vty, "./assert-override-interval", NB_OP_DESTROY, NULL);
|
||||
else
|
||||
nb_cli_enqueue_change(vty, "./assert-override-interval", NB_OP_MODIFY, ao_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
|
||||
}
|
||||
|
||||
DEFUN (debug_igmp,
|
||||
debug_igmp_cmd,
|
||||
"debug igmp",
|
||||
|
@ -9193,12 +9242,15 @@ void pim_cmd_init(void)
|
|||
install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ip_pim_joinprune_time_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ip_pim_boundary_acl_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ip_pim_neighbor_prefix_list_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_no_ip_pim_neighbor_prefix_list_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ip_pim_assert_interval_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ip_pim_assert_override_cmd);
|
||||
|
||||
// Static mroutes NEB
|
||||
install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
|
||||
|
|
|
@ -130,6 +130,9 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool gm, bool pim,
|
|||
pim_ifp->gm_last_member_query_count = GM_DEFAULT_ROBUSTNESS_VARIABLE;
|
||||
pim_ifp->gm_group_limit = UINT32_MAX;
|
||||
pim_ifp->gm_source_limit = UINT32_MAX;
|
||||
pim_ifp->periodic_jp_sec = -1;
|
||||
pim_ifp->assert_msec = PIM_ASSERT_TIME;
|
||||
pim_ifp->assert_override_msec = -1;
|
||||
|
||||
/* BSM config on interface: true by default */
|
||||
pim_ifp->bsm_enable = true;
|
||||
|
@ -1140,6 +1143,19 @@ uint16_t pim_if_jp_override_interval_msec(struct interface *ifp)
|
|||
+ pim_if_effective_override_interval_msec(ifp);
|
||||
}
|
||||
|
||||
int pim_if_jp_period(const struct pim_interface *pim_interface)
|
||||
{
|
||||
if (pim_interface->periodic_jp_sec != -1)
|
||||
return pim_interface->periodic_jp_sec;
|
||||
|
||||
return router->t_periodic;
|
||||
}
|
||||
|
||||
int pim_if_jp_hold(const struct pim_interface *pim_interface)
|
||||
{
|
||||
return pim_if_jp_period(pim_interface) * 7 / 2;
|
||||
}
|
||||
|
||||
/*
|
||||
RFC 4601: 4.1.6. State Summarization Macros
|
||||
|
||||
|
@ -1202,7 +1218,7 @@ long pim_if_t_suppressed_msec(struct interface *ifp)
|
|||
|
||||
/* t_suppressed = t_periodic * rand(1.1, 1.4) */
|
||||
ramount = 1100 + (frr_weak_random() % (1400 - 1100 + 1));
|
||||
t_suppressed_msec = router->t_periodic * ramount;
|
||||
t_suppressed_msec = pim_if_jp_period(pim_ifp) * ramount;
|
||||
|
||||
return t_suppressed_msec;
|
||||
}
|
||||
|
|
|
@ -126,6 +126,11 @@ struct pim_interface {
|
|||
struct list *upstream_switch_list;
|
||||
struct pim_ifchannel_rb ifchannel_rb;
|
||||
|
||||
/* Periodic join prune interval (-1 means `router->t_periodic`). */
|
||||
int periodic_jp_sec;
|
||||
int assert_msec;
|
||||
int assert_override_msec;
|
||||
|
||||
/* neighbors without lan_delay */
|
||||
int pim_number_of_nonlandelay_neighbors;
|
||||
uint16_t pim_neighbors_highest_propagation_delay_msec;
|
||||
|
@ -220,6 +225,8 @@ int pim_if_lan_delay_enabled(struct interface *ifp);
|
|||
uint16_t pim_if_effective_propagation_delay_msec(struct interface *ifp);
|
||||
uint16_t pim_if_effective_override_interval_msec(struct interface *ifp);
|
||||
uint16_t pim_if_jp_override_interval_msec(struct interface *ifp);
|
||||
int pim_if_jp_period(const struct pim_interface *pim_interface);
|
||||
int pim_if_jp_hold(const struct pim_interface *pim_interface);
|
||||
struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp, pim_addr addr);
|
||||
|
||||
long pim_if_t_suppressed_msec(struct interface *ifp);
|
||||
|
|
|
@ -490,7 +490,7 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
|
|||
pim_msg_addr_encode_ucast((uint8_t *)&msg->addr,
|
||||
rpf->rpf_addr);
|
||||
msg->reserved = 0;
|
||||
msg->holdtime = htons(PIM_JP_HOLDTIME);
|
||||
msg->holdtime = htons(pim_if_jp_hold(pim_ifp));
|
||||
|
||||
new_packet = false;
|
||||
|
||||
|
@ -533,7 +533,7 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
|
|||
pim_msg_addr_encode_ucast((uint8_t *)&msg->addr,
|
||||
rpf->rpf_addr);
|
||||
msg->reserved = 0;
|
||||
msg->holdtime = htons(PIM_JP_HOLDTIME);
|
||||
msg->holdtime = htons(pim_if_jp_hold(pim_ifp));
|
||||
|
||||
new_packet = false;
|
||||
|
||||
|
|
|
@ -321,6 +321,26 @@ const struct frr_yang_module_info frr_pim_info = {
|
|||
.destroy = lib_interface_pim_address_family_nbr_plist_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family/join-prune-interval",
|
||||
.cbs = {
|
||||
.modify = lib_interface_pim_address_family_join_prune_interval_modify,
|
||||
.destroy = lib_interface_pim_address_family_join_prune_interval_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family/assert-interval",
|
||||
.cbs = {
|
||||
.modify = lib_interface_pim_assert_interval_modify,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family/assert-override-interval",
|
||||
.cbs = {
|
||||
.modify = lib_interface_pim_assert_override_interval_modify,
|
||||
.destroy = lib_interface_pim_assert_override_interval_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family/bfd",
|
||||
.cbs = {
|
||||
|
|
|
@ -112,6 +112,9 @@ int lib_interface_pim_address_family_dr_priority_modify(
|
|||
struct nb_cb_modify_args *args);
|
||||
int lib_interface_pim_address_family_nbr_plist_modify(struct nb_cb_modify_args *args);
|
||||
int lib_interface_pim_address_family_nbr_plist_destroy(struct nb_cb_destroy_args *args);
|
||||
int lib_interface_pim_assert_interval_modify(struct nb_cb_modify_args *args);
|
||||
int lib_interface_pim_assert_override_interval_modify(struct nb_cb_modify_args *args);
|
||||
int lib_interface_pim_assert_override_interval_destroy(struct nb_cb_destroy_args *args);
|
||||
int lib_interface_pim_address_family_create(struct nb_cb_create_args *args);
|
||||
int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args *args);
|
||||
int lib_interface_pim_address_family_pim_enable_modify(
|
||||
|
@ -124,6 +127,8 @@ int lib_interface_pim_address_family_hello_holdtime_modify(
|
|||
struct nb_cb_modify_args *args);
|
||||
int lib_interface_pim_address_family_hello_holdtime_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
int lib_interface_pim_address_family_join_prune_interval_modify(struct nb_cb_modify_args *args);
|
||||
int lib_interface_pim_address_family_join_prune_interval_destroy(struct nb_cb_destroy_args *args);
|
||||
int lib_interface_pim_address_family_bfd_create(struct nb_cb_create_args *args);
|
||||
int lib_interface_pim_address_family_bfd_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
|
|
|
@ -2212,6 +2212,109 @@ int lib_interface_pim_address_family_nbr_plist_destroy(struct nb_cb_destroy_args
|
|||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/join-prune-interval
|
||||
*/
|
||||
int lib_interface_pim_address_family_join_prune_interval_modify(struct nb_cb_modify_args *args)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct pim_interface *pim_ifp;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_ABORT:
|
||||
case NB_EV_PREPARE:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim_ifp = ifp->info;
|
||||
pim_ifp->periodic_jp_sec = yang_dnode_get_uint16(args->dnode, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int lib_interface_pim_address_family_join_prune_interval_destroy(struct nb_cb_destroy_args *args)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct pim_interface *pim_ifp;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_ABORT:
|
||||
case NB_EV_PREPARE:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim_ifp = ifp->info;
|
||||
pim_ifp->periodic_jp_sec = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int lib_interface_pim_assert_interval_modify(struct nb_cb_modify_args *args)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct pim_interface *pim_ifp;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_ABORT:
|
||||
case NB_EV_PREPARE:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim_ifp = ifp->info;
|
||||
pim_ifp->assert_msec = yang_dnode_get_uint32(args->dnode, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int lib_interface_pim_assert_override_interval_modify(struct nb_cb_modify_args *args)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct pim_interface *pim_ifp;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_ABORT:
|
||||
case NB_EV_PREPARE:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim_ifp = ifp->info;
|
||||
pim_ifp->assert_override_msec = yang_dnode_get_uint32(args->dnode, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int lib_interface_pim_assert_override_interval_destroy(struct nb_cb_destroy_args *args)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct pim_interface *pim_ifp;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_ABORT:
|
||||
case NB_EV_PREPARE:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim_ifp = ifp->info;
|
||||
pim_ifp->assert_override_msec = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
|
||||
*/
|
||||
|
|
|
@ -255,15 +255,15 @@ static void on_neighbor_jp_timer(struct event *t)
|
|||
rpf.rpf_addr = neigh->source_addr;
|
||||
pim_joinprune_send(&rpf, neigh->upstream_jp_agg);
|
||||
|
||||
event_add_timer(router->master, on_neighbor_jp_timer, neigh,
|
||||
router->t_periodic, &neigh->jp_timer);
|
||||
event_add_timer(router->master, on_neighbor_jp_timer, neigh, pim_neigh_jp_period(neigh),
|
||||
&neigh->jp_timer);
|
||||
}
|
||||
|
||||
static void pim_neighbor_start_jp_timer(struct pim_neighbor *neigh)
|
||||
{
|
||||
EVENT_OFF(neigh->jp_timer);
|
||||
event_add_timer(router->master, on_neighbor_jp_timer, neigh,
|
||||
router->t_periodic, &neigh->jp_timer);
|
||||
event_add_timer(router->master, on_neighbor_jp_timer, neigh, pim_neigh_jp_period(neigh),
|
||||
&neigh->jp_timer);
|
||||
}
|
||||
|
||||
static struct pim_neighbor *
|
||||
|
|
|
@ -35,6 +35,12 @@ struct pim_neighbor {
|
|||
struct bfd_session_params *bfd_session;
|
||||
};
|
||||
|
||||
static inline int pim_neigh_jp_period(const struct pim_neighbor *neigh)
|
||||
{
|
||||
const struct pim_interface *pim_ifp = neigh->interface->info;
|
||||
return pim_if_jp_period(pim_ifp);
|
||||
}
|
||||
|
||||
void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime);
|
||||
void pim_neighbor_free(struct pim_neighbor *neigh);
|
||||
struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
|
||||
|
|
|
@ -346,26 +346,38 @@ static void join_timer_stop(struct pim_upstream *up)
|
|||
|
||||
void join_timer_start(struct pim_upstream *up)
|
||||
{
|
||||
const struct pim_interface *pim_interface = NULL;
|
||||
struct pim_neighbor *nbr = NULL;
|
||||
|
||||
if (up->rpf.source_nexthop.interface) {
|
||||
pim_interface = up->rpf.source_nexthop.interface->info;
|
||||
nbr = pim_neighbor_find(up->rpf.source_nexthop.interface,
|
||||
up->rpf.rpf_addr, true);
|
||||
}
|
||||
|
||||
if (nbr) {
|
||||
if (PIM_DEBUG_PIM_EVENTS) {
|
||||
zlog_debug("%s: starting %d sec timer for upstream (S,G)=%s neighbor %pPA",
|
||||
__func__, pim_neigh_jp_period(nbr), up->sg_str,
|
||||
&nbr->source_addr);
|
||||
}
|
||||
|
||||
pim_jp_agg_add_group(nbr->upstream_jp_agg, up, 1, nbr);
|
||||
} else {
|
||||
int t_periodic = router->t_periodic;
|
||||
|
||||
if (pim_interface)
|
||||
t_periodic = pim_if_jp_period(pim_interface);
|
||||
|
||||
if (PIM_DEBUG_PIM_EVENTS) {
|
||||
zlog_debug(
|
||||
"%s: starting %d sec timer for upstream (S,G)=%s",
|
||||
__func__, router->t_periodic, up->sg_str);
|
||||
zlog_debug("%s: starting %d sec timer for upstream (S,G)=%s", __func__,
|
||||
t_periodic, up->sg_str);
|
||||
}
|
||||
|
||||
EVENT_OFF(up->t_join_timer);
|
||||
event_add_timer(router->master, on_join_timer, up, t_periodic, &up->t_join_timer);
|
||||
}
|
||||
|
||||
if (nbr)
|
||||
pim_jp_agg_add_group(nbr->upstream_jp_agg, up, 1, nbr);
|
||||
else {
|
||||
EVENT_OFF(up->t_join_timer);
|
||||
event_add_timer(router->master, on_join_timer, up,
|
||||
router->t_periodic, &up->t_join_timer);
|
||||
}
|
||||
pim_jp_agg_upstream_verification(up, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -501,6 +501,23 @@ int pim_config_write(struct vty *vty, int writes, struct interface *ifp,
|
|||
|
||||
writes += gm_config_write(vty, writes, pim_ifp);
|
||||
|
||||
if (pim_ifp->periodic_jp_sec != -1) {
|
||||
vty_out(vty, " " PIM_AF_NAME " pim join-prune-interval %d\n",
|
||||
pim_ifp->periodic_jp_sec);
|
||||
++writes;
|
||||
}
|
||||
|
||||
if (pim_ifp->assert_msec != PIM_ASSERT_TIME) {
|
||||
vty_out(vty, " " PIM_AF_NAME " pim assert-interval %d\n", pim_ifp->assert_msec);
|
||||
++writes;
|
||||
}
|
||||
|
||||
if (pim_ifp->assert_override_msec != -1) {
|
||||
vty_out(vty, " " PIM_AF_NAME " pim assert-override-interval %d\n",
|
||||
pim_ifp->assert_override_msec);
|
||||
++writes;
|
||||
}
|
||||
|
||||
/* update source */
|
||||
if (!pim_addr_is_any(pim_ifp->update_source)) {
|
||||
vty_out(vty, " " PIM_AF_NAME " pim use-source %pPA\n",
|
||||
|
|
|
@ -509,6 +509,7 @@ def _enable_disable_pim_config(tgen, topo, input_dict, router, build=False):
|
|||
cmd = "interface {}".format(interface_name)
|
||||
config_data.append(cmd)
|
||||
config_data.append("ip pim")
|
||||
config_data.append("exit")
|
||||
|
||||
if "pim" in input_dict[router]:
|
||||
if "disable" in input_dict[router]["pim"]:
|
||||
|
|
|
@ -522,6 +522,34 @@ module frr-pim {
|
|||
"Prefix-List to filter allowed PIM neighbors.";
|
||||
}
|
||||
|
||||
leaf join-prune-interval {
|
||||
type uint16 {
|
||||
range "5..600";
|
||||
}
|
||||
description
|
||||
"Join Prune Send Interval in seconds (defaults to global value).";
|
||||
}
|
||||
|
||||
leaf assert-interval {
|
||||
type uint32 {
|
||||
range "1000..86400000";
|
||||
}
|
||||
default "180000";
|
||||
description
|
||||
"Assert interval in milliseconds. (defaults to 180s)";
|
||||
}
|
||||
|
||||
leaf assert-override-interval {
|
||||
type uint32 {
|
||||
range "1000..86400000";
|
||||
}
|
||||
must ". < ./../assert-interval - 100" {
|
||||
error-message "Assert override interval must be at least 0.1s smaller than assert interval.";
|
||||
}
|
||||
description
|
||||
"Assert override interval in milliseconds. (calculated from assert interval by default)";
|
||||
}
|
||||
|
||||
container bfd {
|
||||
presence
|
||||
"Enable BFD support on the interface.";
|
||||
|
|
Loading…
Reference in a new issue