static void bs_down_handler(struct bfd_session *bs, int nstate);
static void bs_init_handler(struct bfd_session *bs, int nstate);
static void bs_up_handler(struct bfd_session *bs, int nstate);
-static void bs_neighbour_admin_down_handler(struct bfd_session *bfd,
- uint8_t diag);
/**
* Remove BFD profile from all BFD sessions so we don't leave dangling
/* Sanity check: don't leak open sockets. */
if (bs->sock != -1) {
if (bglobal.debug_peer_event)
- zlog_debug("session-enable: previous socket open");
+ zlog_debug("%s: previous socket open", __func__);
close(bs->sock);
bs->sock = -1;
ptm_bfd_start_xmt_timer(bs, false);
}
+ /* initialize RTT */
+ bfd_rtt_init(bs);
+
return 0;
}
static void ptm_bfd_echo_xmt_TO(struct bfd_session *bfd)
{
/* Send the scheduled echo packet */
- ptm_bfd_echo_snd(bfd);
+ /* if ipv4 use the new echo implementation that causes
+ * the packet to be looped in forwarding plane of peer
+ */
+ if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6) == 0)
+#ifdef BFD_LINUX
+ ptm_bfd_echo_fp_snd(bfd);
+#else
+ ptm_bfd_echo_snd(bfd);
+#endif
+ else
+ ptm_bfd_echo_snd(bfd);
/* Restart the timer for next time */
ptm_bfd_start_xmt_timer(bfd, true);
state_list[bfd->ses_state].str,
get_diag_str(bfd->local_diag));
}
+
+ /* clear peer's mac address */
+ UNSET_FLAG(bfd->flags, BFD_SESS_FLAG_MAC_SET);
+ memset(bfd->peer_hw_addr, 0, sizeof(bfd->peer_hw_addr));
+ /* reset local address ,it might has been be changed after bfd is up*/
+ memset(&bfd->local_address, 0, sizeof(bfd->local_address));
+
+ /* reset RTT */
+ bfd_rtt_init(bfd);
}
static struct bfd_session *bfd_find_disc(struct sockaddr_any *sa,
return bfd_key_lookup(key);
}
-int bfd_xmt_cb(struct thread *t)
+void bfd_xmt_cb(struct thread *t)
{
struct bfd_session *bs = THREAD_ARG(t);
ptm_bfd_xmt_TO(bs, 0);
-
- return 0;
}
-int bfd_echo_xmt_cb(struct thread *t)
+void bfd_echo_xmt_cb(struct thread *t)
{
struct bfd_session *bs = THREAD_ARG(t);
if (bs->echo_xmt_TO > 0)
ptm_bfd_echo_xmt_TO(bs);
-
- return 0;
}
/* Was ptm_bfd_detect_TO() */
-int bfd_recvtimer_cb(struct thread *t)
+void bfd_recvtimer_cb(struct thread *t)
{
struct bfd_session *bs = THREAD_ARG(t);
ptm_bfd_sess_dn(bs, BD_CONTROL_EXPIRED);
break;
}
-
- return 0;
}
/* Was ptm_bfd_echo_detect_TO() */
-int bfd_echo_recvtimer_cb(struct thread *t)
+void bfd_echo_recvtimer_cb(struct thread *t)
{
struct bfd_session *bs = THREAD_ARG(t);
ptm_bfd_sess_dn(bs, BD_ECHO_FAILED);
break;
}
-
- return 0;
}
struct bfd_session *bfd_session_new(void)
* Apply profile last: it also calls `bfd_set_shutdown`.
*
* There is no problem calling `shutdown` twice if the value doesn't
- * change or if it is overriden by peer specific configuration.
+ * change or if it is overridden by peer specific configuration.
*/
if (bpc->bpc_has_profile)
bfd_profile_apply(bpc->bpc_profile, bs);
}
if (bglobal.debug_peer_event)
- zlog_debug("session-delete: %s", bs_to_string(bs));
+ zlog_debug("%s: %s", __func__, bs_to_string(bs));
control_notify_config(BCM_NOTIFY_CONFIG_DELETE, bs);
*/
bs->ses_state = PTM_BFD_INIT;
- /* Answer peer with INIT immediately in passive mode. */
+ /*
+ * RFC 5880, Section 6.1.
+ * A system taking the Passive role MUST NOT begin
+ * sending BFD packets for a particular session until
+ * it has received a BFD packet for that session, and thus
+ * has learned the remote system's discriminator value.
+ *
+ * Now we can start transmission timer in passive mode.
+ */
if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_PASSIVE))
- ptm_bfd_snd(bs, 0);
+ ptm_bfd_xmt_TO(bs, 0);
+
break;
case PTM_BFD_INIT:
* Remote peer doesn't want to talk, so lets make the
* connection down.
*/
- bs->ses_state = PTM_BFD_DOWN;
+ ptm_bfd_sess_dn(bs, BD_NEIGHBOR_DOWN);
break;
case PTM_BFD_DOWN:
}
}
-static void bs_neighbour_admin_down_handler(struct bfd_session *bfd,
- uint8_t diag)
-{
- int old_state = bfd->ses_state;
-
- bfd->local_diag = diag;
- bfd->discrs.remote_discr = 0;
- bfd->ses_state = PTM_BFD_DOWN;
- bfd->polling = 0;
- bfd->demand_mode = 0;
- monotime(&bfd->downtime);
-
- /* Slow down the control packets, the connection is down. */
- bs_set_slow_timers(bfd);
-
- /* only signal clients when going from up->down state */
- if (old_state == PTM_BFD_UP)
- control_notify(bfd, PTM_BFD_ADM_DOWN);
-
- /* Stop echo packet transmission if they are 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++;
- 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));
- }
-}
-
static void bs_up_handler(struct bfd_session *bs, int nstate)
{
switch (nstate) {
case PTM_BFD_ADM_DOWN:
- bs_neighbour_admin_down_handler(bs, BD_ADMIN_DOWN);
- break;
-
case PTM_BFD_DOWN:
/* Peer lost or asked to shutdown connection. */
ptm_bfd_sess_dn(bs, BD_NEIGHBOR_DOWN);
void integer2timestr(uint64_t time, char *buf, size_t buflen)
{
- unsigned int year, month, day, hour, minute, second;
+ uint64_t year, month, day, hour, minute, second;
int rv;
#define MINUTES (60)
year = time / YEARS;
time -= year * YEARS;
- rv = snprintf(buf, buflen, "%u year(s), ", year);
+ rv = snprintfrr(buf, buflen, "%" PRIu64 " year(s), ", year);
buf += rv;
buflen -= rv;
}
month = time / MONTHS;
time -= month * MONTHS;
- rv = snprintf(buf, buflen, "%u month(s), ", month);
+ rv = snprintfrr(buf, buflen, "%" PRIu64 " month(s), ", month);
buf += rv;
buflen -= rv;
}
day = time / DAYS;
time -= day * DAYS;
- rv = snprintf(buf, buflen, "%u day(s), ", day);
+ rv = snprintfrr(buf, buflen, "%" PRIu64 " day(s), ", day);
buf += rv;
buflen -= rv;
}
hour = time / HOURS;
time -= hour * HOURS;
- rv = snprintf(buf, buflen, "%u hour(s), ", hour);
+ rv = snprintfrr(buf, buflen, "%" PRIu64 " hour(s), ", hour);
buf += rv;
buflen -= rv;
}
minute = time / MINUTES;
time -= minute * MINUTES;
- rv = snprintf(buf, buflen, "%u minute(s), ", minute);
+ rv = snprintfrr(buf, buflen, "%" PRIu64 " minute(s), ", minute);
buf += rv;
buflen -= rv;
}
second = time % MINUTES;
- snprintf(buf, buflen, "%u second(s)", second);
+ snprintfrr(buf, buflen, "%" PRIu64 " second(s)", second);
}
const char *bs_to_string(const struct bfd_session *bs)
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)
- bvrf->bg_shop = bp_udp_shop(vrf);
- if (!bvrf->bg_mhop)
- bvrf->bg_mhop = bp_udp_mhop(vrf);
- if (!bvrf->bg_shop6)
- bvrf->bg_shop6 = bp_udp6_shop(vrf);
- if (!bvrf->bg_mhop6)
- bvrf->bg_mhop6 = bp_udp6_mhop(vrf);
- if (!bvrf->bg_echo)
- bvrf->bg_echo = bp_echo_socket(vrf);
- if (!bvrf->bg_echov6)
- bvrf->bg_echov6 = bp_echov6_socket(vrf);
-
- if (!bvrf->bg_ev[0] && bvrf->bg_shop != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_shop, &bvrf->bg_ev[0]);
- if (!bvrf->bg_ev[1] && bvrf->bg_mhop != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_mhop, &bvrf->bg_ev[1]);
- if (!bvrf->bg_ev[2] && bvrf->bg_shop6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_shop6, &bvrf->bg_ev[2]);
- if (!bvrf->bg_ev[3] && bvrf->bg_mhop6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_mhop6, &bvrf->bg_ev[3]);
- if (!bvrf->bg_ev[4] && bvrf->bg_echo != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_echo, &bvrf->bg_ev[4]);
- if (!bvrf->bg_ev[5] && bvrf->bg_echov6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_echov6, &bvrf->bg_ev[5]);
- }
+ if (!bvrf->bg_shop)
+ bvrf->bg_shop = bp_udp_shop(vrf);
+ if (!bvrf->bg_mhop)
+ bvrf->bg_mhop = bp_udp_mhop(vrf);
+ if (!bvrf->bg_shop6)
+ bvrf->bg_shop6 = bp_udp6_shop(vrf);
+ if (!bvrf->bg_mhop6)
+ bvrf->bg_mhop6 = bp_udp6_mhop(vrf);
+ if (!bvrf->bg_echo)
+ bvrf->bg_echo = bp_echo_socket(vrf);
+ if (!bvrf->bg_echov6)
+ bvrf->bg_echov6 = bp_echov6_socket(vrf);
+
+ if (!bvrf->bg_ev[0] && bvrf->bg_shop != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop,
+ &bvrf->bg_ev[0]);
+ if (!bvrf->bg_ev[1] && bvrf->bg_mhop != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop,
+ &bvrf->bg_ev[1]);
+ if (!bvrf->bg_ev[2] && bvrf->bg_shop6 != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6,
+ &bvrf->bg_ev[2]);
+ if (!bvrf->bg_ev[3] && bvrf->bg_mhop6 != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6,
+ &bvrf->bg_ev[3]);
+ if (!bvrf->bg_ev[4] && bvrf->bg_echo != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echo,
+ &bvrf->bg_ev[4]);
+ if (!bvrf->bg_ev[5] && bvrf->bg_echov6 != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6,
+ &bvrf->bg_ev[5]);
+
if (vrf->vrf_id != VRF_DEFAULT) {
bfdd_zclient_register(vrf->vrf_id);
bfdd_sessions_enable_vrf(vrf);
{
return bfd_key_hash->count;
}
+
+void bfd_rtt_init(struct bfd_session *bfd)
+{
+ uint8_t i;
+
+ /* initialize RTT */
+ bfd->rtt_valid = 0;
+ bfd->rtt_index = 0;
+ for (i = 0; i < BFD_RTT_SAMPLE; i++)
+ bfd->rtt[i] = 0;
+}