From d7243b93628450098fd7ed2d3b5cdc355e6bdc15 Mon Sep 17 00:00:00 2001 From: Ethan Jackson Date: Thu, 26 Jan 2012 18:58:51 -0800 Subject: [PATCH] cfm: Allow manual override of CFM fault status. This can be useful when testing. Suggested-by: Reid Price Signed-off-by: Ethan Jackson --- lib/cfm.c | 50 ++++++++++++++++++++++++++++++++++++-- vswitchd/ovs-vswitchd.8.in | 4 +++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/lib/cfm.c b/lib/cfm.c index 1e05853d..d62d4e20 100644 --- a/lib/cfm.c +++ b/lib/cfm.c @@ -90,6 +90,9 @@ struct cfm { bool opup; /* Operational State. */ bool remote_opup; /* Remote Operational State. */ + int fault_override; /* Manual override of 'fault' status. + Ignored if negative. */ + uint32_t seq; /* The sequence number of our last CCM. */ uint8_t ccm_interval; /* The CCM transmission interval. */ int ccm_interval_ms; /* 'ccm_interval' in milliseconds. */ @@ -124,6 +127,7 @@ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(20, 30); static struct hmap all_cfms = HMAP_INITIALIZER(&all_cfms); static unixctl_cb_func cfm_unixctl_show; +static unixctl_cb_func cfm_unixctl_set_fault; static const uint8_t * cfm_ccm_addr(const struct cfm *cfm) @@ -235,6 +239,8 @@ cfm_init(void) { unixctl_command_register("cfm/show", "[interface]", 0, 1, cfm_unixctl_show, NULL); + unixctl_command_register("cfm/set-fault", "[interface] normal|false|true", + 1, 2, cfm_unixctl_set_fault, NULL); } /* Allocates a 'cfm' object called 'name'. 'cfm' should be initialized by @@ -250,6 +256,7 @@ cfm_create(const char *name) cfm_generate_maid(cfm); hmap_insert(&all_cfms, &cfm->hmap_node, hash_string(cfm->name, 0)); cfm->remote_opup = true; + cfm->fault_override = -1; return cfm; } @@ -546,6 +553,9 @@ cfm_process_heartbeat(struct cfm *cfm, const struct ofpbuf *p) bool cfm_get_fault(const struct cfm *cfm) { + if (cfm->fault_override >= 0) { + return cfm->fault_override; + } return cfm->fault; } @@ -589,9 +599,10 @@ cfm_print_details(struct ds *ds, const struct cfm *cfm) struct remote_mp *rmp; ds_put_format(ds, "---- %s ----\n", cfm->name); - ds_put_format(ds, "MPID %"PRIu64":%s%s%s\n", cfm->mpid, + ds_put_format(ds, "MPID %"PRIu64":%s%s%s%s\n", cfm->mpid, cfm->extended ? " extended" : "", - cfm->fault ? " fault" : "", + cfm_get_fault(cfm) ? " fault" : "", + cfm->fault_override >= 0 ? " fault_override" : "", cfm->unexpected_recv ? " unexpected_recv" : ""); ds_put_format(ds, "\topstate: %s\n", cfm->opup ? "up" : "down"); @@ -636,3 +647,38 @@ cfm_unixctl_show(struct unixctl_conn *conn, int argc, const char *argv[], unixctl_command_reply(conn, 200, ds_cstr(&ds)); ds_destroy(&ds); } + +static void +cfm_unixctl_set_fault(struct unixctl_conn *conn, int argc, const char *argv[], + void *aux OVS_UNUSED) +{ + const char *fault_str = argv[argc - 1]; + int fault_override; + struct cfm *cfm; + + if (!strcasecmp("true", fault_str)) { + fault_override = 1; + } else if (!strcasecmp("false", fault_str)) { + fault_override = 0; + } else if (!strcasecmp("normal", fault_str)) { + fault_override = -1; + } else { + unixctl_command_reply(conn, 501, "unknown fault string"); + return; + } + + if (argc > 2) { + cfm = cfm_find(argv[1]); + if (!cfm) { + unixctl_command_reply(conn, 501, "no such CFM object"); + return; + } + cfm->fault_override = fault_override; + } else { + HMAP_FOR_EACH (cfm, hmap_node, &all_cfms) { + cfm->fault_override = fault_override; + } + } + + unixctl_command_reply(conn, 200, "OK"); +} diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in index 01dfcdfe..1abae6f8 100644 --- a/vswitchd/ovs-vswitchd.8.in +++ b/vswitchd/ovs-vswitchd.8.in @@ -118,6 +118,10 @@ Displays detailed information about Connectivity Fault Management configured on \fIinterface\fR. If \fIinterface\fR is not specified, then displays detailed information about all interfaces with CFM enabled. +.IP "\fBcfm/set-fault\fR [\fIinterface\fR] \fIstatus\fR" +Force the fault status of the CFM module on \fIinterface\fR (or all +interfaces if none is given) to be \fIstatus\fR. \fIstatus\fR can be +"true", "false", or "normal" which reverts to the standard behavior. .IP "\fBstp/tcn\fR [\fIbridge\fR]" Forces a topology change event on \fIbridge\fR if it's running STP. This may cause it to send Topology Change Notifications to its peers and flush -- 2.30.2