diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index c4afd04a07..cc11a3cc17 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -9699,6 +9699,38 @@ DEFPY(ip_msdp_peer, ip_msdp_peer_cmd, return nb_cli_apply_changes(vty, NULL); } +DEFPY(ip_msdp_timers, ip_msdp_timers_cmd, + "ip msdp timers (2-600)$keepalive (3-600)$holdtime [(1-600)$connretry]", + IP_STR + CFG_MSDP_STR + "MSDP timers configuration\n" + "Keep alive period (in seconds)\n" + "Hold time period (in seconds)\n" + "Connection retry period (in seconds)\n") +{ + const char *vrfname; + char xpath[XPATH_MAXLEN]; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname == NULL) + return CMD_WARNING_CONFIG_FAILED; + + snprintf(xpath, sizeof(xpath), FRR_PIM_MSDP_XPATH, "frr-pim:pimd", + "pim", vrfname, "frr-routing:ipv4"); + nb_cli_enqueue_change(vty, "./hold-time", NB_OP_MODIFY, holdtime_str); + nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_MODIFY, keepalive_str); + if (connretry_str) + nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_MODIFY, + connretry_str); + else + nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY, + NULL); + + nb_cli_apply_changes(vty, xpath); + + return CMD_SUCCESS; +} + DEFUN (no_ip_msdp_peer, no_ip_msdp_peer_cmd, "no ip msdp peer A.B.C.D", @@ -11322,6 +11354,8 @@ void pim_cmd_init(void) install_element(CONFIG_NODE, &debug_bsm_cmd); install_element(CONFIG_NODE, &no_debug_bsm_cmd); + install_element(CONFIG_NODE, &ip_msdp_timers_cmd); + install_element(VRF_NODE, &ip_msdp_timers_cmd); install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd); install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd); install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd); diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index 47358f38e1..6dda66b79a 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -125,6 +125,12 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf) pim_instance_mlag_init(pim); pim->last_route_change_time = -1; + + /* MSDP global timer defaults. */ + pim->msdp.hold_time = PIM_MSDP_PEER_HOLD_TIME; + pim->msdp.keep_alive = PIM_MSDP_PEER_KA_TIME; + pim->msdp.connection_retry = PIM_MSDP_PEER_CONNECT_RETRY_TIME; + return pim; } diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index be2df7693c..2a8f0c1216 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -918,7 +918,7 @@ static void pim_msdp_peer_hold_timer_setup(struct pim_msdp_peer *mp, bool start) THREAD_OFF(mp->hold_timer); if (start) { thread_add_timer(pim->msdp.master, pim_msdp_peer_hold_timer_cb, - mp, PIM_MSDP_PEER_HOLD_TIME, &mp->hold_timer); + mp, pim->msdp.hold_time, &mp->hold_timer); } } @@ -944,7 +944,7 @@ static void pim_msdp_peer_ka_timer_setup(struct pim_msdp_peer *mp, bool start) if (start) { thread_add_timer(mp->pim->msdp.master, pim_msdp_peer_ka_timer_cb, mp, - PIM_MSDP_PEER_KA_TIME, &mp->ka_timer); + mp->pim->msdp.keep_alive, &mp->ka_timer); } } @@ -1006,9 +1006,9 @@ static void pim_msdp_peer_cr_timer_setup(struct pim_msdp_peer *mp, bool start) { THREAD_OFF(mp->cr_timer); if (start) { - thread_add_timer( - mp->pim->msdp.master, pim_msdp_peer_cr_timer_cb, mp, - PIM_MSDP_PEER_CONNECT_RETRY_TIME, &mp->cr_timer); + thread_add_timer(mp->pim->msdp.master, + pim_msdp_peer_cr_timer_cb, mp, + mp->pim->msdp.connection_retry, &mp->cr_timer); } } diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h index 6bf02f2b9f..a074f21b47 100644 --- a/pimd/pim_msdp.h +++ b/pimd/pim_msdp.h @@ -207,6 +207,13 @@ struct pim_msdp { /** List of mesh groups. */ struct pim_mesh_group_list mglist; + + /** MSDP global hold time period. */ + uint32_t hold_time; + /** MSDP global keep alive period. */ + uint32_t keep_alive; + /** MSDP global connection retry period. */ + uint32_t connection_retry; }; #define PIM_MSDP_PEER_READ_ON(mp) \ diff --git a/pimd/pim_nb.c b/pimd/pim_nb.c index 848a28d31a..6fe078bd8e 100644 --- a/pimd/pim_nb.c +++ b/pimd/pim_nb.c @@ -117,6 +117,24 @@ const struct frr_yang_module_info frr_pim_info = { .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy, } }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/hold-time", + .cbs = { + .modify = pim_msdp_hold_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/keep-alive", + .cbs = { + .modify = pim_msdp_keep_alive_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/connection-retry", + .cbs = { + .modify = pim_msdp_connection_retry_modify, + } + }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups", .cbs = { diff --git a/pimd/pim_nb.h b/pimd/pim_nb.h index 07387be763..f5ebbceb33 100644 --- a/pimd/pim_nb.h +++ b/pimd/pim_nb.h @@ -60,6 +60,9 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss struct nb_cb_create_args *args); int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy( struct nb_cb_destroy_args *args); +int pim_msdp_hold_time_modify(struct nb_cb_modify_args *args); +int pim_msdp_keep_alive_modify(struct nb_cb_modify_args *args); +int pim_msdp_connection_retry_modify(struct nb_cb_modify_args *args); int pim_msdp_mesh_group_create(struct nb_cb_create_args *args); int pim_msdp_mesh_group_destroy(struct nb_cb_destroy_args *args); int pim_msdp_mesh_group_members_create(struct nb_cb_create_args *args); @@ -190,4 +193,6 @@ int routing_control_plane_protocols_name_validate( #define FRR_IGMP_JOIN_XPATH \ "./frr-igmp:igmp/address-family[address-family='%s']/" \ "static-group[group-addr='%s'][source-addr='%s']" +#define FRR_PIM_MSDP_XPATH FRR_PIM_AF_XPATH "/msdp" + #endif /* _FRR_PIM_NB_H_ */ diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index d69ab3aeb6..dfdbd6dee2 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -945,6 +945,95 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss return NB_OK; } +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/hold-time + */ +int pim_msdp_hold_time_modify(struct nb_cb_modify_args *args) +{ + struct pim_instance *pim; + struct vrf *vrf; + + switch (args->event) { + case NB_EV_VALIDATE: + if (yang_dnode_get_uint32(args->dnode, NULL) + <= yang_dnode_get_uint32(args->dnode, "../keep-alive")) { + snprintf( + args->errmsg, args->errmsg_len, + "Hold time must be greater than keep alive interval"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + pim->msdp.hold_time = yang_dnode_get_uint32(args->dnode, NULL); + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/keep-alive + */ +int pim_msdp_keep_alive_modify(struct nb_cb_modify_args *args) +{ + struct pim_instance *pim; + struct vrf *vrf; + + switch (args->event) { + case NB_EV_VALIDATE: + if (yang_dnode_get_uint32(args->dnode, NULL) + >= yang_dnode_get_uint32(args->dnode, "../hold-time")) { + snprintf( + args->errmsg, args->errmsg_len, + "Keep alive must be less than hold time interval"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + pim->msdp.keep_alive = yang_dnode_get_uint32(args->dnode, NULL); + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/connection-retry + */ +int pim_msdp_connection_retry_modify(struct nb_cb_modify_args *args) +{ + struct pim_instance *pim; + struct vrf *vrf; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + pim->msdp.connection_retry = + yang_dnode_get_uint32(args->dnode, NULL); + break; + } + + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index c049ef4029..95882cf58f 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -263,6 +263,17 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty) } } + if (pim->msdp.hold_time != PIM_MSDP_PEER_HOLD_TIME + || pim->msdp.keep_alive != PIM_MSDP_PEER_KA_TIME + || pim->msdp.connection_retry != PIM_MSDP_PEER_CONNECT_RETRY_TIME) { + vty_out(vty, "%sip msdp timers %u %u", spaces, + pim->msdp.hold_time, pim->msdp.keep_alive); + if (pim->msdp.connection_retry + != PIM_MSDP_PEER_CONNECT_RETRY_TIME) + vty_out(vty, " %u", pim->msdp.connection_retry); + vty_out(vty, "\n"); + } + return writes; }