summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfdd/bfd.c133
-rw-r--r--bfdd/bfd.h16
-rw-r--r--bfdd/bfdd_nb_config.c54
-rw-r--r--yang/frr-bfdd.yang2
4 files changed, 89 insertions, 116 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index f9e572db4d..e5432af553 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -550,25 +550,6 @@ int bfd_session_update_label(struct bfd_session *bs, const char *nlabel)
static void _bfd_session_update(struct bfd_session *bs,
struct bfd_peer_cfg *bpc)
{
- if (bpc->bpc_echo) {
- /* Check if echo mode is already active. */
- if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
- goto skip_echo;
-
- SET_FLAG(bs->flags, BFD_SESS_FLAG_ECHO);
-
- /* Activate/update echo receive timeout timer. */
- bs_echo_timer_handler(bs);
- } else {
- /* Check if echo mode is already disabled. */
- if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
- goto skip_echo;
-
- UNSET_FLAG(bs->flags, BFD_SESS_FLAG_ECHO);
- ptm_bfd_echo_stop(bs);
- }
-
-skip_echo:
if (bpc->bpc_has_txinterval)
bs->timers.desired_min_tx = bpc->bpc_txinterval * 1000;
@@ -584,52 +565,18 @@ skip_echo:
if (bpc->bpc_has_label)
bfd_session_update_label(bs, bpc->bpc_label);
- if (bpc->bpc_shutdown) {
- /* Check if already shutdown. */
- if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
- return;
-
- SET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
-
- /* Disable all events. */
- bfd_recvtimer_delete(bs);
- bfd_echo_recvtimer_delete(bs);
- bfd_xmttimer_delete(bs);
- bfd_echo_xmttimer_delete(bs);
-
- /* Change and notify state change. */
- bs->ses_state = PTM_BFD_ADM_DOWN;
- control_notify(bs, bs->ses_state);
-
- /* Don't try to send packets with a disabled session. */
- if (bs->sock != -1)
- ptm_bfd_snd(bs, 0);
- } else {
- /* Check if already working. */
- if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
- return;
-
- UNSET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
-
- /* Change and notify state change. */
- bs->ses_state = PTM_BFD_DOWN;
- control_notify(bs, bs->ses_state);
-
- /* Enable all timers. */
- bfd_recvtimer_update(bs);
- bfd_xmttimer_update(bs, bs->xmt_TO);
- }
- if (bpc->bpc_cbit) {
- if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CBIT))
- return;
-
+ if (bpc->bpc_cbit)
SET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT);
- } else {
- if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CBIT))
- return;
-
+ else
UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT);
- }
+
+ bfd_set_echo(bs, bpc->bpc_echo);
+
+ /*
+ * Shutdown needs to be the last in order to avoid timers enable when
+ * the session is disabled.
+ */
+ bfd_set_shutdown(bs, bpc->bpc_shutdown);
}
static int bfd_session_update(struct bfd_session *bs, struct bfd_peer_cfg *bpc)
@@ -1100,6 +1047,66 @@ void bs_set_slow_timers(struct bfd_session *bs)
bs->xmt_TO = BFD_DEF_SLOWTX;
}
+void bfd_set_echo(struct bfd_session *bs, bool echo)
+{
+ if (echo) {
+ /* Check if echo mode is already active. */
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
+ return;
+
+ SET_FLAG(bs->flags, BFD_SESS_FLAG_ECHO);
+
+ /* Activate/update echo receive timeout timer. */
+ bs_echo_timer_handler(bs);
+ } else {
+ /* Check if echo mode is already disabled. */
+ if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
+ return;
+
+ UNSET_FLAG(bs->flags, BFD_SESS_FLAG_ECHO);
+ ptm_bfd_echo_stop(bs);
+ }
+}
+
+void bfd_set_shutdown(struct bfd_session *bs, bool shutdown)
+{
+ if (shutdown) {
+ /* Already shutdown. */
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
+ return;
+
+ SET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
+
+ /* Disable all events. */
+ bfd_recvtimer_delete(bs);
+ bfd_echo_recvtimer_delete(bs);
+ bfd_xmttimer_delete(bs);
+ bfd_echo_xmttimer_delete(bs);
+
+ /* Change and notify state change. */
+ bs->ses_state = PTM_BFD_ADM_DOWN;
+ control_notify(bs, bs->ses_state);
+
+ /* Don't try to send packets with a disabled session. */
+ if (bs->sock != -1)
+ ptm_bfd_snd(bs, 0);
+ } else {
+ /* Already working. */
+ if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
+ return;
+
+ UNSET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
+
+ /* Change and notify state change. */
+ bs->ses_state = PTM_BFD_DOWN;
+ control_notify(bs, bs->ses_state);
+
+ /* Enable all timers. */
+ bfd_recvtimer_update(bs);
+ bfd_xmttimer_update(bs, bs->xmt_TO);
+ }
+}
+
/*
* Helper functions.
*/
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index 93873eed94..5a81d80424 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -550,6 +550,22 @@ const struct bfd_session *bfd_session_next(const struct bfd_session *bs,
bool mhop);
void bfd_sessions_remove_manual(void);
+/**
+ * Set the BFD session echo state.
+ *
+ * \param bs the BFD session.
+ * \param echo the echo operational state.
+ */
+void bfd_set_echo(struct bfd_session *bs, bool echo);
+
+/**
+ * Set the BFD session functional state.
+ *
+ * \param bs the BFD session.
+ * \param shutdown the operational value.
+ */
+void bfd_set_shutdown(struct bfd_session *bs, bool shutdown);
+
/* BFD hash data structures interface */
void bfd_initialize(void);
void bfd_shutdown(void);
diff --git a/bfdd/bfdd_nb_config.c b/bfdd/bfdd_nb_config.c
index 9e136c3fc5..df8a644e78 100644
--- a/bfdd/bfdd_nb_config.c
+++ b/bfdd/bfdd_nb_config.c
@@ -367,42 +367,7 @@ int bfdd_bfd_sessions_single_hop_administrative_down_modify(
}
bs = nb_running_get_entry(args->dnode, NULL, true);
-
- if (!shutdown) {
- if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
- return NB_OK;
-
- UNSET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
-
- /* Change and notify state change. */
- bs->ses_state = PTM_BFD_DOWN;
- control_notify(bs, bs->ses_state);
-
- /* Enable all timers. */
- bfd_recvtimer_update(bs);
- bfd_xmttimer_update(bs, bs->xmt_TO);
- if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO)) {
- bfd_echo_recvtimer_update(bs);
- bfd_echo_xmttimer_update(bs, bs->echo_xmt_TO);
- }
- } else {
- if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
- return NB_OK;
-
- SET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
-
- /* Disable all events. */
- bfd_recvtimer_delete(bs);
- bfd_echo_recvtimer_delete(bs);
- bfd_xmttimer_delete(bs);
- bfd_echo_xmttimer_delete(bs);
-
- /* Change and notify state change. */
- bs->ses_state = PTM_BFD_ADM_DOWN;
- control_notify(bs, bs->ses_state);
-
- ptm_bfd_snd(bs, 0);
- }
+ bfd_set_shutdown(bs, shutdown);
return NB_OK;
}
@@ -429,22 +394,7 @@ int bfdd_bfd_sessions_single_hop_echo_mode_modify(
}
bs = nb_running_get_entry(args->dnode, NULL, true);
-
- if (!echo) {
- if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
- return NB_OK;
-
- UNSET_FLAG(bs->flags, BFD_SESS_FLAG_ECHO);
- ptm_bfd_echo_stop(bs);
- } else {
- if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
- return NB_OK;
-
- SET_FLAG(bs->flags, BFD_SESS_FLAG_ECHO);
- /* Apply setting immediately. */
- if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
- bs_echo_timer_handler(bs);
- }
+ bfd_set_echo(bs, echo);
return NB_OK;
}
diff --git a/yang/frr-bfdd.yang b/yang/frr-bfdd.yang
index a6d537f01c..19e36fdfd7 100644
--- a/yang/frr-bfdd.yang
+++ b/yang/frr-bfdd.yang
@@ -54,7 +54,7 @@ module frr-bfdd {
"RFC 5880: Bidirectional Forwarding Detection (BFD).
RFC 5881: Bidirectional Forwarding Detection (BFD)
for IPv4 and IPv6 (Single Hop).
- RFC 5882: Bidirectional Forwarding Detection (BFD) for Multihop Paths.";
+ RFC 5883: Bidirectional Forwarding Detection (BFD) for Multihop Paths.";
}