summaryrefslogtreecommitdiff
path: root/bfdd/bfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfdd/bfd.c')
-rw-r--r--bfdd/bfd.c220
1 files changed, 123 insertions, 97 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index 222bf32c94..f9e572db4d 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -28,6 +28,7 @@
#include <zebra.h>
#include "lib/jhash.h"
+#include "lib/network.h"
#include "bfd.h"
@@ -131,7 +132,7 @@ int bfd_session_enable(struct bfd_session *bs)
if (bs->key.vrfname[0]) {
vrf = vrf_lookup_by_name(bs->key.vrfname);
if (vrf == NULL) {
- log_error(
+ zlog_err(
"session-enable: specified VRF doesn't exists.");
return 0;
}
@@ -143,15 +144,15 @@ int bfd_session_enable(struct bfd_session *bs)
else
ifp = if_lookup_by_name_all_vrf(bs->key.ifname);
if (ifp == NULL) {
- log_error(
- "session-enable: specified interface doesn't exists.");
+ zlog_err(
+ "session-enable: specified interface doesn't exists.");
return 0;
}
if (bs->key.ifname[0] && !vrf) {
vrf = vrf_lookup_by_id(ifp->vrf_id);
if (vrf == NULL) {
- log_error(
- "session-enable: specified VRF doesn't exists.");
+ zlog_err(
+ "session-enable: specified VRF doesn't exists.");
return 0;
}
}
@@ -164,12 +165,14 @@ int bfd_session_enable(struct bfd_session *bs)
assert(bs->vrf);
if (bs->key.ifname[0]
- && BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) == 0)
+ && CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) == 0)
bs->ifp = ifp;
/* Sanity check: don't leak open sockets. */
if (bs->sock != -1) {
- log_debug("session-enable: previous socket open");
+ if (bglobal.debug_peer_event)
+ zlog_debug("session-enable: previous socket open");
+
close(bs->sock);
bs->sock = -1;
}
@@ -179,7 +182,7 @@ int bfd_session_enable(struct bfd_session *bs)
* could use the destination port (3784) for the source
* port we wouldn't need a socket per session.
*/
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6) == 0) {
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6) == 0) {
psock = bp_peer_socket(bs);
if (psock == -1)
return 0;
@@ -234,8 +237,8 @@ static uint32_t ptm_bfd_gen_ID(void)
* random session identification numbers.
*/
do {
- session_id = ((random() << 16) & 0xFFFF0000)
- | (random() & 0x0000FFFF);
+ session_id = ((frr_weak_random() << 16) & 0xFFFF0000)
+ | (frr_weak_random() & 0x0000FFFF);
} while (session_id == 0 || bfd_id_lookup(session_id) != NULL);
return session_id;
@@ -256,7 +259,7 @@ void ptm_bfd_start_xmt_timer(struct bfd_session *bfd, bool is_echo)
* between 75% and 90%.
*/
maxpercent = (bfd->detect_mult == 1) ? 16 : 26;
- jitter = (xmt_TO * (75 + (random() % maxpercent))) / 100;
+ jitter = (xmt_TO * (75 + (frr_weak_random() % maxpercent))) / 100;
/* XXX remove that division above */
if (is_echo)
@@ -287,7 +290,7 @@ void ptm_bfd_echo_stop(struct bfd_session *bfd)
{
bfd->echo_xmt_TO = 0;
bfd->echo_detect_TO = 0;
- BFD_UNSET_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE);
+ UNSET_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE);
bfd_echo_xmttimer_delete(bfd);
bfd_echo_recvtimer_delete(bfd);
@@ -318,9 +321,10 @@ void ptm_bfd_sess_up(struct bfd_session *bfd)
if (old_state != bfd->ses_state) {
bfd->stats.session_up++;
- log_info("state-change: [%s] %s -> %s", bs_to_string(bfd),
- state_list[old_state].str,
- state_list[bfd->ses_state].str);
+ if (bglobal.debug_peer_event)
+ zlog_debug("state-change: [%s] %s -> %s",
+ bs_to_string(bfd), state_list[old_state].str,
+ state_list[bfd->ses_state].str);
}
}
@@ -352,15 +356,16 @@ void ptm_bfd_sess_dn(struct bfd_session *bfd, uint8_t diag)
control_notify(bfd, PTM_BFD_DOWN);
/* Stop echo packet transmission if they are active */
- if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
+ if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
ptm_bfd_echo_stop(bfd);
if (old_state != bfd->ses_state) {
bfd->stats.session_down++;
- log_info("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 (bglobal.debug_peer_event)
+ 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));
}
}
@@ -522,8 +527,7 @@ int bfd_session_update_label(struct bfd_session *bs, const char *nlabel)
return -1;
}
- if (pl_new(nlabel, bs) == NULL)
- return -1;
+ pl_new(nlabel, bs);
return 0;
}
@@ -548,19 +552,19 @@ static void _bfd_session_update(struct bfd_session *bs,
{
if (bpc->bpc_echo) {
/* Check if echo mode is already active. */
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
goto skip_echo;
- BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_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 (!BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
+ if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
goto skip_echo;
- BFD_UNSET_FLAG(bs->flags, BFD_SESS_FLAG_ECHO);
+ UNSET_FLAG(bs->flags, BFD_SESS_FLAG_ECHO);
ptm_bfd_echo_stop(bs);
}
@@ -582,10 +586,10 @@ skip_echo:
if (bpc->bpc_shutdown) {
/* Check if already shutdown. */
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
return;
- BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
+ SET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
/* Disable all events. */
bfd_recvtimer_delete(bs);
@@ -602,10 +606,10 @@ skip_echo:
ptm_bfd_snd(bs, 0);
} else {
/* Check if already working. */
- if (!BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
+ if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
return;
- BFD_UNSET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
+ UNSET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
/* Change and notify state change. */
bs->ses_state = PTM_BFD_DOWN;
@@ -616,15 +620,15 @@ skip_echo:
bfd_xmttimer_update(bs, bs->xmt_TO);
}
if (bpc->bpc_cbit) {
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CBIT))
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CBIT))
return;
- BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT);
+ SET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT);
} else {
- if (!BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CBIT))
+ if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CBIT))
return;
- BFD_UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT);
+ UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT);
}
}
@@ -681,10 +685,6 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
/* Get BFD session storage with its defaults. */
bfd = bfd_session_new();
- if (bfd == NULL) {
- log_error("session-new: allocation failed");
- return NULL;
- }
/*
* Store interface/VRF name in case we need to delay session
@@ -703,7 +703,7 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
/* Copy remaining data. */
if (bpc->bpc_ipv4 == false)
- BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6);
+ SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6);
bfd->key.family = (bpc->bpc_ipv4) ? AF_INET : AF_INET6;
switch (bfd->key.family) {
@@ -727,7 +727,7 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
}
if (bpc->bpc_mhop)
- BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_MH);
+ SET_FLAG(bfd->flags, BFD_SESS_FLAG_MH);
bfd->key.mhop = bpc->bpc_mhop;
@@ -758,7 +758,8 @@ struct bfd_session *bs_registrate(struct bfd_session *bfd)
if (bfd->key.ifname[0] || bfd->key.vrfname[0] || bfd->sock == -1)
bs_observer_add(bfd);
- log_info("session-new: %s", bs_to_string(bfd));
+ if (bglobal.debug_peer_event)
+ zlog_debug("session-new: %s", bs_to_string(bfd));
control_notify_config(BCM_NOTIFY_CONFIG_ADD, bfd);
@@ -776,13 +777,14 @@ int ptm_bfd_sess_del(struct bfd_peer_cfg *bpc)
/* This pointer is being referenced, don't let it be deleted. */
if (bs->refcount > 0) {
- log_error("session-delete: refcount failure: %" PRIu64
- " references",
- bs->refcount);
+ zlog_err("session-delete: refcount failure: %" PRIu64
+ " references",
+ bs->refcount);
return -1;
}
- log_info("session-delete: %s", bs_to_string(bs));
+ if (bglobal.debug_peer_event)
+ zlog_debug("session-delete: %s", bs_to_string(bs));
control_notify_config(BCM_NOTIFY_CONFIG_DELETE, bs);
@@ -849,7 +851,9 @@ static void bs_down_handler(struct bfd_session *bs, int nstate)
break;
default:
- log_debug("state-change: unhandled neighbor state: %d", nstate);
+ if (bglobal.debug_peer_event)
+ zlog_debug("state-change: unhandled neighbor state: %d",
+ nstate);
break;
}
}
@@ -876,7 +880,9 @@ static void bs_init_handler(struct bfd_session *bs, int nstate)
break;
default:
- log_debug("state-change: unhandled neighbor state: %d", nstate);
+ if (bglobal.debug_peer_event)
+ zlog_debug("state-change: unhandled neighbor state: %d",
+ nstate);
break;
}
}
@@ -901,16 +907,16 @@ static void bs_neighbour_admin_down_handler(struct bfd_session *bfd,
control_notify(bfd, PTM_BFD_ADM_DOWN);
/* Stop echo packet transmission if they are active */
- if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
+ if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
ptm_bfd_echo_stop(bfd);
if (old_state != bfd->ses_state) {
bfd->stats.session_down++;
-
- log_info("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 (bglobal.debug_peer_event)
+ 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));
}
}
@@ -932,7 +938,9 @@ static void bs_up_handler(struct bfd_session *bs, int nstate)
break;
default:
- log_debug("state-change: unhandled neighbor state: %d", nstate);
+ if (bglobal.debug_peer_event)
+ zlog_debug("state-change: unhandled neighbor state: %d",
+ nstate);
break;
}
}
@@ -954,8 +962,9 @@ void bs_state_handler(struct bfd_session *bs, int nstate)
break;
default:
- log_debug("state-change: [%s] is in invalid state: %d",
- bs_to_string(bs), nstate);
+ if (bglobal.debug_peer_event)
+ zlog_debug("state-change: [%s] is in invalid state: %d",
+ bs_to_string(bs), nstate);
break;
}
}
@@ -976,14 +985,14 @@ void bs_echo_timer_handler(struct bfd_session *bs)
* Section 3).
* - Check that we are already at the up state.
*/
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO) == 0
- || BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO) == 0
+ || CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)
|| bs->ses_state != PTM_BFD_UP)
return;
/* Remote peer asked to stop echo. */
if (bs->remote_timers.required_min_echo == 0) {
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
ptm_bfd_echo_stop(bs);
return;
@@ -1002,7 +1011,7 @@ void bs_echo_timer_handler(struct bfd_session *bs)
else
bs->echo_xmt_TO = bs->timers.required_min_echo;
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO_ACTIVE) == 0
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO_ACTIVE) == 0
|| old_timer != bs->echo_xmt_TO)
ptm_bfd_echo_start(bs);
}
@@ -1032,20 +1041,19 @@ void bs_final_handler(struct bfd_session *bs)
}
/*
- * Calculate detection time based on new timers.
+ * Calculate transmission time based on new timers.
*
* Transmission calculation:
- * We must respect the RequiredMinRxInterval from the remote
- * system: if our desired transmission timer is more than the
- * minimum receive rate, then we must lower it to at least the
- * minimum receive interval.
+ * Unless specified by exceptions at the end of Section 6.8.7, the
+ * transmission time will be determined by the system with the
+ * slowest rate.
*
- * RFC 5880, Section 6.8.3.
+ * RFC 5880, Section 6.8.7.
*/
if (bs->timers.desired_min_tx > bs->remote_timers.required_min_rx)
- bs->xmt_TO = bs->remote_timers.required_min_rx;
- else
bs->xmt_TO = bs->timers.desired_min_tx;
+ else
+ bs->xmt_TO = bs->remote_timers.required_min_rx;
/* Apply new transmission timer immediately. */
ptm_bfd_start_xmt_timer(bs, false);
@@ -1104,13 +1112,13 @@ static const char *get_diag_str(int diag)
return "N/A";
}
-const char *satostr(struct sockaddr_any *sa)
+const char *satostr(const struct sockaddr_any *sa)
{
#define INETSTR_BUFCOUNT 8
static char buf[INETSTR_BUFCOUNT][INET6_ADDRSTRLEN];
static int bufidx;
- struct sockaddr_in *sin = &sa->sa_sin;
- struct sockaddr_in6 *sin6 = &sa->sa_sin6;
+ const struct sockaddr_in *sin = &sa->sa_sin;
+ const struct sockaddr_in6 *sin6 = &sa->sa_sin6;
bufidx += (bufidx + 1) % INETSTR_BUFCOUNT;
buf[bufidx][0] = 0;
@@ -1241,7 +1249,7 @@ const char *bs_to_string(const struct bfd_session *bs)
static char buf[256];
char addr_buf[INET6_ADDRSTRLEN];
int pos;
- bool is_mhop = BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH);
+ bool is_mhop = CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH);
pos = snprintf(buf, sizeof(buf), "mhop:%s", is_mhop ? "yes" : "no");
pos += snprintf(buf + pos, sizeof(buf) - pos, " peer:%s",
@@ -1431,12 +1439,14 @@ struct bfd_session *bfd_key_lookup(struct bfd_key key)
memset(&bs.key.local, 0, sizeof(bs.key.local));
bsp = hash_lookup(bfd_key_hash, &bs);
if (bsp) {
- char addr_buf[INET6_ADDRSTRLEN];
-
- inet_ntop(bs.key.family, &key.local, addr_buf,
- sizeof(addr_buf));
- log_debug(" peer %s found, but loc-addr %s ignored",
- peer_buf, addr_buf);
+ if (bglobal.debug_peer_event) {
+ char addr_buf[INET6_ADDRSTRLEN];
+ inet_ntop(bs.key.family, &key.local, addr_buf,
+ sizeof(addr_buf));
+ zlog_debug(
+ " peer %s found, but loc-addr %s ignored",
+ peer_buf, addr_buf);
+ }
return bsp;
}
}
@@ -1447,8 +1457,9 @@ struct bfd_session *bfd_key_lookup(struct bfd_key key)
memset(bs.key.ifname, 0, sizeof(bs.key.ifname));
bsp = hash_lookup(bfd_key_hash, &bs);
if (bsp) {
- log_debug(" peer %s found, but ifp %s ignored",
- peer_buf, key.ifname);
+ if (bglobal.debug_peer_event)
+ zlog_debug(" peer %s found, but ifp %s ignored",
+ peer_buf, key.ifname);
return bsp;
}
}
@@ -1458,14 +1469,15 @@ struct bfd_session *bfd_key_lookup(struct bfd_key key)
memset(&bs.key.local, 0, sizeof(bs.key.local));
bsp = hash_lookup(bfd_key_hash, &bs);
if (bsp) {
- char addr_buf[INET6_ADDRSTRLEN];
-
- inet_ntop(bs.key.family, &bs.key.local, addr_buf,
- sizeof(addr_buf));
- log_debug(" peer %s found, but ifp %s"
- " and loc-addr %s ignored",
- peer_buf, key.ifname,
- addr_buf);
+ if (bglobal.debug_peer_event) {
+ char addr_buf[INET6_ADDRSTRLEN];
+ inet_ntop(bs.key.family, &bs.key.local,
+ addr_buf, sizeof(addr_buf));
+ zlog_debug(
+ " peer %s found, but ifp %s"
+ " and loc-addr %s ignored",
+ peer_buf, key.ifname, addr_buf);
+ }
return bsp;
}
}
@@ -1483,8 +1495,11 @@ struct bfd_session *bfd_key_lookup(struct bfd_key key)
/* change key */
if (ctx.result) {
bsp = ctx.result;
- log_debug(" peer %s found, but ifp"
- " and/or loc-addr params ignored", peer_buf);
+ if (bglobal.debug_peer_event)
+ zlog_debug(
+ " peer %s found, but ifp"
+ " and/or loc-addr params ignored",
+ peer_buf);
}
return bsp;
}
@@ -1644,11 +1659,11 @@ static void _bfd_session_remove_manual(struct hash_bucket *hb,
struct bfd_session *bs = hb->data;
/* Delete only manually configured sessions. */
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG) == 0)
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG) == 0)
return;
bs->refcount--;
- BFD_UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
+ UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
/* Don't delete sessions still in use. */
if (bs->refcount != 0)
@@ -1672,13 +1687,17 @@ void bfd_sessions_remove_manual(void)
*/
static int bfd_vrf_new(struct vrf *vrf)
{
- log_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id);
+ if (bglobal.debug_zebra)
+ zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id);
+
return 0;
}
static int bfd_vrf_delete(struct vrf *vrf)
{
- log_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id);
+ if (bglobal.debug_zebra)
+ zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id);
+
return 0;
}
@@ -1686,7 +1705,10 @@ static int bfd_vrf_update(struct vrf *vrf)
{
if (!vrf_is_enabled(vrf))
return 0;
- log_debug("VRF update: %s(%u)", vrf->name, vrf->vrf_id);
+
+ if (bglobal.debug_zebra)
+ zlog_debug("VRF update: %s(%u)", vrf->name, vrf->vrf_id);
+
/* a different name is given; update bfd list */
bfdd_sessions_enable_vrf(vrf);
return 0;
@@ -1703,7 +1725,10 @@ static int bfd_vrf_enable(struct vrf *vrf)
vrf->info = (void *)bvrf;
} else
bvrf = vrf->info;
- log_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);
+
+ if (bglobal.debug_zebra)
+ zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);
+
if (vrf->vrf_id == VRF_DEFAULT ||
vrf_get_backend() == VRF_BACKEND_NETNS) {
if (!bvrf->bg_shop)
@@ -1759,7 +1784,8 @@ static int bfd_vrf_disable(struct vrf *vrf)
bfdd_zclient_unregister(vrf->vrf_id);
}
- log_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
+ if (bglobal.debug_zebra)
+ zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
/* Disable read/write poll triggering. */
THREAD_OFF(bvrf->bg_ev[0]);