}
/* Toggle 'passive-mode' if default value. */
- if (bs->peer_profile.passive == false)
- bfd_set_passive_mode(bs, bp->passive);
- else
- bfd_set_passive_mode(bs, bs->peer_profile.passive);
+ if (bs->bfd_mode == BFD_MODE_TYPE_BFD) {
+ if (bs->peer_profile.passive == false)
+ bfd_set_passive_mode(bs, bp->passive);
+ else
+ bfd_set_passive_mode(bs, bs->peer_profile.passive);
+ }
/* Toggle 'no shutdown' if default value. */
if (bs->peer_profile.admin_shutdown == false)
* could use the destination port (3784) for the source
* port we wouldn't need a socket per session.
*/
- if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6) == 0) {
+ if (bs->bfd_mode == BFD_MODE_TYPE_SBFD_ECHO || bs->bfd_mode == BFD_MODE_TYPE_SBFD_INIT) {
+ psock = bp_peer_srh_socketv6(bs);
+ if (psock <= 0) {
+ zlog_err("bp_peer_srh_socketv6 error");
+ return 0;
+ }
+ } else if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6) == 0) {
psock = bp_peer_socket(bs);
- if (psock == -1)
+ if (psock == -1) {
+ zlog_err("bp_peer_socket error");
return 0;
+ }
} else {
psock = bp_peer_socketv6(bs);
- if (psock == -1)
+ if (psock == -1) {
+ zlog_err("bp_peer_socketv6 error");
return 0;
+ }
}
/*
/* Only start timers if we are using active mode. */
if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_PASSIVE) == 0) {
- bfd_recvtimer_update(bs);
- ptm_bfd_start_xmt_timer(bs, false);
- }
+ if (bs->bfd_mode == BFD_MODE_TYPE_SBFD_ECHO) {
+ /*enable receive echo response*/
+ bfd_set_echo(bs, true);
+ bs->echo_detect_TO = (bs->remote_detect_mult * bs->echo_xmt_TO);
+ sbfd_echo_recvtimer_update(bs);
+ ptm_bfd_start_xmt_timer(bs, true);
+ } else {
+ bfd_recvtimer_update(bs);
+ ptm_bfd_start_xmt_timer(bs, false);
+ }
+ }
/* initialize RTT */
bfd_rtt_init(bs);
bfd_recvtimer_delete(bs);
bfd_xmttimer_delete(bs);
ptm_bfd_echo_stop(bs);
+ bs->vrf = NULL;
+ bs->ifp = NULL;
/* Set session down so it doesn't report UP and disabled. */
ptm_bfd_sess_dn(bs, BD_PATH_DOWN);
jitter = (xmt_TO * (75 + (frr_weak_random() % maxpercent))) / 100;
/* XXX remove that division above */
- if (is_echo)
- bfd_echo_xmttimer_update(bfd, jitter);
- else
- bfd_xmttimer_update(bfd, jitter);
+ if (bfd->bfd_mode == BFD_MODE_TYPE_SBFD_ECHO || bfd->bfd_mode == BFD_MODE_TYPE_SBFD_INIT) {
+ if (is_echo)
+ sbfd_echo_xmttimer_update(bfd, jitter);
+ else
+ sbfd_init_xmttimer_update(bfd, jitter);
+
+ } else {
+ if (is_echo)
+ bfd_echo_xmttimer_update(bfd, jitter);
+ else
+ bfd_xmttimer_update(bfd, jitter);
+ }
}
static void ptm_bfd_echo_xmt_TO(struct bfd_session *bfd)
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));
+ if (bfd->bfd_mode == BFD_MODE_TYPE_BFD)
+ memset(&bfd->local_address, 0, sizeof(bfd->local_address));
/* reset RTT */
bfd_rtt_init(bfd);
{
struct bfd_session *bs = EVENT_ARG(t);
+ if (bglobal.debug_peer_event) {
+ zlog_debug("%s: time-out bfd: [%s] bfd'state is %s", __func__, bs_to_string(bs),
+ state_list[bs->ses_state].str);
+ }
+
switch (bs->ses_state) {
case PTM_BFD_INIT:
case PTM_BFD_UP:
/* Set the appropriated timeouts for slow connection. */
bs->detect_TO = (BFD_DEFDETECTMULT * BFD_DEF_SLOWTX);
bs->xmt_TO = BFD_DEF_SLOWTX;
+
+ /* add for sbfd-echo slow connection */
+ if (BFD_MODE_TYPE_SBFD_ECHO == bs->bfd_mode) {
+ bs->echo_xmt_TO = SBFD_ECHO_DEF_SLOWTX;
+ bs->timers.desired_min_echo_tx = BFD_DEFDESIREDMINTX;
+ bs->timers.required_min_echo_rx = BFD_DEFDESIREDMINTX;
+ bs->peer_profile.min_echo_rx = BFD_DEFDESIREDMINTX;
+ bs->peer_profile.min_echo_tx = BFD_DEFDESIREDMINTX;
+ }
}
void bfd_set_echo(struct bfd_session *bs, bool echo)
if (bs->key.ifname[0])
pos += snprintf(buf + pos, sizeof(buf) - pos, " ifname:%s",
bs->key.ifname);
+ if (bs->bfd_name[0])
+ pos += snprintf(buf + pos, sizeof(buf) - pos, " bfd_name:%s", bs->bfd_name);
(void)pos;
if (memcmp(bs1->key.vrfname, bs2->key.vrfname,
sizeof(bs1->key.vrfname)))
return false;
+ if (memcmp(bs1->key.bfdname, bs2->key.bfdname, sizeof(bs1->key.bfdname)))
+ return false;
/*
* Local address is optional and can be empty.
bvrf->bg_mhop6 = -1;
bvrf->bg_echo = -1;
bvrf->bg_echov6 = -1;
+ bvrf->bg_initv6 = -1;
return 0;
}
bvrf->bg_shop6 = bp_udp6_shop(vrf);
if (bvrf->bg_mhop6 == -1)
bvrf->bg_mhop6 = bp_udp6_mhop(vrf);
+ if (bvrf->bg_initv6 == -1)
+ bvrf->bg_initv6 = bp_initv6_socket(vrf);
if (bvrf->bg_ev[0] == NULL && bvrf->bg_shop != -1)
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop,
if (bvrf->bg_ev[3] == NULL && bvrf->bg_mhop6 != -1)
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6,
&bvrf->bg_ev[3]);
+ if (bvrf->bg_ev[6] == NULL && bvrf->bg_initv6 != -1)
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_initv6, &bvrf->bg_ev[6]);
/* Toggle echo if VRF was disabled. */
bfd_vrf_toggle_echo(bvrf);
EVENT_OFF(bvrf->bg_ev[3]);
EVENT_OFF(bvrf->bg_ev[4]);
EVENT_OFF(bvrf->bg_ev[5]);
+ EVENT_OFF(bvrf->bg_ev[6]);
/* Close all descriptors. */
socket_close(&bvrf->bg_echo);
socket_close(&bvrf->bg_shop6);
socket_close(&bvrf->bg_mhop6);
socket_close(&bvrf->bg_echov6);
+ socket_close(&bvrf->bg_initv6);
return 0;
}
#ifdef BFD_LINUX
#include <linux/if_packet.h>
+#include <linux/seg6.h>
+#include <linux/ipv6.h>
#endif /* BFD_LINUX */
#include <netinet/if_ether.h>
/* Compute detect time */
bfd->echo_detect_TO = bfd->remote_detect_mult * bfd->echo_xmt_TO;
- /* Update echo receive timeout. */
+ /* Update sbfd-echo session state */
+ if (bfd->bfd_mode == BFD_MODE_TYPE_SBFD_ECHO) {
+ sbfd_echo_state_handler(bfd, PTM_BFD_UP);
+
+ if (bfd->echo_xmt_TO != bfd->timers.desired_min_echo_tx) {
+ bfd->echo_xmt_TO = bfd->timers.desired_min_echo_tx;
+ //reset xmt timer TO after UP
+ ptm_bfd_start_xmt_timer(bfd, true);
+ }
+
+ bfd->echo_detect_TO = bfd->detect_mult * bfd->echo_xmt_TO;
+ /* Update sbfd echo receive timeout. */
+ if (bfd->echo_detect_TO > 0)
+ sbfd_echo_recvtimer_update(bfd);
+ return 0;
+ }
+
+ /* Update bfd-echo receive timeout. */
if (bfd->echo_detect_TO > 0)
bfd_echo_recvtimer_update(bfd);
EVENT_OFF(bvrf->bg_ev[5]);
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6,
&bvrf->bg_ev[5]);
+ } else if (sd == bvrf->bg_initv6) {
+ EVENT_OFF(bvrf->bg_ev[6]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_initv6, &bvrf->bg_ev[6]);
}
}
/* Schedule next read. */
bfd_sd_reschedule(bvrf, sd);
+ /* The reflector handle SBFD init packets. */
+ if (sd == bvrf->bg_initv6) {
+ ptm_bfd_reflector_process_init_packet(bvrf, sd);
+ return;
+ }
/* Handle echo packets. */
if (sd == bvrf->bg_echo || sd == bvrf->bg_echov6) {
ptm_bfd_process_echo_pkt(bvrf, sd);
else
bfd->remote_cbit = 0;
+ /* The initiator handle SBFD reflect packet. */
+ if (bfd->bfd_mode == BFD_MODE_TYPE_SBFD_INIT) {
+ sbfd_initiator_state_handler(bfd, PTM_BFD_UP);
+ if (bfd->xmt_TO != bfd->timers.desired_min_tx) {
+ bfd->xmt_TO = bfd->timers.desired_min_tx;
+ //reset xmt timer TO after UP
+ ptm_bfd_start_xmt_timer(bfd, false);
+ }
+
+ bfd->detect_TO = bfd->detect_mult * bfd->xmt_TO;
+ sbfd_init_recvtimer_update(bfd);
+
+ if (bfd->polling && BFD_GETFBIT(cp->flags)) {
+ /* Disable polling. */
+ bfd->polling = 0;
+ /* Start using our new timers. */
+ bfd->cur_timers.desired_min_tx = bfd->timers.desired_min_tx;
+ bfd->cur_timers.required_min_rx = bfd->timers.required_min_rx;
+ }
+
+ return;
+ }
+
/* State switch from section 6.2. */
bs_state_handler(bfd, BFD_GETSTATE(cp->flags));