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 *);
ovsdb_idl_omit_alert(idl, &ovsrec_controller_col_status);
ovsdb_idl_omit(idl, &ovsrec_controller_col_external_ids);
- ovsdb_idl_omit_alert(idl, &ovsrec_maintenance_point_col_fault);
-
- ovsdb_idl_omit_alert(idl, &ovsrec_monitor_col_fault);
-
ovsdb_idl_omit(idl, &ovsrec_qos_col_external_ids);
ovsdb_idl_omit(idl, &ovsrec_queue_col_external_ids);
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);
NULL);
lacp_init();
bond_init();
+ cfm_init();
}
void
port_configure(port);
- HMAP_FOR_EACH (iface, ofp_port_node, &br->ifaces) {
+ LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
iface_configure_cfm(iface);
iface_configure_qos(iface, port->cfg->qos);
iface_set_mac(iface);
} else {
s.bond = NULL;
s.bond_stable_ids = NULL;
+
+ LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
+ netdev_set_miimon_interval(iface->netdev, 0);
+ }
}
/* Register. */
ofproto_bundle_register(port->bridge->ofproto, port, &s);
/* Clean up. */
+ free(s.slaves);
free(s.trunks);
free(s.lacp_slaves);
free(s.bond_stable_ids);
assert(iface->ofp_port < 0 && ofp_port >= 0);
iface->ofp_port = ofp_port;
hmap_insert(&br->ifaces, &iface->ofp_port_node, hash_int(ofp_port, 0));
-
+ iface_set_ofport(iface->cfg, ofp_port);
}
static void
/* Already exists, nothing to do. */
ofproto_port_destroy(&ofproto_port);
}
- ofproto_port_destroy(&ofproto_port);
}
}
}
static bool
iface_refresh_cfm_stats(struct iface *iface)
{
- const struct ovsrec_monitor *mon;
- const struct cfm *cfm;
+ const struct ovsrec_interface *cfg = iface->cfg;
bool changed = false;
- size_t i;
+ int fault;
- mon = iface->cfg->monitor;
- cfm = ofproto_port_get_cfm(iface->port->bridge->ofproto, iface->ofp_port);
+ fault = ofproto_port_get_cfm_fault(iface->port->bridge->ofproto,
+ iface->ofp_port);
- if (!cfm || !mon) {
+ if (fault < 0) {
return false;
}
- for (i = 0; i < mon->n_remote_mps; i++) {
- const struct ovsrec_maintenance_point *mp;
- const struct remote_mp *rmp;
-
- mp = mon->remote_mps[i];
- rmp = cfm_get_remote_mp(cfm, mp->mpid);
-
- if (mp->n_fault != 1 || mp->fault[0] != rmp->fault) {
- ovsrec_maintenance_point_set_fault(mp, &rmp->fault, 1);
- changed = true;
- }
- }
-
- if (mon->n_fault != 1 || mon->fault[0] != cfm->fault) {
- ovsrec_monitor_set_fault(mon, &cfm->fault, 1);
+ if (cfg->n_cfm_fault != 1 || cfg->cfm_fault[0] != fault) {
+ bool fault_bool = fault;
+ ovsrec_interface_set_cfm_fault(cfg, &fault_bool, 1);
changed = true;
}
static void
iface_refresh_stats(struct iface *iface)
{
- struct iface_stat {
- char *name;
- int offset;
- };
- static const struct iface_stat iface_stats[] = {
- { "rx_packets", offsetof(struct netdev_stats, rx_packets) },
- { "tx_packets", offsetof(struct netdev_stats, tx_packets) },
- { "rx_bytes", offsetof(struct netdev_stats, rx_bytes) },
- { "tx_bytes", offsetof(struct netdev_stats, tx_bytes) },
- { "rx_dropped", offsetof(struct netdev_stats, rx_dropped) },
- { "tx_dropped", offsetof(struct netdev_stats, tx_dropped) },
- { "rx_errors", offsetof(struct netdev_stats, rx_errors) },
- { "tx_errors", offsetof(struct netdev_stats, tx_errors) },
- { "rx_frame_err", offsetof(struct netdev_stats, rx_frame_errors) },
- { "rx_over_err", offsetof(struct netdev_stats, rx_over_errors) },
- { "rx_crc_err", offsetof(struct netdev_stats, rx_crc_errors) },
- { "collisions", offsetof(struct netdev_stats, collisions) },
- };
- enum { N_STATS = ARRAY_SIZE(iface_stats) };
- const struct iface_stat *s;
-
- char *keys[N_STATS];
- int64_t values[N_STATS];
- int n;
+#define IFACE_STATS \
+ IFACE_STAT(rx_packets, "rx_packets") \
+ IFACE_STAT(tx_packets, "tx_packets") \
+ IFACE_STAT(rx_bytes, "rx_bytes") \
+ IFACE_STAT(tx_bytes, "tx_bytes") \
+ IFACE_STAT(rx_dropped, "rx_dropped") \
+ IFACE_STAT(tx_dropped, "tx_dropped") \
+ IFACE_STAT(rx_errors, "rx_errors") \
+ IFACE_STAT(tx_errors, "tx_errors") \
+ IFACE_STAT(rx_frame_errors, "rx_frame_err") \
+ IFACE_STAT(rx_over_errors, "rx_over_err") \
+ IFACE_STAT(rx_crc_errors, "rx_crc_err") \
+ IFACE_STAT(collisions, "collisions")
+
+#define IFACE_STAT(MEMBER, NAME) NAME,
+ static char *keys[] = { IFACE_STATS };
+#undef IFACE_STAT
+ int64_t values[ARRAY_SIZE(keys)];
+ int i;
struct netdev_stats stats;
* all-1s, and we will deal with that correctly below. */
netdev_get_stats(iface->netdev, &stats);
- n = 0;
- for (s = iface_stats; s < &iface_stats[N_STATS]; s++) {
- uint64_t value = *(uint64_t *) (((char *) &stats) + s->offset);
- if (value != UINT64_MAX) {
- keys[n] = s->name;
- values[n] = value;
- n++;
- }
- }
+ /* Copy statistics into values[] array. */
+ i = 0;
+#define IFACE_STAT(MEMBER, NAME) values[i++] = stats.MEMBER;
+ IFACE_STATS;
+#undef IFACE_STAT
+ assert(i == ARRAY_SIZE(keys));
- ovsrec_interface_set_statistics(iface->cfg, keys, values, n);
+ ovsrec_interface_set_statistics(iface->cfg, keys, values, ARRAY_SIZE(keys));
+#undef IFACE_STATS
}
static void
}
}
\f
-/* 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);
-}
-\f
/* QoS unixctl user interface functions. */
struct qos_unixctl_show_cbdata {
br->name = xstrdup(br_cfg->name);
br->type = xstrdup(ofproto_normalize_type(br_cfg->datapath_type));
br->cfg = br_cfg;
- eth_addr_nicira_random(br->default_ea);
+
+ /* Derive the default Ethernet address from the bridge's UUID. This should
+ * be unique and it will be stable between ovs-vswitchd runs. */
+ memcpy(br->default_ea, &br_cfg->header_.uuid, ETH_ADDR_LEN);
+ eth_addr_mark_random(br->default_ea);
hmap_init(&br->ports);
hmap_init(&br->ifaces);
{
const char *detect_s;
struct iface *iface;
+ int miimon_interval;
size_t i;
s->name = port->name;
bond_mode_to_string(s->balance));
}
- s->detect = BLSM_CARRIER;
- detect_s = get_port_other_config(port->cfg, "bond-detect-mode", NULL);
- if (detect_s && !bond_detect_mode_from_string(&s->detect, detect_s)) {
- VLOG_WARN("port %s: unsupported bond-detect-mode %s, "
- "defaulting to %s",
- port->name, detect_s, bond_detect_mode_to_string(s->detect));
+ miimon_interval = atoi(get_port_other_config(port->cfg,
+ "bond-miimon-interval", "0"));
+ if (miimon_interval <= 0) {
+ miimon_interval = 200;
}
- s->miimon_interval = atoi(
- get_port_other_config(port->cfg, "bond-miimon-interval", "200"));
- if (s->miimon_interval < 100) {
- s->miimon_interval = 100;
+ detect_s = get_port_other_config(port->cfg, "bond-detect-mode", "carrier");
+ if (!strcmp(detect_s, "carrier")) {
+ miimon_interval = 0;
+ } else if (strcmp(detect_s, "miimon")) {
+ VLOG_WARN("port %s: unsupported bond-detect-mode %s, "
+ "defaulting to carrier", port->name, detect_s);
+ miimon_interval = 0;
}
s->up_delay = MAX(0, port->cfg->bond_updelay);
stable_id = iface->ofp_port;
}
bond_stable_ids[i++] = stable_id;
+
+ netdev_set_miimon_interval(iface->netdev, miimon_interval);
}
}
\f
static void
iface_configure_cfm(struct iface *iface)
{
- size_t i;
- struct cfm cfm;
- uint16_t *remote_mps;
- struct ovsrec_monitor *mon;
- uint8_t maid[CCM_MAID_LEN];
+ const struct ovsrec_interface *cfg = iface->cfg;
+ struct cfm_settings s;
+ uint16_t remote_mpid;
- mon = iface->cfg->monitor;
-
- if (!mon) {
+ if (!cfg->n_cfm_mpid || !cfg->n_cfm_remote_mpid) {
ofproto_port_clear_cfm(iface->port->bridge->ofproto, iface->ofp_port);
return;
}
- if (!cfm_generate_maid(mon->md_name, mon->ma_name, maid)) {
- VLOG_WARN("interface %s: Failed to generate MAID.", iface->name);
- return;
- }
-
- cfm.mpid = mon->mpid;
- cfm.interval = mon->interval ? *mon->interval : 1000;
-
- memcpy(cfm.maid, maid, sizeof cfm.maid);
+ s.mpid = *cfg->cfm_mpid;
+ remote_mpid = *cfg->cfm_remote_mpid;
+ s.remote_mpids = &remote_mpid;
+ s.n_remote_mpids = 1;
- remote_mps = xzalloc(mon->n_remote_mps * sizeof *remote_mps);
- for(i = 0; i < mon->n_remote_mps; i++) {
- remote_mps[i] = mon->remote_mps[i]->mpid;
+ s.interval = atoi(get_interface_other_config(iface->cfg, "cfm_interval",
+ "0"));
+ if (s.interval <= 0) {
+ s.interval = 1000;
}
- ofproto_port_set_cfm(iface->port->bridge->ofproto, iface->ofp_port,
- &cfm, remote_mps, mon->n_remote_mps);
- free(remote_mps);
+ ofproto_port_set_cfm(iface->port->bridge->ofproto, iface->ofp_port, &s);
}
/* Read carrier or miimon status directly from 'iface''s netdev, according to