diff options
Diffstat (limited to 'bfdd/bfd.c')
| -rw-r--r-- | bfdd/bfd.c | 220 |
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]); |
