bool rdi; /* Remote Defect Indicator. Indicates remote_mp isn't
receiving CCMs that it's expecting to. */
bool opup; /* Operational State. */
+ uint32_t seq; /* Most recently received sequence number. */
};
-static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
+static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(20, 30);
static struct hmap all_cfms = HMAP_INITIALIZER(&all_cfms);
-static void cfm_unixctl_show(struct unixctl_conn *, const char *args,
- void *aux);
+static unixctl_cb_func cfm_unixctl_show;
static const uint8_t *
cfm_ccm_addr(const struct cfm *cfm)
void
cfm_init(void)
{
- unixctl_command_register("cfm/show", "[interface]", cfm_unixctl_show,
+ unixctl_command_register("cfm/show", "[interface]", 0, 1, cfm_unixctl_show,
NULL);
}
if (timer_expired(&cfm->fault_timer)) {
long long int interval = cfm_fault_interval(cfm);
struct remote_mp *rmp, *rmp_next;
+ bool old_cfm_fault = cfm->fault;
cfm->fault = cfm->unexpected_recv;
cfm->unexpected_recv = false;
cfm->fault = true;
}
+ if (old_cfm_fault != cfm->fault) {
+ VLOG_INFO_RL(&rl, "%s: CFM fault status changed to %s",
+ cfm->name, cfm->fault ? "true" : "false");
+ }
+
timer_set_duration(&cfm->fault_timer, interval);
}
}
struct remote_mp *rmp;
uint64_t ccm_mpid;
+ uint32_t ccm_seq;
bool ccm_opdown;
if (cfm->extended) {
ccm_mpid = ntohs(ccm->mpid);
ccm_opdown = false;
}
+ ccm_seq = ntohl(ccm->seq);
if (ccm_interval != cfm->ccm_interval) {
VLOG_WARN_RL(&rl, "%s: received a CCM with an invalid interval"
rmp = lookup_remote_mp(cfm, ccm_mpid);
if (!rmp) {
if (hmap_count(&cfm->remote_mps) < CFM_MAX_RMPS) {
- rmp = xmalloc(sizeof *rmp);
+ rmp = xzalloc(sizeof *rmp);
hmap_insert(&cfm->remote_mps, &rmp->node, hash_mpid(ccm_mpid));
} else {
cfm->unexpected_recv = true;
}
}
+ VLOG_DBG("%s: received CCM (seq %"PRIu32") (mpid %"PRIu64")"
+ " (interval %"PRIu8") (RDI %s)", cfm->name, ccm_seq,
+ ccm_mpid, ccm_interval, ccm_rdi ? "true" : "false");
+
if (rmp) {
+ if (rmp->seq && ccm_seq != (rmp->seq + 1)) {
+ VLOG_WARN_RL(&rl, "%s: (mpid %"PRIu64") detected sequence"
+ " numbers which indicate possible connectivity"
+ " problems (previous %"PRIu32") (current %"PRIu32
+ ")", cfm->name, ccm_mpid, rmp->seq, ccm_seq);
+ }
+
rmp->mpid = ccm_mpid;
rmp->recv = true;
+ rmp->seq = ccm_seq;
rmp->rdi = ccm_rdi;
rmp->opup = !ccm_opdown;
}
-
- VLOG_DBG("%s: received CCM (seq %"PRIu32") (mpid %"PRIu64")"
- " (interval %"PRIu8") (RDI %s)", cfm->name, ntohl(ccm->seq),
- ccm_mpid, ccm_interval, ccm_rdi ? "true" : "false");
}
}
}
static void
-cfm_unixctl_show(struct unixctl_conn *conn,
- const char *args, void *aux OVS_UNUSED)
+cfm_unixctl_show(struct unixctl_conn *conn, int argc, const char *argv[],
+ void *aux OVS_UNUSED)
{
struct ds ds = DS_EMPTY_INITIALIZER;
const struct cfm *cfm;
- if (strlen(args)) {
- cfm = cfm_find(args);
+ if (argc > 1) {
+ cfm = cfm_find(argv[1]);
if (!cfm) {
unixctl_command_reply(conn, 501, "no such CFM object");
return;