[ovs-dev] [cfm_v2 7/9] cfm: Allow accurate transmission intervals in extended mode.
Ethan Jackson
ethan at nicira.com
Fri Sep 9 01:59:51 UTC 2011
The standard CFM protocol only allows a handful of transmission
rates. This is particularly problematic if you want to support a
transmission rate slower than 100 ms and faster than 1000 ms.
This patch allows arbitrary transmission rates (between 1 ms and
65535 ms). It does this by commandeering parts of a reserved
"zero" field in the ccm message. This breaks wire compatibility
with standard 802.1ag implementations, and thus is only supported
in extended mode.
Bug #7014.
---
lib/cfm.c | 41 +++++++++++++++++++++++++++++++----------
vswitchd/vswitch.xml | 5 ++++-
2 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/lib/cfm.c b/lib/cfm.c
index d526a05..94079b6 100644
--- a/lib/cfm.c
+++ b/lib/cfm.c
@@ -61,7 +61,10 @@ struct ccm {
ovs_be32 seq;
ovs_be16 mpid;
uint8_t maid[CCM_MAID_LEN];
- uint8_t zero[16]; /* Defined by ITU-T Y.1731 should be zero */
+
+ /* Defined by ITU-T Y.1731 should be zero */
+ ovs_be16 interval_ms_x; /* Transmission interval in ms. */
+ uint8_t zero[14];
} __attribute__((packed));
BUILD_ASSERT_DECL(CCM_LEN == sizeof(struct ccm));
@@ -312,6 +315,11 @@ cfm_compose_ccm(struct cfm *cfm, struct ofpbuf *packet,
memcpy(ccm->maid, cfm->maid, sizeof ccm->maid);
memset(ccm->zero, 0, sizeof ccm->zero);
+ if (cfm->ccm_interval == 0) {
+ assert(cfm->extended);
+ ccm->interval_ms_x = htons(cfm->ccm_interval_ms);
+ }
+
if (hmap_is_empty(&cfm->remote_mps)) {
ccm->flags |= CCM_RDI_MASK;
}
@@ -330,6 +338,7 @@ bool
cfm_configure(struct cfm *cfm, const struct cfm_settings *s)
{
uint8_t interval;
+ int interval_ms;
if (!cfm_is_valid_mpid(s->mpid) || s->interval <= 0) {
return false;
@@ -338,10 +347,16 @@ cfm_configure(struct cfm *cfm, const struct cfm_settings *s)
cfm->mpid = s->mpid;
cfm->extended = s->extended;
interval = ms_to_ccm_interval(s->interval);
+ interval_ms = ccm_interval_to_ms(interval);
+
+ if (cfm->extended && interval_ms != s->interval) {
+ interval = 0;
+ interval_ms = MIN(s->interval, UINT16_MAX);
+ }
- if (interval != cfm->ccm_interval) {
+ if (interval != cfm->ccm_interval || interval_ms != cfm->ccm_interval_ms) {
cfm->ccm_interval = interval;
- cfm->ccm_interval_ms = ccm_interval_to_ms(interval);
+ cfm->ccm_interval_ms = interval_ms;
timer_set_expired(&cfm->tx_timer);
timer_set_duration(&cfm->fault_timer, cfm_fault_interval(cfm));
@@ -367,10 +382,6 @@ void
cfm_process_heartbeat(struct cfm *cfm, const struct ofpbuf *p)
{
struct ccm *ccm;
- bool ccm_rdi;
- uint16_t ccm_mpid;
- uint8_t ccm_interval;
- struct remote_mp *rmp;
struct eth_header *eth;
eth = p->l2;
@@ -402,9 +413,12 @@ cfm_process_heartbeat(struct cfm *cfm, const struct ofpbuf *p)
VLOG_WARN_RL(&rl, "%s: Received unexpected remote MAID from MAC "
ETH_ADDR_FMT, cfm->name, ETH_ADDR_ARGS(eth->eth_src));
} else {
- ccm_mpid = ntohs(ccm->mpid);
- ccm_interval = ccm->flags & 0x7;
- ccm_rdi = ccm->flags & CCM_RDI_MASK;
+ uint16_t ccm_mpid = ntohs(ccm->mpid);
+ uint8_t ccm_interval = ccm->flags & 0x7;
+ bool ccm_rdi = ccm->flags & CCM_RDI_MASK;
+ uint16_t ccm_interval_ms_x = ntohs(ccm->interval_ms_x);
+
+ struct remote_mp *rmp;
if (ccm_interval != cfm->ccm_interval) {
VLOG_WARN_RL(&rl, "%s: received a CCM with an invalid interval"
@@ -412,6 +426,13 @@ cfm_process_heartbeat(struct cfm *cfm, const struct ofpbuf *p)
ccm_interval, ccm_mpid);
}
+ if (cfm->extended && ccm_interval == 0
+ && ccm_interval_ms_x != cfm->ccm_interval_ms) {
+ VLOG_WARN_RL(&rl, "%s: received a CCM with an invalid extended"
+ " interval (%"PRIu16"ms) from RMP %"PRIu16, cfm->name,
+ ccm_interval_ms_x, ccm_mpid);
+ }
+
rmp = lookup_remote_mp(cfm, ccm_mpid);
if (rmp) {
rmp->recv = true;
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index e3953b4..eebf8e4 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -1418,7 +1418,10 @@
<dd> When true, the CFM module operates in extended mode. This causes
it to use a nonstandard destination address to avoid conflicting
with compliant implementations which may be running concurrently on
- the network. Defaults to false. </dd>
+ the network. Furthermore, extended mode increases the accuracy of
+ the <code>cfm_interval</code> configuration parameter by breaking
+ wire compatibility with 802.1ag compliant implementations.
+ Defaults to false.</dd>
<dt><code>bond-stable-id</code></dt>
<dd> A positive integer using in <code>stable</code> bond mode to
make slave selection decisions. Allocating
--
1.7.6.1
More information about the dev
mailing list