From a38ed18a4ed77a31584f2692da6f40fb53cd47fe Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Tue, 10 May 2022 08:23:40 -0300 Subject: [PATCH] pimd: implement MSDP peer SA limiting Implement a command to enable/disable per peer MSDP SA limiting. Signed-off-by: Rafael Zalamena --- pimd/pim_cmd.c | 24 ++++++++++++++++++++++++ pimd/pim_msdp.c | 12 ++++++++++++ pimd/pim_msdp.h | 3 +++ pimd/pim_nb_config.c | 4 ++-- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index f4c25ea81e..c2d88f400e 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -7578,6 +7578,29 @@ DEFPY(msdp_shutdown, return nb_cli_apply_changes(vty, NULL); } +DEFPY(msdp_peer_sa_limit, msdp_peer_sa_limit_cmd, + "[no] msdp peer A.B.C.D$peer sa-limit ![(1-4294967294)$sa_limit]", + NO_STR + CFG_MSDP_STR + "Configure MSDP peer\n" + "MSDP peer address\n" + "Limit amount of SA\n" + "Maximum number of SA\n") +{ + const struct lyd_node *peer_node; + char xpath[XPATH_MAXLEN + 24]; + + snprintf(xpath, sizeof(xpath), "%s/msdp-peer[peer-ip='%s']", VTY_CURR_XPATH, peer_str); + peer_node = yang_dnode_get(vty->candidate_config->dnode, xpath); + if (peer_node == NULL) { + vty_out(vty, "%% MSDP peer %s not yet configured\n", peer_str); + return CMD_SUCCESS; + } + + nb_cli_enqueue_change(vty, "./sa-limit", NB_OP_MODIFY, sa_limit_str); + return nb_cli_apply_changes(vty, "%s", xpath); +} + static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg, struct json_object *json) { @@ -8973,6 +8996,7 @@ void pim_cmd_init(void) 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, &msdp_peer_sa_limit_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 ae887b2482..bd86ca502d 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -359,6 +359,15 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp, struct rp_info *rp_info; struct prefix grp; + /* Check peer SA limit. */ + if (mp && mp->sa_limit && mp->sa_cnt >= mp->sa_limit) { + if (pim_msdp_log_sa_events(pim)) + zlog_debug("MSDP peer %pI4 reject SA (%pI4, %pI4): SA limit %u of %u", + &mp->peer, &sg->src, &sg->grp, mp->sa_cnt, mp->sa_limit); + + return; + } + sa = pim_msdp_sa_add(pim, sg, rp); if (!sa) { return; @@ -1316,6 +1325,9 @@ bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim) vty_out(vty, " msdp peer %pI4 sa-filter %s out\n", &mp->peer, mp->acl_out); + if (mp->sa_limit) + vty_out(vty, " msdp peer %pI4 sa-limit %u\n", &mp->peer, mp->sa_limit); + written = true; } diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h index d0aa83d997..15ed685b3c 100644 --- a/pimd/pim_msdp.h +++ b/pimd/pim_msdp.h @@ -152,6 +152,9 @@ struct pim_msdp_peer { char *acl_in; /** SA output access list name. */ char *acl_out; + + /** SA maximum amount. */ + uint32_t sa_limit; }; struct pim_msdp_mg_mbr { diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index b563bf5a30..fbba045982 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -1595,7 +1595,7 @@ int pim_msdp_peer_sa_limit_modify(struct nb_cb_modify_args *args) break; case NB_EV_APPLY: mp = nb_running_get_entry(args->dnode, NULL, true); - /* TODO: apply limitation. */ + mp->sa_limit = yang_dnode_get_uint32(args->dnode, NULL); break; } @@ -1614,7 +1614,7 @@ int pim_msdp_peer_sa_limit_destroy(struct nb_cb_destroy_args *args) break; case NB_EV_APPLY: mp = nb_running_get_entry(args->dnode, NULL, true); - /* TODO: remove limitation. */ + mp->sa_limit = 0; break; }