summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Wang <alexw@nicira.com>2013-12-20 14:53:52 -0800
committerJarno Rajahalme <jrajahalme@nicira.com>2013-12-20 14:53:52 -0800
commit60d02c72941d5a4aeea85090f120a0cc03e945f2 (patch)
treee49e34222f69d679098512bcea7c1c0d9fd3e68d
parentd1890de500d012d512ac7a680a2a0dc5e8acf444 (diff)
downloadopenvswitch-60d02c72941d5a4aeea85090f120a0cc03e945f2.tar.gz
bfd: Send FINAL immediately after receiving POLL.
Commit 307464a11 (ofproto-dpif-monitor: Use heap to order the mport wakeup time.) makes bfd only send packet at specified periodic instant. This fails to meet the RFC5880 requirement, which requires bfd send FINAL immediately after receiving POLL. This commit fixes the above issue by scheduling bfd to send FINAL within 100 ms after receiving POLL. Signed-off-by: Alex Wang <alexw@nicira.com>
-rw-r--r--ofproto/ofproto-dpif-monitor.c29
-rw-r--r--ofproto/ofproto-dpif-monitor.h3
-rw-r--r--ofproto/ofproto-dpif-xlate.c9
3 files changed, 39 insertions, 2 deletions
diff --git a/ofproto/ofproto-dpif-monitor.c b/ofproto/ofproto-dpif-monitor.c
index af66387b7..f67f0363a 100644
--- a/ofproto/ofproto-dpif-monitor.c
+++ b/ofproto/ofproto-dpif-monitor.c
@@ -225,8 +225,9 @@ monitor_run(void)
bfd_wait(mport->bfd);
}
/* Computes the next wakeup time for this mport. */
- next_wake_time = MIN(bfd_wake_time(mport->bfd), cfm_wake_time(mport->cfm));
- heap_change(&monitor_heap, heap_max(&monitor_heap),
+ next_wake_time = MIN(bfd_wake_time(mport->bfd),
+ cfm_wake_time(mport->cfm));
+ heap_change(&monitor_heap, &mport->heap_node,
MSEC_TO_PRIO(next_wake_time));
}
@@ -275,3 +276,27 @@ ofproto_dpif_monitor_port_update(const struct ofport_dpif *ofport,
monitor_running = false;
}
}
+
+/* Moves the mport on top of the heap. This is necessary when
+ * for example, bfd POLL is received and the mport should
+ * immediately send FINAL back. */
+void
+ofproto_dpif_monitor_port_send_soon_safe(const struct ofport_dpif *ofport)
+{
+ ovs_rwlock_wrlock(&monitor_rwlock);
+ ofproto_dpif_monitor_port_send_soon(ofport);
+ ovs_rwlock_unlock(&monitor_rwlock);
+}
+
+void
+ofproto_dpif_monitor_port_send_soon(const struct ofport_dpif *ofport)
+ OVS_REQ_WRLOCK(monitor_rwlock)
+{
+ struct mport *mport;
+
+ monitor_init();
+ mport = mport_find(ofport);
+ if (mport) {
+ heap_change(&monitor_heap, &mport->heap_node, LLONG_MAX);
+ }
+}
diff --git a/ofproto/ofproto-dpif-monitor.h b/ofproto/ofproto-dpif-monitor.h
index f914fbe93..1f6be5cf9 100644
--- a/ofproto/ofproto-dpif-monitor.h
+++ b/ofproto/ofproto-dpif-monitor.h
@@ -23,6 +23,9 @@ struct bfd;
struct cfm;
struct ofport_dpif;
+void ofproto_dpif_monitor_port_send_soon(const struct ofport_dpif *);
+void ofproto_dpif_monitor_port_send_soon_safe(const struct ofport_dpif *);
+
void ofproto_dpif_monitor_port_update(const struct ofport_dpif *,
struct bfd *, struct cfm *,
uint8_t[OFP_ETH_ALEN]);
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 09406b72a..848c7780b 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -42,6 +42,7 @@
#include "ofp-actions.h"
#include "ofproto/ofproto-dpif-ipfix.h"
#include "ofproto/ofproto-dpif-mirror.h"
+#include "ofproto/ofproto-dpif-monitor.h"
#include "ofproto/ofproto-dpif-sflow.h"
#include "ofproto/ofproto-dpif.h"
#include "ofproto/ofproto-provider.h"
@@ -1645,6 +1646,14 @@ process_special(struct xlate_ctx *ctx, const struct flow *flow,
} else if (xport->bfd && bfd_should_process_flow(xport->bfd, flow, wc)) {
if (packet) {
bfd_process_packet(xport->bfd, flow, packet);
+ /* If POLL received, immediately sends FINAL back. */
+ if (bfd_should_send_packet(xport->bfd)) {
+ if (xport->peer) {
+ ofproto_dpif_monitor_port_send_soon(xport->ofport);
+ } else {
+ ofproto_dpif_monitor_port_send_soon_safe(xport->ofport);
+ }
+ }
}
return SLOW_BFD;
} else if (xport->xbundle && xport->xbundle->lacp