From aa50f5ebb88ef24cf1d95e0ce9061366d8ab37c5 Mon Sep 17 00:00:00 2001 From: Acee Lindem Date: Mon, 3 Mar 2025 22:46:01 +0000 Subject: [PATCH] bfdd: Add BFD "log-session-changes" feature. Add the BFD "log-session-changes" via the YANG and northbound API. Also add the configured value to show and operational state. Signed-off-by: Acee Lindem --- bfdd/bfd.c | 41 ++++++++++++++++++++++++++++++++++++ bfdd/bfd.h | 34 ++++++++++++++++++++---------- bfdd/bfdd_cli.c | 20 ++++++++++++++++++ bfdd/bfdd_nb.c | 35 +++++++++++++++++++++++++++++++ bfdd/bfdd_nb.h | 4 ++++ bfdd/bfdd_nb_config.c | 49 +++++++++++++++++++++++++++++++++++++++++++ bfdd/bfdd_vty.c | 6 +++++- bfdd/dplane.c | 7 ++++++- 8 files changed, 183 insertions(+), 13 deletions(-) diff --git a/bfdd/bfd.c b/bfdd/bfd.c index fade89d04f..8d5306aaaf 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -79,6 +79,7 @@ static void bfd_profile_set_default(struct bfd_profile *bp) bp->detection_multiplier = BFD_DEFDETECTMULT; bp->echo_mode = false; bp->passive = false; + bp->log_session_changes = false; bp->minimum_ttl = BFD_DEF_MHOP_TTL; bp->min_echo_rx = BFD_DEF_REQ_MIN_ECHO_RX; bp->min_echo_tx = BFD_DEF_DES_MIN_ECHO_TX; @@ -210,6 +211,12 @@ void bfd_session_apply(struct bfd_session *bs) else bfd_set_shutdown(bs, bs->peer_profile.admin_shutdown); + /* Toggle 'no log-session-changes' if default value. */ + if (bs->peer_profile.log_session_changes == false) + bfd_set_log_session_changes(bs, bp->log_session_changes); + else + bfd_set_log_session_changes(bs, bs->peer_profile.log_session_changes); + /* If session interval changed negotiate new timers. */ if (bs->ses_state == PTM_BFD_UP && (bs->timers.desired_min_tx != min_tx @@ -574,6 +581,9 @@ void ptm_bfd_sess_up(struct bfd_session *bfd) zlog_debug("state-change: [%s] %s -> %s", bs_to_string(bfd), state_list[old_state].str, state_list[bfd->ses_state].str); + if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES)) + zlog_notice("Session-Change: [%s] %s -> %s", bs_to_string(bfd), + state_list[old_state].str, state_list[bfd->ses_state].str); } } @@ -621,6 +631,11 @@ void ptm_bfd_sess_dn(struct bfd_session *bfd, uint8_t diag) bs_to_string(bfd), state_list[old_state].str, state_list[bfd->ses_state].str, get_diag_str(bfd->local_diag)); + if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES) && + old_state == PTM_BFD_UP) + zlog_notice("Session-Change: [%s] %s -> %s reason:%s", bs_to_string(bfd), + state_list[old_state].str, state_list[bfd->ses_state].str, + get_diag_str(bfd->local_diag)); } /* clear peer's mac address */ @@ -651,6 +666,9 @@ void ptm_sbfd_sess_up(struct bfd_session *bfd) if (bglobal.debug_peer_event) zlog_info("state-change: [%s] %s -> %s", bs_to_string(bfd), state_list[old_state].str, state_list[bfd->ses_state].str); + if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES)) + zlog_notice("Session-Change: [%s] %s -> %s", bs_to_string(bfd), + state_list[old_state].str, state_list[bfd->ses_state].str); } } @@ -693,6 +711,11 @@ void ptm_sbfd_init_sess_dn(struct bfd_session *bfd, uint8_t diag) zlog_debug("state-change: [%s] %s -> %s reason:%s", bs_to_string(bfd), state_list[old_state].str, state_list[bfd->ses_state].str, get_diag_str(bfd->local_diag)); + if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES) && + old_state == PTM_BFD_UP) + zlog_notice("Session-Change: [%s] %s -> %s reason:%s", bs_to_string(bfd), + state_list[old_state].str, state_list[bfd->ses_state].str, + get_diag_str(bfd->local_diag)); } /* reset local address ,it might has been be changed after bfd is up*/ //memset(&bfd->local_address, 0, sizeof(bfd->local_address)); @@ -721,6 +744,11 @@ void ptm_sbfd_echo_sess_dn(struct bfd_session *bfd, uint8_t diag) zlog_warn("state-change: [%s] %s -> %s reason:%s", bs_to_string(bfd), state_list[old_state].str, state_list[bfd->ses_state].str, get_diag_str(bfd->local_diag)); + if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES) && + old_state == PTM_BFD_UP) + zlog_notice("Session-Change: [%s] %s -> %s reason:%s", bs_to_string(bfd), + state_list[old_state].str, state_list[bfd->ses_state].str, + get_diag_str(bfd->local_diag)); } } @@ -944,6 +972,11 @@ static void _bfd_session_update(struct bfd_session *bs, bs->peer_profile.echo_mode = bpc->bpc_echo; bfd_set_echo(bs, bpc->bpc_echo); + if (bpc->bpc_log_session_changes) + SET_FLAG(bs->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES); + else + UNSET_FLAG(bs->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES); + /* * Shutdown needs to be the last in order to avoid timers enable when * the session is disabled. @@ -1608,6 +1641,14 @@ void bfd_set_passive_mode(struct bfd_session *bs, bool passive) } } +void bfd_set_log_session_changes(struct bfd_session *bs, bool log_session_changes) +{ + if (log_session_changes) + SET_FLAG(bs->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES); + else + UNSET_FLAG(bs->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES); +} + /* * Helper functions. */ diff --git a/bfdd/bfd.h b/bfdd/bfd.h index 645a76596f..75efb483fe 100644 --- a/bfdd/bfd.h +++ b/bfdd/bfd.h @@ -84,6 +84,7 @@ struct bfd_peer_cfg { bool bpc_cbit; bool bpc_passive; + bool bpc_log_session_changes; bool bpc_has_profile; char bpc_profile[64]; @@ -224,21 +225,22 @@ enum bfd_diagnosticis { /* BFD session flags */ enum bfd_session_flags { BFD_SESS_FLAG_NONE = 0, - BFD_SESS_FLAG_ECHO = 1 << 0, /* BFD Echo functionality */ - BFD_SESS_FLAG_ECHO_ACTIVE = 1 << 1, /* BFD Echo Packets are being sent + BFD_SESS_FLAG_ECHO = 1 << 0, /* BFD Echo functionality */ + BFD_SESS_FLAG_ECHO_ACTIVE = 1 << 1, /* BFD Echo Packets are being sent * actively */ - BFD_SESS_FLAG_MH = 1 << 2, /* BFD Multi-hop session */ - BFD_SESS_FLAG_IPV6 = 1 << 4, /* BFD IPv6 session */ - BFD_SESS_FLAG_SEND_EVT_ACTIVE = 1 << 5, /* send event timer active */ - BFD_SESS_FLAG_SEND_EVT_IGNORE = 1 << 6, /* ignore send event when timer + BFD_SESS_FLAG_MH = 1 << 2, /* BFD Multi-hop session */ + BFD_SESS_FLAG_IPV6 = 1 << 4, /* BFD IPv6 session */ + BFD_SESS_FLAG_SEND_EVT_ACTIVE = 1 << 5, /* send event timer active */ + BFD_SESS_FLAG_SEND_EVT_IGNORE = 1 << 6, /* ignore send event when timer * expires */ - BFD_SESS_FLAG_SHUTDOWN = 1 << 7, /* disable BGP peer function */ - BFD_SESS_FLAG_CONFIG = 1 << 8, /* Session configured with bfd NB API */ - BFD_SESS_FLAG_CBIT = 1 << 9, /* CBIT is set */ - BFD_SESS_FLAG_PASSIVE = 1 << 10, /* Passive mode */ - BFD_SESS_FLAG_MAC_SET = 1 << 11, /* MAC of peer known */ + BFD_SESS_FLAG_SHUTDOWN = 1 << 7, /* disable BGP peer function */ + BFD_SESS_FLAG_CONFIG = 1 << 8, /* Session configured with bfd NB API */ + BFD_SESS_FLAG_CBIT = 1 << 9, /* CBIT is set */ + BFD_SESS_FLAG_PASSIVE = 1 << 10, /* Passive mode */ + BFD_SESS_FLAG_MAC_SET = 1 << 11, /* MAC of peer known */ + BFD_SESS_FLAG_LOG_SESSION_CHANGES = 1 << 12, /* Log session changes */ }; enum bfd_mode_type { @@ -297,6 +299,8 @@ struct bfd_profile { bool admin_shutdown; /** Passive mode. */ bool passive; + /** Log session changes. */ + bool log_session_changes; /** Minimum expected TTL value. */ uint8_t minimum_ttl; @@ -682,6 +686,14 @@ void bfd_set_shutdown(struct bfd_session *bs, bool shutdown); */ void bfd_set_passive_mode(struct bfd_session *bs, bool passive); +/** + * Set the BFD session to log or not log session changes. + * + * \param bs the BFD session. + * \param log_session indicates whether or not to log session changes. + */ +void bfd_set_log_session_changes(struct bfd_session *bs, bool log_session); + /** * Picks the BFD session configuration from the appropriated source: * if using the default peer configuration prefer profile (if it exists), diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c index a1710ec127..016e63b192 100644 --- a/bfdd/bfdd_cli.c +++ b/bfdd/bfdd_cli.c @@ -754,6 +754,21 @@ void bfd_cli_show_passive(struct vty *vty, const struct lyd_node *dnode, yang_dnode_get_bool(dnode, NULL) ? "" : "no "); } +DEFPY_YANG(bfd_peer_log_session_changes, bfd_peer_log_session_changes_cmd, + "[no] log-session-changes", + NO_STR + "Log Up/Down changes for the session\n") +{ + nb_cli_enqueue_change(vty, "./log-session-changes", NB_OP_MODIFY, no ? "false" : "true"); + return nb_cli_apply_changes(vty, NULL); +} + +void bfd_cli_show_log_session_changes(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " %slog-session-changes\n", yang_dnode_get_bool(dnode, NULL) ? "" : "no "); +} + DEFPY_YANG( bfd_peer_minimum_ttl, bfd_peer_minimum_ttl_cmd, "[no] minimum-ttl (1-254)$ttl", @@ -1063,6 +1078,9 @@ ALIAS_YANG(bfd_peer_passive, bfd_profile_passive_cmd, NO_STR "Don't attempt to start sessions\n") +ALIAS_YANG(bfd_peer_log_session_changes, bfd_profile_log_session_changes_cmd, + "[no] log-session-changes", NO_STR "Log Up/Down session changes in the profile\n") + ALIAS_YANG(bfd_peer_minimum_ttl, bfd_profile_minimum_ttl_cmd, "[no] minimum-ttl (1-254)$ttl", NO_STR @@ -1329,6 +1347,7 @@ bfdd_cli_init(void) install_element(BFD_PEER_NODE, &bfd_peer_echo_receive_interval_cmd); install_element(BFD_PEER_NODE, &bfd_peer_profile_cmd); install_element(BFD_PEER_NODE, &bfd_peer_passive_cmd); + install_element(BFD_PEER_NODE, &bfd_peer_log_session_changes_cmd); install_element(BFD_PEER_NODE, &bfd_peer_minimum_ttl_cmd); install_element(BFD_PEER_NODE, &no_bfd_peer_minimum_ttl_cmd); @@ -1350,6 +1369,7 @@ bfdd_cli_init(void) install_element(BFD_PROFILE_NODE, &bfd_profile_echo_transmit_interval_cmd); install_element(BFD_PROFILE_NODE, &bfd_profile_echo_receive_interval_cmd); install_element(BFD_PROFILE_NODE, &bfd_profile_passive_cmd); + install_element(BFD_PROFILE_NODE, &bfd_profile_log_session_changes_cmd); install_element(BFD_PROFILE_NODE, &bfd_profile_minimum_ttl_cmd); install_element(BFD_PROFILE_NODE, &no_bfd_profile_minimum_ttl_cmd); } diff --git a/bfdd/bfdd_nb.c b/bfdd/bfdd_nb.c index f60d8397bb..7595d8d05e 100644 --- a/bfdd/bfdd_nb.c +++ b/bfdd/bfdd_nb.c @@ -70,6 +70,13 @@ const struct frr_yang_module_info frr_bfdd_info = { .cli_show = bfd_cli_show_passive, } }, + { + .xpath = "/frr-bfdd:bfdd/bfd/profile/log-session-changes", + .cbs = { + .modify = bfdd_bfd_profile_log_session_changes_modify, + .cli_show = bfd_cli_show_log_session_changes, + } + }, { .xpath = "/frr-bfdd:bfdd/bfd/profile/minimum-ttl", .cbs = { @@ -160,6 +167,13 @@ const struct frr_yang_module_info frr_bfdd_info = { .cli_show = bfd_cli_show_passive, } }, + { + .xpath = "/frr-bfdd:bfdd/bfd/sessions/single-hop/log-session-changes", + .cbs = { + .modify = bfdd_bfd_sessions_single_hop_log_session_changes_modify, + .cli_show = bfd_cli_show_log_session_changes, + } + }, { .xpath = "/frr-bfdd:bfdd/bfd/sessions/single-hop/echo-mode", .cbs = { @@ -356,6 +370,13 @@ const struct frr_yang_module_info frr_bfdd_info = { .cli_show = bfd_cli_show_passive, } }, + { + .xpath = "/frr-bfdd:bfdd/bfd/sessions/multi-hop/log-session-changes", + .cbs = { + .modify = bfdd_bfd_sessions_single_hop_log_session_changes_modify, + .cli_show = bfd_cli_show_log_session_changes, + } + }, { .xpath = "/frr-bfdd:bfdd/bfd/sessions/multi-hop/minimum-ttl", .cbs = { @@ -572,6 +593,13 @@ const struct frr_yang_module_info frr_bfdd_info = { .cli_show = bfd_cli_show_passive, } }, + { + .xpath = "/frr-bfdd:bfdd/bfd/sessions/sbfd-echo/log-session-changes", + .cbs = { + .modify = bfdd_bfd_sessions_single_hop_log_session_changes_modify, + .cli_show = bfd_cli_show_log_session_changes, + } + }, { .xpath = "/frr-bfdd:bfdd/bfd/sessions/sbfd-echo/bfd-mode", .cbs = { @@ -788,6 +816,13 @@ const struct frr_yang_module_info frr_bfdd_info = { .cli_show = bfd_cli_show_passive, } }, + { + .xpath = "/frr-bfdd:bfdd/bfd/sessions/sbfd-init/log-session-changes", + .cbs = { + .modify = bfdd_bfd_sessions_single_hop_log_session_changes_modify, + .cli_show = bfd_cli_show_log_session_changes, + } + }, { .xpath = "/frr-bfdd:bfdd/bfd/sessions/sbfd-init/bfd-mode", .cbs = { diff --git a/bfdd/bfdd_nb.h b/bfdd/bfdd_nb.h index 6621973ae3..ce6ee0d002 100644 --- a/bfdd/bfdd_nb.h +++ b/bfdd/bfdd_nb.h @@ -24,6 +24,7 @@ int bfdd_bfd_profile_required_receive_interval_modify( struct nb_cb_modify_args *args); int bfdd_bfd_profile_administrative_down_modify(struct nb_cb_modify_args *args); int bfdd_bfd_profile_passive_mode_modify(struct nb_cb_modify_args *args); +int bfdd_bfd_profile_log_session_changes_modify(struct nb_cb_modify_args *args); int bfdd_bfd_profile_minimum_ttl_modify(struct nb_cb_modify_args *args); int bfdd_bfd_profile_echo_mode_modify(struct nb_cb_modify_args *args); int bfdd_bfd_profile_desired_echo_transmission_interval_modify( @@ -54,6 +55,7 @@ int bfdd_bfd_sessions_single_hop_administrative_down_modify( struct nb_cb_modify_args *args); int bfdd_bfd_sessions_single_hop_passive_mode_modify( struct nb_cb_modify_args *args); +int bfdd_bfd_sessions_single_hop_log_session_changes_modify(struct nb_cb_modify_args *args); int bfdd_bfd_sessions_single_hop_echo_mode_modify( struct nb_cb_modify_args *args); int bfdd_bfd_sessions_single_hop_desired_echo_transmission_interval_modify( @@ -229,6 +231,8 @@ void bfd_cli_peer_profile_show(struct vty *vty, const struct lyd_node *dnode, bool show_defaults); void bfd_cli_show_passive(struct vty *vty, const struct lyd_node *dnode, bool show_defaults); +void bfd_cli_show_log_session_changes(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults); void bfd_cli_show_minimum_ttl(struct vty *vty, const struct lyd_node *dnode, bool show_defaults); diff --git a/bfdd/bfdd_nb_config.c b/bfdd/bfdd_nb_config.c index f553d56652..e2d7f5061d 100644 --- a/bfdd/bfdd_nb_config.c +++ b/bfdd/bfdd_nb_config.c @@ -595,6 +595,23 @@ int bfdd_bfd_profile_passive_mode_modify(struct nb_cb_modify_args *args) return NB_OK; } +/* + * XPath: /frr-bfdd:bfdd/bfd/profile/log-session-changes + */ +int bfdd_bfd_profile_log_session_changes_modify(struct nb_cb_modify_args *args) +{ + struct bfd_profile *bp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + bp = nb_running_get_entry(args->dnode, NULL, true); + bp->log_session_changes = yang_dnode_get_bool(args->dnode, NULL); + bfd_profile_update(bp); + + return NB_OK; +} + /* * XPath: /frr-bfdd:bfdd/bfd/profile/minimum-ttl */ @@ -903,6 +920,38 @@ int bfdd_bfd_sessions_single_hop_passive_mode_modify( return NB_OK; } +/* + * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/log-session-changes + * /frr-bfdd:bfdd/bfd/sessions/multi-hop/log-session-changes + * /frr-bfdd:bfdd/bfd/sessions/sbfd_echo/log-session-changes + * /frr-bfdd:bfdd/bfd/sessions/sbfd_init/log-session-changes + */ +int bfdd_bfd_sessions_single_hop_log_session_changes_modify(struct nb_cb_modify_args *args) +{ + struct bfd_session *bs; + bool log_session_changes; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + return NB_OK; + + case NB_EV_APPLY: + break; + + case NB_EV_ABORT: + return NB_OK; + } + + log_session_changes = yang_dnode_get_bool(args->dnode, NULL); + + bs = nb_running_get_entry(args->dnode, NULL, true); + bs->peer_profile.log_session_changes = log_session_changes; + bfd_session_apply(bs); + + return NB_OK; +} + /* * XPath: /frr-bfdd:bfdd/bfd/sessions/sbfd-init/bfd-mode * /frr-bfdd:bfdd/bfd/sessions/sbfd-echo/bfd-mode diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c index c281197849..32e3bc27c0 100644 --- a/bfdd/bfdd_vty.c +++ b/bfdd/bfdd_vty.c @@ -164,9 +164,10 @@ static void _display_peer(struct vty *vty, struct bfd_session *bs) vty_out(vty, "\t\tPassive mode\n"); else vty_out(vty, "\t\tActive mode\n"); + if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES)) + vty_out(vty, "\t\tLog session changes\n"); if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) vty_out(vty, "\t\tMinimum TTL: %d\n", bs->mh_ttl); - vty_out(vty, "\t\tStatus: "); switch (bs->ses_state) { case PTM_BFD_ADM_DOWN: @@ -289,6 +290,8 @@ static struct json_object *__display_peer_json(struct bfd_session *bs) json_object_int_add(jo, "remote-id", bs->discrs.remote_discr); json_object_boolean_add(jo, "passive-mode", CHECK_FLAG(bs->flags, BFD_SESS_FLAG_PASSIVE)); + json_object_boolean_add(jo, "log-session-changes", + CHECK_FLAG(bs->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES)); if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) json_object_int_add(jo, "minimum-ttl", bs->mh_ttl); @@ -1194,6 +1197,7 @@ static int bfd_configure_peer(struct bfd_peer_cfg *bpc, bool mhop, /* Defaults */ bpc->bpc_shutdown = false; + bpc->bpc_log_session_changes = false; bpc->bpc_detectmultiplier = BPC_DEF_DETECTMULTIPLIER; bpc->bpc_recvinterval = BPC_DEF_RECEIVEINTERVAL; bpc->bpc_txinterval = BPC_DEF_TRANSMITINTERVAL; diff --git a/bfdd/dplane.c b/bfdd/dplane.c index b1a32fb150..7269b319a3 100644 --- a/bfdd/dplane.c +++ b/bfdd/dplane.c @@ -384,10 +384,15 @@ bfd_dplane_session_state_change(struct bfd_dplane_ctx *bdc, break; } - if (bglobal.debug_peer_event) + if (bglobal.debug_peer_event) { zlog_debug("state-change: [data plane: %s] %s -> %s", bs_to_string(bs), state_list[old_state].str, state_list[bs->ses_state].str); + if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_LOG_SESSION_CHANGES) && + old_state != bs->ses_state) + zlog_notice("Session-Change: [data plane: %s] %s -> %s", bs_to_string(bs), + state_list[old_state].str, state_list[bs->ses_state].str); + } } /**