]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bfdd: Add BFD "log-session-changes" feature.
authorAcee Lindem <acee@lindem.com>
Mon, 3 Mar 2025 22:46:01 +0000 (22:46 +0000)
committerAcee Lindem <acee@lindem.com>
Mon, 3 Mar 2025 22:46:01 +0000 (22:46 +0000)
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>
bfdd/bfd.c
bfdd/bfd.h
bfdd/bfdd_cli.c
bfdd/bfdd_nb.c
bfdd/bfdd_nb.h
bfdd/bfdd_nb_config.c
bfdd/bfdd_vty.c
bfdd/dplane.c

index fade89d04fc1b28289e8ffa51ad4e2293323b0c2..8d5306aaafbb68fd1dc04aaeb47d8eee93e0b265 100644 (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.
  */
index 645a76596f9b6bb47ce0117adddffa0c0b3f5356..75efb483fe6a3cd88f430b104012ec6785d055e4 100644 (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),
index a1710ec12756b43b7b88e7c6851f78e63ea96307..016e63b19267c41e0efea32082ea8954b4fa161d 100644 (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);
 }
index f60d8397bb66e9ab52b9c3422852c0041aa28688..7595d8d05e7cb0e17e6718d79bd2266b245dc816 100644 (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 = {
index 6621973ae36531c6a44c374367443e060103ef77..ce6ee0d00202e017373249f25740884f60a01106 100644 (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);
 
index f553d5665249b1c541029ed5b9162a186a2a4965..e2d7f5061dc608605d203de890c50add350121b0 100644 (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
index c2811978491ba66116b2ad3b3914a6f9d527d1a6..32e3bc27c06443a283d22aea74d01d1f7a5e7e53 100644 (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;
index b1a32fb15059f2b42548371eebe01c704a46f373..7269b319a365ff07af8c33707f7c8d72770dfcfb 100644 (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);
+       }
 }
 
 /**