static ULARGE_INTEGER unix_epoch;
#endif /* _WIN32 */
+/* Structure set by unixctl time/warp command. */
+struct large_warp {
+ struct unixctl_conn *conn; /* Connection waiting for warp response. */
+ long long int total_warp; /* Total offset to be added to monotonic time. */
+ long long int warp; /* 'total_warp' offset done in steps of 'warp'. */
+ unsigned int main_thread_id; /* Identification for the main thread. */
+};
+
struct clock {
clockid_t id; /* CLOCK_MONOTONIC or CLOCK_REALTIME. */
struct timespec warp OVS_GUARDED; /* Offset added for unit tests. */
bool stopped OVS_GUARDED; /* Disable real-time updates if true. */
struct timespec cache OVS_GUARDED; /* Last time read from kernel. */
+ struct large_warp large_warp OVS_GUARDED; /* Connection information waiting
+ for warp response. */
};
/* Our clocks. */
atomic_init(&c->slow_path, false);
xclock_gettime(c->id, &c->cache);
timewarp_seq = seq_create();
+ memset(&c->large_warp, 0, sizeof(c->large_warp));
}
static void
}
}
-/* Makes threads wait on timewarp_seq and be waken up when time is warped.
- * This function will be no-op unless timeval_dummy_register() is called. */
+static void
+msec_to_timespec(long long int ms, struct timespec *ts)
+{
+ ts->tv_sec = ms / 1000;
+ ts->tv_nsec = (ms % 1000) * 1000 * 1000;
+}
+
+static void
+timewarp_work(void)
+{
+ struct clock *c = &monotonic_clock;
+ struct timespec warp;
+
+ ovs_mutex_lock(&c->mutex);
+ if (!c->large_warp.conn) {
+ ovs_mutex_unlock(&c->mutex);
+ return;
+ }
+
+ if (c->large_warp.total_warp >= c->large_warp.warp) {
+ msec_to_timespec(c->large_warp.warp, &warp);
+ timespec_add(&c->warp, &c->warp, &warp);
+ c->large_warp.total_warp -= c->large_warp.warp;
+ } else if (c->large_warp.total_warp) {
+ msec_to_timespec(c->large_warp.total_warp, &warp);
+ timespec_add(&c->warp, &c->warp, &warp);
+ c->large_warp.total_warp = 0;
+ } else {
+ /* c->large_warp.total_warp is 0. */
+ msec_to_timespec(c->large_warp.warp, &warp);
+ timespec_add(&c->warp, &c->warp, &warp);
+ }
+
+ if (!c->large_warp.total_warp) {
+ unixctl_command_reply(c->large_warp.conn, "warped");
+ c->large_warp.conn = NULL;
+ }
+
+ ovs_mutex_unlock(&c->mutex);
+ seq_change(timewarp_seq);
+
+ /* give threads (eg. monitor) some chances to run */
+#ifndef _WIN32
+ poll(NULL, 0, 10);
+#else
+ Sleep(10);
+#endif
+}
+
+/* Perform work needed for "timewarp_seq"'s producer and consumers. */
void
-timewarp_wait(void)
+timewarp_run(void)
{
+ /* The function is a no-op unless timeval_dummy_register() is called. */
if (timewarp_enabled) {
- uint64_t *last_seq = last_seq_get();
-
- *last_seq = seq_read(timewarp_seq);
- seq_wait(timewarp_seq, *last_seq);
+ unsigned int thread_id;
+ ovs_mutex_lock(&monotonic_clock.mutex);
+ thread_id = monotonic_clock.large_warp.main_thread_id;
+ ovs_mutex_unlock(&monotonic_clock.mutex);
+
+ if (thread_id != ovsthread_id_self()) {
+ /* For threads other than the thread that changes the sequence,
+ * wait on it. */
+ uint64_t *last_seq = last_seq_get();
+
+ *last_seq = seq_read(timewarp_seq);
+ seq_wait(timewarp_seq, *last_seq);
+ } else {
+ /* Work on adding the remaining warps. */
+ timewarp_work();
+ }
}
}
* number of milliseconds. Unless "time/stop" has also been executed, the
* monotonic clock continues to tick forward at the normal rate afterward.
*
+ * "time/warp LARGE_MSECS MSECS" is a variation of the above command. It
+ * advances the current monotonic time by LARGE_MSECS. This is done MSECS
+ * at a time in each run of the main thread. This gives other threads
+ * time to run after the clock has been advanced by MSECS.
+ *
* Does not affect wall clock readings. */
static void
timeval_warp_cb(struct unixctl_conn *conn,
int argc OVS_UNUSED, const char *argv[], void *aux OVS_UNUSED)
{
- struct timespec ts;
- int msecs;
-
- msecs = atoi(argv[1]);
- if (msecs <= 0) {
+ long long int total_warp = argc > 2 ? atoll(argv[1]) : 0;
+ long long int msecs = argc > 2 ? atoll(argv[2]) : atoll(argv[1]);
+ if (msecs <= 0 || total_warp < 0) {
unixctl_command_reply_error(conn, "invalid MSECS");
return;
}
- ts.tv_sec = msecs / 1000;
- ts.tv_nsec = (msecs % 1000) * 1000 * 1000;
-
ovs_mutex_lock(&monotonic_clock.mutex);
+ if (monotonic_clock.large_warp.conn) {
+ ovs_mutex_unlock(&monotonic_clock.mutex);
+ unixctl_command_reply_error(conn, "A previous warp in progress");
+ return;
+ }
atomic_store(&monotonic_clock.slow_path, true);
- timespec_add(&monotonic_clock.warp, &monotonic_clock.warp, &ts);
+ monotonic_clock.large_warp.conn = conn;
+ monotonic_clock.large_warp.total_warp = total_warp;
+ monotonic_clock.large_warp.warp = msecs;
+ monotonic_clock.large_warp.main_thread_id = ovsthread_id_self();
ovs_mutex_unlock(&monotonic_clock.mutex);
- seq_change(timewarp_seq);
- /* give threads (eg. monitor) some chances to run */
-#ifndef _WIN32
- poll(NULL, 0, 10);
-#else
- Sleep(10);
-#endif
- unixctl_command_reply(conn, "warped");
+
+ timewarp_work();
}
void
{
timewarp_enabled = true;
unixctl_command_register("time/stop", "", 0, 0, timeval_stop_cb, NULL);
- unixctl_command_register("time/warp", "MSECS", 1, 1,
+ unixctl_command_register("time/warp", "[LARGE_MSECS] MSECS", 1, 2,
timeval_warp_cb, NULL);
}
set Interface p0 bfd:enable=true -- \
set Interface p1 bfd:enable=true ])
ovs-appctl time/stop
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
#Verify that BFD has been enabled on both interfaces.
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
AT_CHECK([ ovs-vsctl set interface p0 bfd:enable=false])
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
BFD_CHECK([p1], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic])
AT_CHECK([ ovs-vsctl set interface p0 bfd:enable=true])
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
BFD_CHECK([p1], [true], [false], [none], [up], [Control Detection Time Expired], [none], [up], [No Diagnostic])
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [Control Detection Time Expired])
AT_CHECK([ovs-ofctl add-flow br-sw 'priority=0,actions=NORMAL'])
#Verify that BFD is enabled.
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
#Drop all packets in the br-sw bridge so that the tunnel is down.
AT_CHECK([ ovs-ofctl add-flow br-sw 'priority=5,actions=drop' ])
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
BFD_CHECK([p1], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic])
BFD_CHECK([p0], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic])
AT_CHECK([ovs-ofctl del-flows br-sw], [0])
AT_CHECK([ovs-ofctl add-flow br-sw 'priority=0,actions=NORMAL'])
#Verify that BFD is back up again.
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
BFD_CHECK([p1], [true], [false], [none], [up], [Control Detection Time Expired], [none], [up], [Control Detection Time Expired])
BFD_CHECK([p0], [true], [false], [none], [up], [Control Detection Time Expired], [none], [up], [Control Detection Time Expired])
# but not received by p1. p0 will receive all BFD packets from p1.
AT_CHECK([ ovs-ofctl add-flow br-sw 'in_port=1,priority=5,actions=drop'])
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
# Make sure p1 BFD state is down since it received no BFD packets.
BFD_CHECK([p1], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic])
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
+
# p0 will be in init state once it receives "down" BFD message from p1.
BFD_CHECK([p0], [false], [false], [none], [init], [Neighbor Signaled Session Down], [none], [down], [Control Detection Time Expired])
AT_CHECK([ovs-ofctl add-flow br-sw 'priority=0,actions=NORMAL'])
#Ensure that BFD is back up again.
-for i in `seq 0 10`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 1100 100
#Bring down the br-bfd0 - br-sw link
AT_CHECK([ ovs-ofctl add-flow br-sw 'in_port=2,priority=5,actions=drop'])
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
BFD_CHECK([p0], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic])
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
BFD_CHECK([p1], [false], [false], [none], [init], [Neighbor Signaled Session Down], [none], [down], [Control Detection Time Expired])
OVS_VSWITCHD_STOP
AT_CLEANUP
options:peer=p1 ])
AT_CHECK([ ovs-vsctl -- set interface p0 bfd:enable=true ])
AT_CHECK([ ovs-vsctl -- set interface p1 bfd:enable=true ])
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
#Verify that BFD has been enabled on both interfaces.
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
#Set cpath_down to true on one interface, make sure the remote interface updates its values.
AT_CHECK([ovs-vsctl set interface p0 bfd:cpath_down=true])
-for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 4100 100
BFD_CHECK([p1], [false], [false], [none], [up], [No Diagnostic], [none], [up], [Concatenated Path Down])
OVS_VSWITCHD_STOP
AT_CLEANUP
options:peer=p1 ])
AT_CHECK([ ovs-vsctl -- set interface p0 bfd:enable=true ])
AT_CHECK([ ovs-vsctl -- set interface p1 bfd:enable=true ])
-for i in `seq 0 30`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 3100 100
#Verify that BFD has been enabled on both interfaces.
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
#Edit the min Tx value.
AT_CHECK([ovs-vsctl set interface p0 bfd:min_tx=200])
-for i in `seq 0 20`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 2100 100
BFD_CHECK_TX([p0], [1000ms], [200ms], [100ms])
BFD_CHECK_TX([p1], [1000ms], [100ms], [200ms])
#Edit the min Rx value.
AT_CHECK([ovs-vsctl set interface p1 bfd:min_rx=300])
-for i in `seq 0 20`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 2100 100
BFD_CHECK_RX([p1], [300ms], [300ms], [1000ms])
BFD_CHECK_RX([p0], [1000ms], [1000ms], [300ms])
ovs-appctl time/stop
# wait for a while to stablize everything.
-for i in `seq 0 19`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 10000 500
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
AT_CHECK([ovs-vsctl set interface p0 bfd:decay_min_rx=3000])
# bfd:decay_min_rx is set to 3000ms after the local state of p0 goes up,
# so for the first 2000ms, there should be no change.
-for i in `seq 0 3`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 2000 500
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
BFD_CHECK_RX([p0], [500ms], [300ms], [500ms])
# advance the clock by 5000ms.
-for i in `seq 0 9`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 5000 500
# now, min_rx should decay to 3000ms.
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
BFD_CHECK_RX([p0], [3000ms], [3000ms], [500ms])
# advance clock by 5000ms and check the the flags are all 'none'.
-for i in `seq 0 9`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 5000 500
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
# this should firstly reset the min_rx and then re-decay to 1000ms.
AT_CHECK([ovs-vsctl set Interface p0 bfd:decay_min_rx=1000])
# advance the clock by 10000ms, decay should have happened.
-for i in `seq 0 19`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 10000 500
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
# Test-4 BFD decay: set decay_min_rx to 0 to disable bfd decay.
AT_CHECK([ovs-vsctl set Interface p0 bfd:decay_min_rx=0])
# advance the clock by 5000ms.
-for i in `seq 0 9`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 10000 500
# min_rx is reset.
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
BFD_CHECK_RX([p0], [500ms], [300ms], [500ms])
# Test-5 BFD decay: rmt_min_tx is greater than decay_min_rx
AT_CHECK([ovs-vsctl set Interface p0 bfd:decay_min_rx=3000 -- set interface p1 bfd:min_tx=5000])
# advance the clock by 10000ms to stable everything.
-for i in `seq 0 19`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 10000 500
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
# p0 rx should show 5000ms even if it is in decay.
AT_CHECK([ovs-vsctl set Interface p1 bfd:min_tx=500])
# advance the clock by 20000ms to stable everything.
# since p0 has been in decay, now the RX will show 3000ms.
-for i in `seq 0 39`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 20000 500
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
BFD_CHECK_RX([p0], [3000ms], [3000ms], [500ms])
# End of Test-5 ###############################################################
AT_CHECK([ovs-vsctl set Interface p1 bfd:enable=false])
# advance the clock by 15000ms to stable everything.
-for i in `seq 0 14`; do ovs-appctl time/warp 1000; done
+ovs-appctl time/warp 15000 1000
BFD_CHECK([p0], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic])
BFD_CHECK_TX([p0], [1000ms], [1000ms], [0ms])
BFD_CHECK_RX([p0], [300ms], [300ms], [1ms])
# resume the bfd on p1. the bfd should not go to decay mode direclty.
AT_CHECK([ovs-vsctl set Interface p1 bfd:enable=true])
-for i in `seq 0 3`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 1500 500
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
BFD_CHECK_RX([p0], [500ms], [300ms], [500ms])
# since the decay_min_rx is still 3000ms, so after 5000ms, p0 should have decayed.
-for i in `seq 0 9`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 5000 500
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
BFD_CHECK_RX([p0], [3000ms], [3000ms], [500ms])
# End of Test-6 ################################################################
ovs-appctl time/stop
# advance the clock, to stablize the states.
-for i in `seq 0 9`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 5000 500
# enable forwarding_if_rx.
AT_CHECK([ovs-vsctl set Interface p0 bfd:forwarding_if_rx=true], [0])
# re-enable bfd on the other end. the states should be up.
AT_CHECK([ovs-vsctl set Interface p1 bfd:enable=true bfd:min_tx=300 bfd:min_rx=300])
# advance the clock, to stablize the states.
-for i in `seq 0 9`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 5000 500
BFD_CHECK([p0], [true], [false], [none], [up], [Control Detection Time Expired], [none], [up], [No Diagnostic])
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [Control Detection Time Expired])
BFD_CHECK_TX([p0], [500ms], [500ms], [300ms])
ovs-appctl time/stop
# advance the clock, to stablize the states.
-for i in `seq 0 19`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 10000 500
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
AT_CHECK([ovs-vsctl set interface p0 bfd:decay_min_rx=1000])
# wait for 5000ms to decay.
-for i in `seq 0 9`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 5000 500
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
BFD_CHECK_RX([p0], [1000ms], [1000ms], [500ms])
done
# stop receiving for 5000ms.
-for i in `seq 0 49`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 5000 100
BFD_CHECK([p0], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic])
# reset bfd forwarding_if_rx.
# re-enable bfd on the other end. the states should be up.
AT_CHECK([ovs-vsctl set Interface p1 bfd:enable=true bfd:min_tx=300 bfd:min_rx=300])
# advance the clock, to stablize the states.
-for i in `seq 0 19`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 10000 500
BFD_CHECK([p0], [true], [false], [none], [up], [Control Detection Time Expired], [none], [up], [No Diagnostic])
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [Control Detection Time Expired])
BFD_CHECK_TX([p0], [300ms], [300ms], [300ms])
ovs-appctl time/stop
# advance the clock, to stablize the states.
-for i in `seq 0 19`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 10000 500
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
# now enable the bfd on p1 again.
AT_CHECK([ovs-vsctl set Interface p1 bfd:enable=true], [0])
# advance clock by 5000ms. and p1 and p0 should be all up.
-for i in `seq 0 9`; do ovs-appctl time/warp 500; done
+ovs-appctl time/warp 5000 500
BFD_CHECK([p0], [true], [false], [none], [up], [Control Detection Time Expired], [none], [up], [No Diagnostic])
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [Control Detection Time Expired])
BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
ovs-appctl time/stop
# Part-1 wait for a while to stablize bfd.
-for i in `seq 0 100`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 10100 100
BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
BFD_CHECK_TX([p0], [100ms], [100ms], [100ms])
# turn bfd on p1 off, should increment the bfd:flap_count on p0.
AT_CHECK([ovs-vsctl set interface p1 bfd:enable=false])
-for i in `seq 0 49`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 5000 100
BFD_CHECK([p0], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic])
BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["2"])
AT_CHECK([ovs-vsctl list interface p1 | sed -n "s/^.*flap_count=\(.*\), forwarding.*$/\1/p"])
# turn bfd on p1 on again, should increment the bfd:flap_count on p0.
# p1 should still have flap_count = "1", since it is reset.
AT_CHECK([ovs-vsctl set interface p1 bfd:enable=true])
-for i in `seq 0 49`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 5000 100
BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["3"])
BFD_VSCTL_LIST_IFACE([p1], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"])
# turn bfd on p1 off, should not increment the bfd:flap_count on p0, since forwarding_override is on.
AT_CHECK([ovs-vsctl set interface p1 bfd:enable=false])
-for i in `seq 0 49`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 5000 100
BFD_CHECK([p0], [true], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic])
BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["3"])
AT_CHECK([ovs-vsctl list interface p1 | sed -n "s/^.*flap_count=\(.*\), forwarding.*$/\1/p"])
# turn bfd on p1 on again, should not increment the bfd:flap_count on p0, since forwarding override is on.
# p1 should still have flap_count = "1", since it is reset.
AT_CHECK([ovs-vsctl set interface p1 bfd:enable=true])
-for i in `seq 0 49`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 5000 100
BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["3"])
BFD_VSCTL_LIST_IFACE([p1], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"])
# turn bfd on p1 off and on, should increment the bfd:flap_count on p0.
AT_CHECK([ovs-vsctl set interface p1 bfd:enable=false])
-for i in `seq 0 49`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 5000 100
AT_CHECK([ovs-vsctl set interface p1 bfd:enable=true])
-for i in `seq 0 49`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 5000 100
BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["5"])
BFD_VSCTL_LIST_IFACE([p1], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"])
# Part-3 now turn on forwarding_if_rx.
AT_CHECK([ovs-vsctl set Interface p0 bfd:forwarding_if_rx=true], [0])
-for i in `seq 0 10`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 1100 100
# disable the bfd on p1.
AT_CHECK([ovs-vsctl set Interface p1 bfd:enable=false], [0])
# stop the traffic for more than 100 * bfd->cfm_min_rx ms, the forwarding flag of p0 should turn false.
# and there should be the increment of flap_count.
-for i in `seq 0 120`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 12100 100
BFD_CHECK([p0], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic])
BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["6"])
# turn on the bfd on p1.
AT_CHECK([ovs-vsctl set interface p1 bfd:enable=true])
-for i in `seq 0 49`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 5000 100
# even though there is no data traffic, since p1 bfd is on again, should increment the flap_count.
BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["7"])
BFD_VSCTL_LIST_IFACE([p1], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"])
OVS_VSWITCHD_STOP
-AT_CLEANUP
\ No newline at end of file
+AT_CLEANUP
# advance clock to pass the fault check timeout and check cfm
# status update in OVSDB.
-for i in `seq 0 14`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 1500 100
CFM_CHECK_DB([p0], [true], [recv], [1], [], [], [up])
# remove the cfm on p0 and status should be all empty.
AT_CHECK([ovs-vsctl remove int p0 cfm_mpid 1])
-for i in `seq 0 4`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 500 100
CFM_CHECK_DB([p0], [[[]]], [], [[[]]], [], [], [[[]]])
OVS_VSWITCHD_STOP
AT_CHECK([ovs-vsctl set Interface p0 cfm_mpid=1])
# check cfm status update in OVSDB.
-for i in `seq 0 14`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 1500 100
CFM_CHECK_DB([p0], [true], [recv], [1], [], [], [up])
# turn cfm on p1 on, cfm status of p0 and p1 should all go up.
AT_CHECK([ovs-vsctl set interface p1 cfm_mpid=2])
-for i in `seq 0 14`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 1500 100
CFM_CHECK_DB([p0], [false], [], [2], [], [2], [up])
CFM_CHECK_DB([p1], [false], [], [0], [], [1], [up])
# turn cfm on p1 off, cfm status of p0 should go down again.
AT_CHECK([ovs-vsctl remove int p1 cfm_mpid 2])
-for i in `seq 0 14`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 1500 100
CFM_CHECK_DB([p0], [true], [recv], [3], [], [], [up])
OVS_VSWITCHD_STOP
ovs-appctl time/stop
# wait for a while to stablize cfm.
-for i in `seq 0 100`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 10100 100
CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [300ms], [2], [up])
CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [300ms], [1], [up])
ovs-appctl time/stop
# wait for a while to stablize cfm. (need a longer time, since in demand mode
# the fault interval is (MAX(ccm_interval_ms, 500) * 3.5) ms)
-for i in `seq 0 200`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 20100 100
CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [300ms], [2], [up])
CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [300ms], [1], [up])
# now turn on the cfm on p1 again,
AT_CHECK([ovs-vsctl set Interface p1 cfm_mpid=2])
# cfm should be up for both p0 and p1
-for i in `seq 0 200`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 20100 100
CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [300ms], [2], [up])
CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [300ms], [1], [up])
ovs-appctl time/stop
# wait for a while to stablize cfm.
-for i in `seq 0 100`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 10100 100
CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [100ms], [2], [up])
CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [100ms], [1], [up])
# turn cfm on p1 off, should increment the cfm_flap_count on p0.
AT_CHECK([ovs-vsctl remove interface p1 cfm_mpid 2])
-for i in `seq 0 10`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 1100 100
CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count : 1])
CFM_VSCTL_LIST_IFACE([p1], [cfm_flap_count], [cfm_flap_count : [[]]])
# turn cfm on p1 on again, should increment the cfm_flap_count on p0.
AT_CHECK([ovs-vsctl set interface p1 cfm_mpid=2])
-for i in `seq 0 10`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 1100 100
CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count : 2])
OVS_VSWITCHD_STOP
ovs-appctl time/stop
# wait for a while to stablize cfm.
-for i in `seq 0 100`; do ovs-appctl time/warp 100; done
+ovs-appctl time/warp 10100 100
CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [100ms], [2], [up])
CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [100ms], [1], [up])
AT_CHECK([ovs-appctl cfm/show p1 | grep 'fault_override'], [1], [ignore])
CFM_VSCTL_LIST_IFACE([p1], [cfm_fault_status], [cfm_fault_status : [[]]])
OVS_VSWITCHD_STOP
-AT_CLEANUP
\ No newline at end of file
+AT_CLEANUP