From 9ac3fce4d5aea7e963439eb97f7c2d157aef4dfc Mon Sep 17 00:00:00 2001 From: Ethan Jackson Date: Fri, 13 May 2011 16:53:24 -0700 Subject: [PATCH] cfm: Migrate cfm/show unixctl command to CFM module. This patch moves the cfm/show unixctl show command from the bridge to the CFM module. This is more in line with how LACP does it, and will make future patches easier to implement. --- lib/cfm.c | 64 +++++++++++++++++++++++++++++++++--------- lib/cfm.h | 9 +++--- ofproto/ofproto-dpif.c | 1 + vswitchd/bridge.c | 31 ++------------------ 4 files changed, 58 insertions(+), 47 deletions(-) diff --git a/lib/cfm.c b/lib/cfm.c index a605c098..ff416a35 100644 --- a/lib/cfm.c +++ b/lib/cfm.c @@ -30,6 +30,7 @@ #include "poll-loop.h" #include "timer.h" #include "timeval.h" +#include "unixctl.h" #include "vlog.h" VLOG_DEFINE_THIS_MODULE(cfm); @@ -38,8 +39,9 @@ VLOG_DEFINE_THIS_MODULE(cfm); struct cfm_internal { struct cfm cfm; - uint32_t seq; /* The sequence number of our last CCM. */ + struct list list_node; /* Node in all_cfms list. */ + 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. */ @@ -48,6 +50,10 @@ struct cfm_internal { }; static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); +static struct list all_cfms = LIST_INITIALIZER(&all_cfms); + +static void cfm_unixctl_show(struct unixctl_conn *, const char *args, + void *aux); static int ccm_interval_to_ms(uint8_t interval) @@ -128,6 +134,12 @@ lookup_remote_mp(const struct hmap *hmap, uint16_t mpid) return NULL; } +void +cfm_init(void) +{ + unixctl_command_register("cfm/show", cfm_unixctl_show, NULL); +} + /* Allocates a 'cfm' object. This object should have its 'mpid', 'maid', * 'eth_src', and 'interval' filled out. cfm_configure() should be called * whenever changes are made to 'cfm', and before cfm_run() is called for the @@ -142,6 +154,7 @@ cfm_create(void) cfm = &cfmi->cfm; hmap_init(&cfm->remote_mps); + list_push_back(&all_cfms, &cfmi->list_node); return cfm; } @@ -161,6 +174,7 @@ cfm_destroy(struct cfm *cfm) } hmap_destroy(&cfm->remote_mps); + list_remove(&cfmi->list_node); free(cfmi); } @@ -411,26 +425,50 @@ cfm_process_heartbeat(struct cfm *cfm, const struct ofpbuf *p) } } -void -cfm_dump_ds(const struct cfm *cfm, struct ds *ds) +static struct cfm_internal * +cfm_find(const char *name) { - const struct cfm_internal *cfmi = cfm_to_internal(cfm); + struct cfm_internal *cfmi; + + LIST_FOR_EACH (cfmi, list_node, &all_cfms) { + if (cfmi->cfm.name && !strcmp(cfmi->cfm.name, name)) { + return cfmi; + } + } + return NULL; +} + +static void +cfm_unixctl_show(struct unixctl_conn *conn, + const char *args, void *aux OVS_UNUSED) +{ + struct ds ds = DS_EMPTY_INITIALIZER; + const struct cfm_internal *cfmi; struct remote_mp *rmp; - ds_put_format(ds, "MPID %"PRIu16": %s\n", cfm->mpid, - cfm->fault ? "fault" : ""); + cfmi = cfm_find(args); + if (!cfmi) { + unixctl_command_reply(conn, 501, "no such CFM object"); + return; + } - ds_put_format(ds, "\tinterval: %dms\n", cfmi->ccm_interval_ms); - ds_put_format(ds, "\tnext CCM tx: %lldms\n", + ds_put_format(&ds, "MPID %"PRIu16": %s\n", cfmi->cfm.mpid, + cfmi->cfm.fault ? "fault" : ""); + + ds_put_format(&ds, "\tinterval: %dms\n", cfmi->ccm_interval_ms); + ds_put_format(&ds, "\tnext CCM tx: %lldms\n", timer_msecs_until_expired(&cfmi->tx_timer)); - ds_put_format(ds, "\tnext fault check: %lldms\n", + ds_put_format(&ds, "\tnext fault check: %lldms\n", timer_msecs_until_expired(&cfmi->fault_timer)); - ds_put_cstr(ds, "\n"); - HMAP_FOR_EACH (rmp, node, &cfm->remote_mps) { - ds_put_format(ds, "Remote MPID %"PRIu16": %s\n", rmp->mpid, + ds_put_cstr(&ds, "\n"); + HMAP_FOR_EACH (rmp, node, &cfmi->cfm.remote_mps) { + ds_put_format(&ds, "Remote MPID %"PRIu16": %s\n", rmp->mpid, rmp->fault ? "fault" : ""); - ds_put_format(ds, "\trecv since check: %s", + ds_put_format(&ds, "\trecv since check: %s", rmp->recv ? "true" : "false"); } + + unixctl_command_reply(conn, 200, ds_cstr(&ds)); + ds_destroy(&ds); } diff --git a/lib/cfm.h b/lib/cfm.h index 4bb8dc93..c83a7cce 100644 --- a/lib/cfm.h +++ b/lib/cfm.h @@ -1,5 +1,4 @@ -/* - * Copyright (c) 2010 Nicira Networks. +/* Copyright (c) 2010, 2011 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +23,6 @@ struct flow; struct ofpbuf; -struct ds; /* Ethernet destination address of CCM packets. */ static const uint8_t eth_addr_ccm[6] OVS_UNUSED @@ -57,6 +55,7 @@ struct cfm { uint16_t mpid; /* The MPID of this CFM. */ uint8_t maid[CCM_MAID_LEN]; /* The MAID of this CFM. */ int interval; /* The requested transmission interval. */ + const char *name; /* Name of this CFM object. */ /* Statistics. */ struct hmap remote_mps; /* Expected remote MPs. */ @@ -73,6 +72,8 @@ struct remote_mp { bool fault; /* Indicates a connectivity fault. */ }; +void cfm_init(void); + struct cfm *cfm_create(void); void cfm_destroy(struct cfm *); @@ -98,6 +99,4 @@ bool cfm_should_process_flow(const struct flow *); void cfm_process_heartbeat(struct cfm *, const struct ofpbuf *packet); -void cfm_dump_ds(const struct cfm *, struct ds *); - #endif /* cfm.h */ diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index d3cb92b9..5807c564 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -750,6 +750,7 @@ set_cfm(struct ofport *ofport_, const struct cfm *cfm, ofport->cfm->mpid = cfm->mpid; ofport->cfm->interval = cfm->interval; + ofport->cfm->name = cfm->name; memcpy(ofport->cfm->maid, cfm->maid, CCM_MAID_LEN); cfm_update_remote_mps(ofport->cfm, remote_mps, n_remote_mps); diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index ec4bb7be..aba0b942 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -164,7 +164,6 @@ static bool bridge_has_bond_fake_iface(const struct bridge *, const char *name); static bool port_is_bond_fake_iface(const struct port *); -static unixctl_cb_func cfm_unixctl_show; static unixctl_cb_func qos_unixctl_show; static struct port *port_create(struct bridge *, const struct ovsrec_port *); @@ -268,7 +267,6 @@ bridge_init(const char *remote) ovsdb_idl_omit(idl, &ovsrec_ssl_col_external_ids); /* Register unixctl commands. */ - unixctl_command_register("cfm/show", cfm_unixctl_show, NULL); unixctl_command_register("qos/show", qos_unixctl_show, NULL); unixctl_command_register("bridge/dump-flows", bridge_unixctl_dump_flows, NULL); @@ -276,6 +274,7 @@ bridge_init(const char *remote) NULL); lacp_init(); bond_init(); + cfm_init(); } void @@ -1501,33 +1500,6 @@ bridge_wait(void) } } -/* CFM unixctl user interface functions. */ -static void -cfm_unixctl_show(struct unixctl_conn *conn, - const char *args, void *aux OVS_UNUSED) -{ - struct ds ds = DS_EMPTY_INITIALIZER; - struct iface *iface; - const struct cfm *cfm; - - iface = iface_find(args); - if (!iface) { - unixctl_command_reply(conn, 501, "no such interface"); - return; - } - - cfm = ofproto_port_get_cfm(iface->port->bridge->ofproto, iface->ofp_port); - - if (!cfm) { - unixctl_command_reply(conn, 501, "CFM not enabled"); - return; - } - - cfm_dump_ds(cfm, &ds); - unixctl_command_reply(conn, 200, ds_cstr(&ds)); - ds_destroy(&ds); -} - /* QoS unixctl user interface functions. */ struct qos_unixctl_show_cbdata { @@ -2549,6 +2521,7 @@ iface_configure_cfm(struct iface *iface) cfm.mpid = mon->mpid; cfm.interval = mon->interval ? *mon->interval : 1000; + cfm.name = iface->name; memcpy(cfm.maid, maid, sizeof cfm.maid); -- 2.30.2