summaryrefslogtreecommitdiff
path: root/bfdd/bfd_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfdd/bfd_packet.c')
-rw-r--r--bfdd/bfd_packet.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index 3d6ca6ddd3..652b914118 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -546,8 +546,6 @@ int bfd_recv_cb(struct thread *t)
struct interface *ifp = NULL;
struct bfd_vrf_global *bvrf = THREAD_ARG(t);
- vrfid = bvrf->vrf->vrf_id;
-
/* Schedule next read. */
bfd_sd_reschedule(bvrf, sd);
@@ -573,13 +571,19 @@ int bfd_recv_cb(struct thread *t)
&local, &peer);
}
- /* update vrf-id because when in vrf-lite mode,
- * the socket is on default namespace
+ /*
+ * With netns backend, we have a separate socket in each VRF. It means
+ * that bvrf here is correct and we believe the bvrf->vrf->vrf_id.
+ * With VRF-lite backend, we have a single socket in the default VRF.
+ * It means that we can't believe the bvrf->vrf->vrf_id. But in
+ * VRF-lite, the ifindex is globally unique, so we can retrieve the
+ * correct vrf_id from the interface.
*/
+ vrfid = bvrf->vrf->vrf_id;
if (ifindex) {
ifp = if_lookup_by_index(ifindex, vrfid);
if (ifp)
- vrfid = ifp->vrf_id;
+ vrfid = ifp->vrf->vrf_id;
}
/* Implement RFC 5880 6.8.6 */
@@ -628,7 +632,7 @@ int bfd_recv_cb(struct thread *t)
}
/* Find the session that this packet belongs. */
- bfd = ptm_bfd_sess_find(cp, &peer, &local, ifindex, vrfid, is_mhop);
+ bfd = ptm_bfd_sess_find(cp, &peer, &local, ifp, vrfid, is_mhop);
if (bfd == NULL) {
cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"no session found");
@@ -657,7 +661,7 @@ int bfd_recv_cb(struct thread *t)
* packet came in.
*/
if (!is_mhop && bfd->ifp == NULL)
- bfd->ifp = if_lookup_by_index(ifindex, vrfid);
+ bfd->ifp = ifp;
/* Log remote discriminator changes. */
if ((bfd->discrs.remote_discr != 0)
@@ -693,11 +697,26 @@ int bfd_recv_cb(struct thread *t)
/* Handle poll finalization. */
bs_final_handler(bfd);
- } else {
- /* Received a packet, lets update the receive timer. */
- bfd_recvtimer_update(bfd);
}
+ /*
+ * Detection timeout calculation:
+ * The minimum detection timeout is the remote detection
+ * multipler (number of packets to be missed) times the agreed
+ * transmission interval.
+ *
+ * RFC 5880, Section 6.8.4.
+ */
+ if (bfd->cur_timers.required_min_rx > bfd->remote_timers.desired_min_tx)
+ bfd->detect_TO = bfd->remote_detect_mult
+ * bfd->cur_timers.required_min_rx;
+ else
+ bfd->detect_TO = bfd->remote_detect_mult
+ * bfd->remote_timers.desired_min_tx;
+
+ /* Apply new receive timer immediately. */
+ bfd_recvtimer_update(bfd);
+
/* Handle echo timers changes. */
bs_echo_timer_handler(bfd);