From 379dc9ee2f0df7944bf6e03d385db6b4f6bc9d5c Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Tue, 10 May 2022 08:23:33 -0300 Subject: [PATCH 1/3] pimd: implement MSDP shutdown command Allow MSDP protocol to be disabled. Signed-off-by: Rafael Zalamena --- pimd/pim_cmd.c | 19 +++++++++++++++++ pimd/pim_msdp.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ pimd/pim_msdp.h | 15 +++++++++++++ pimd/pim_nb.c | 6 ++++++ pimd/pim_nb.h | 1 + pimd/pim_nb_config.c | 27 ++++++++++++++++++++++++ yang/frr-pim.yang | 7 +++++++ 7 files changed, 125 insertions(+) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index a2a4c3493108..f4c25ea81ea9 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -7560,6 +7560,24 @@ DEFPY_ATTR(no_ip_pim_msdp_mesh_group, return ret; } +DEFPY(msdp_shutdown, + msdp_shutdown_cmd, + "[no] msdp shutdown", + NO_STR + CFG_MSDP_STR + "Shutdown MSDP operation\n") +{ + char xpath_value[XPATH_MAXLEN]; + + snprintf(xpath_value, sizeof(xpath_value), "./msdp/shutdown"); + if (no) + nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg, struct json_object *json) { @@ -8954,6 +8972,7 @@ void pim_cmd_init(void) install_element(PIM_NODE, &no_pim_msdp_mesh_group_cmd); install_element(PIM_NODE, &msdp_log_neighbor_changes_cmd); install_element(PIM_NODE, &msdp_log_sa_changes_cmd); + install_element(PIM_NODE, &msdp_shutdown_cmd); install_element(PIM_NODE, &pim_bsr_candidate_rp_cmd); install_element(PIM_NODE, &pim_bsr_candidate_rp_group_cmd); diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index a536ab6fe031..ae887b248253 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -734,6 +734,10 @@ static void pim_msdp_peer_state_chg_log(struct pim_msdp_peer *mp) * a tcp connection will be made */ static void pim_msdp_peer_connect(struct pim_msdp_peer *mp) { + /* Stop here if we are shutdown. */ + if (mp->pim->msdp.shutdown) + return; + mp->state = PIM_MSDP_CONNECTING; if (pim_msdp_log_neighbor_events(mp->pim)) pim_msdp_peer_state_chg_log(mp); @@ -744,6 +748,10 @@ static void pim_msdp_peer_connect(struct pim_msdp_peer *mp) /* 11.2.A3: passive peer - just listen for connections */ static void pim_msdp_peer_listen(struct pim_msdp_peer *mp) { + /* Stop here if we are shutdown. */ + if (mp->pim->msdp.shutdown) + return; + mp->state = PIM_MSDP_LISTEN; if (pim_msdp_log_neighbor_events(mp->pim)) pim_msdp_peer_state_chg_log(mp); @@ -1311,6 +1319,9 @@ bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim) written = true; } + if (pim->msdp.shutdown) + vty_out(vty, " msdp shutdown\n"); + return written; } @@ -1431,3 +1442,42 @@ struct pim_msdp_mg_mbr *pim_msdp_mg_mbr_add(struct pim_instance *pim, return mbr; } + +void pim_msdp_shutdown(struct pim_instance *pim, bool state) +{ + struct pim_msdp_peer *peer; + struct listnode *node; + + /* Same value nothing to do. */ + if (pim->msdp.shutdown == state) + return; + + if (state) { + pim->msdp.shutdown = true; + + for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, peer)) { + /* Stop the tcp connection and shutdown all timers */ + pim_msdp_peer_stop_tcp_conn(peer, true); + + /* Stop listening socket if any. */ + event_cancel(&peer->auth_listen_ev); + if (peer->auth_listen_sock != -1) + close(peer->auth_listen_sock); + + /* Disable and remove listener flag. */ + UNSET_FLAG(pim->msdp.flags, PIM_MSDPF_ENABLE | PIM_MSDPF_LISTENER); + } + } else { + pim->msdp.shutdown = false; + + for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, peer)) { + /* Start connection again. */ + if (PIM_MSDP_PEER_IS_LISTENER(peer)) + pim_msdp_peer_listen(peer); + else + pim_msdp_peer_connect(peer); + + SET_FLAG(pim->msdp.flags, PIM_MSDPF_ENABLE); + } + } +} diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h index 0a7c74e438e7..d0aa83d9978c 100644 --- a/pimd/pim_msdp.h +++ b/pimd/pim_msdp.h @@ -216,6 +216,9 @@ struct pim_msdp { uint32_t keep_alive; /** MSDP global connection retry period. */ uint32_t connection_retry; + + /** MSDP operation state. */ + bool shutdown; }; #define PIM_MSDP_PEER_READ_ON(mp) \ @@ -327,6 +330,14 @@ void pim_msdp_peer_change_source(struct pim_msdp_peer *mp, */ void pim_msdp_peer_restart(struct pim_msdp_peer *mp); +/** + * Toggle MSDP functionality administrative state. + * + * \param pim PIM instance we want to shutdown. + * \param state shutdown state. + */ +void pim_msdp_shutdown(struct pim_instance *pim, bool state); + #else /* PIM_IPV == 6 */ static inline void pim_msdp_init(struct pim_instance *pim, struct event_loop *master) @@ -370,6 +381,10 @@ static inline bool pim_msdp_peer_config_write(struct vty *vty, { return false; } + +static inline void pim_msdp_shutdown(struct pim_instance *pim, bool state) +{ +} #endif /* PIM_IPV == 6 */ #endif diff --git a/pimd/pim_nb.c b/pimd/pim_nb.c index c5a9c7f05562..4a5ad87942b2 100644 --- a/pimd/pim_nb.c +++ b/pimd/pim_nb.c @@ -141,6 +141,12 @@ const struct frr_yang_module_info frr_pim_info = { .modify = pim_msdp_log_sa_events_modify, } }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/shutdown", + .cbs = { + .modify = pim_msdp_shutdown_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 8412ef4a6e5a..a9693c65d8e6 100644 --- a/pimd/pim_nb.h +++ b/pimd/pim_nb.h @@ -56,6 +56,7 @@ 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_log_neighbor_events_modify(struct nb_cb_modify_args *args); int pim_msdp_log_sa_events_modify(struct nb_cb_modify_args *args); +int pim_msdp_shutdown_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); diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index e594a150fd2f..171614208f09 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -1098,6 +1098,7 @@ pim6_msdp_err(pim_msdp_peer_authentication_key_modify, nb_cb_modify_args); pim6_msdp_err(pim_msdp_peer_authentication_key_destroy, nb_cb_destroy_args); pim6_msdp_err(pim_msdp_log_neighbor_events_modify, nb_cb_modify_args); pim6_msdp_err(pim_msdp_log_sa_events_modify, nb_cb_modify_args); +pim6_msdp_err(pim_msdp_shutdown_modify, nb_cb_modify_args); #if PIM_IPV != 6 /* @@ -1158,6 +1159,32 @@ int pim_msdp_log_sa_events_modify(struct nb_cb_modify_args *args) return NB_OK; } +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/shutdown + */ +int pim_msdp_shutdown_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: + /* NOTHING */ + break; + + case NB_EV_APPLY: + vrf = nb_running_get_entry(args->dnode, NULL, true); + pim = vrf->info; + pim_msdp_shutdown(pim, yang_dnode_get_bool(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/yang/frr-pim.yang b/yang/frr-pim.yang index c3c953b76b42..33602fd29e60 100644 --- a/yang/frr-pim.yang +++ b/yang/frr-pim.yang @@ -264,6 +264,13 @@ module frr-pim { description "Log all MSDP SA related events."; } + + leaf shutdown { + type boolean; + default false; + description + "Shutdown MSDP functionality."; + } } list msdp-mesh-groups { From 2c79f3532e7121c938da69e4af16eee94ff01866 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Mon, 25 Nov 2024 11:32:46 -0300 Subject: [PATCH 2/3] topotests: test MSDP shutdown command New test step to check that MSDP shutdown command is working. Signed-off-by: Rafael Zalamena --- tests/topotests/msdp_topo1/test_msdp_topo1.py | 51 +++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/tests/topotests/msdp_topo1/test_msdp_topo1.py b/tests/topotests/msdp_topo1/test_msdp_topo1.py index 1c97f7cb1e47..8c25eeca06a6 100755 --- a/tests/topotests/msdp_topo1/test_msdp_topo1.py +++ b/tests/topotests/msdp_topo1/test_msdp_topo1.py @@ -521,15 +521,58 @@ def test_msdp_log_events(): r1_log = tgen.gears["r1"].net.getLog("log", "pimd") # Look up for informational messages that should have been enabled. - match = re.search( - "MSDP peer 192.168.1.2 state changed to established", r1_log) + match = re.search("MSDP peer 192.168.1.2 state changed to established", r1_log) assert match is not None - match = re.search( - r"MSDP SA \(192.168.10.100\,229.1.2.3\) created", r1_log) + match = re.search(r"MSDP SA \(192.168.10.100\,229.1.2.3\) created", r1_log) assert match is not None +def test_msdp_shutdown(): + "Shutdown MSDP sessions between r1, r2, r3, then check the state." + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + tgen.gears["r1"].vtysh_cmd( + """ + configure terminal + router pim + msdp shutdown + """ + ) + + r1_expect = { + "192.168.0.2": { + "state": "inactive", + }, + "192.168.1.2": { + "state": "inactive", + }, + } + r2_expect = { + "192.168.0.1": { + "state": "listen", + } + } + r3_expect = { + "192.168.1.1": { + "state": "listen", + } + } + for router in [("r1", r1_expect), ("r2", r2_expect), ("r3", r3_expect)]: + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router[0]], + "show ip msdp peer json", + router[1], + ) + logger.info("Waiting for {} msdp peer data".format(router[0])) + _, val = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert val is None, "multicast route convergence failure" + + def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() From cd8d9d3906ed925580605fa158d034ed24fe4a6e Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Mon, 25 Nov 2024 12:03:59 -0300 Subject: [PATCH 3/3] doc: document shutdown command Let users know about the MSDP shutdown command. Signed-off-by: Rafael Zalamena --- doc/user/pim.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/user/pim.rst b/doc/user/pim.rst index 0fe53247b05e..05418da5a990 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -478,6 +478,10 @@ Commands available for MSDP To apply it immediately call `clear ip msdp peer A.B.C.D`. +.. clicmd:: msdp shutdown + + Shutdown the MSDP sessions in this PIM instance. + .. _show-pim-information: