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 <acee@lindem.com>
This commit is contained in:
Acee Lindem 2025-03-03 22:46:01 +00:00
parent 4b0aeb6b29
commit aa50f5ebb8
8 changed files with 183 additions and 13 deletions

View File

@ -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.
*/

View File

@ -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),

View File

@ -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);
}

View File

@ -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 = {

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);
}
}
/**