static void iface_set_ofport(const struct ovsrec_interface *, int64_t ofport);
static void iface_configure_qos(struct iface *, const struct ovsrec_qos *);
static void iface_configure_cfm(struct iface *);
-static bool iface_refresh_cfm_stats(struct iface *);
+static void iface_refresh_cfm_stats(struct iface *);
static void iface_refresh_stats(struct iface *);
static void iface_refresh_status(struct iface *);
static bool iface_get_carrier(const struct iface *);
ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_statistics);
ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_status);
ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_fault);
+ ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_remote_mpids);
ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_lacp_current);
ovsdb_idl_omit(idl, &ovsrec_interface_col_external_ids);
!eth_addr_is_local(iface_ea) &&
!eth_addr_is_reserved(iface_ea) &&
!eth_addr_is_zero(iface_ea) &&
- eth_addr_compare_3way(iface_ea, ea) < 0)
+ (!found_addr || eth_addr_compare_3way(iface_ea, ea) < 0))
{
memcpy(ea, iface_ea, ETH_ADDR_LEN);
*hw_addr_iface = iface;
iface_get_carrier(iface) ? "up" : "down");
error = netdev_get_mtu(iface->netdev, &mtu);
- if (!error && mtu != INT_MAX) {
+ if (!error) {
mtu_64 = mtu;
ovsrec_interface_set_mtu(iface->cfg, &mtu_64, 1);
}
/* Writes 'iface''s CFM statistics to the database. Returns true if anything
* changed, false otherwise. */
-static bool
+static void
iface_refresh_cfm_stats(struct iface *iface)
{
const struct ovsrec_interface *cfg = iface->cfg;
- bool changed = false;
- int fault;
+ int fault, error;
+ const uint64_t *rmps;
+ size_t n_rmps;
fault = ofproto_port_get_cfm_fault(iface->port->bridge->ofproto,
iface->ofp_port);
-
- if (fault < 0) {
- return false;
- }
-
- if (cfg->n_cfm_fault != 1 || cfg->cfm_fault[0] != fault) {
+ if (fault >= 0) {
bool fault_bool = fault;
ovsrec_interface_set_cfm_fault(cfg, &fault_bool, 1);
- changed = true;
+ } else {
+ ovsrec_interface_set_cfm_fault(cfg, NULL, 0);
}
- return changed;
+ error = ofproto_port_get_cfm_remote_mpids(iface->port->bridge->ofproto,
+ iface->ofp_port, &rmps, &n_rmps);
+ if (error >= 0) {
+ ovsrec_interface_set_cfm_remote_mpids(cfg, (const int64_t *)rmps,
+ n_rmps);
+ } else {
+ ovsrec_interface_set_cfm_remote_mpids(cfg, NULL, 0);
+ }
}
static bool
ofproto_free_ofproto_controller_info(&info);
}
+static void
+refresh_cfm_stats(void)
+{
+ static struct ovsdb_idl_txn *txn = NULL;
+
+ if (!txn) {
+ struct bridge *br;
+
+ txn = ovsdb_idl_txn_create(idl);
+
+ HMAP_FOR_EACH (br, node, &all_bridges) {
+ struct iface *iface;
+
+ HMAP_FOR_EACH (iface, name_node, &br->iface_by_name) {
+ iface_refresh_cfm_stats(iface);
+ }
+ }
+ }
+
+ if (ovsdb_idl_txn_commit(txn) != TXN_INCOMPLETE) {
+ ovsdb_idl_txn_destroy(txn);
+ txn = NULL;
+ }
+}
+
void
bridge_run(void)
{
struct iface *iface;
LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
- changed = iface_refresh_cfm_stats(iface) || changed;
+ /* XXX: Eventually we need to remove the lacp_current flag
+ * from the database so that we can completely get rid of
+ * this rate limiter code. */
changed = iface_refresh_lacp_stats(iface) || changed;
}
}
ovsdb_idl_txn_commit(txn);
ovsdb_idl_txn_destroy(txn);
}
+
+ refresh_cfm_stats();
}
void
iface_configure_cfm(struct iface *iface)
{
const struct ovsrec_interface *cfg = iface->cfg;
+ const char *extended_str;
struct cfm_settings s;
- uint16_t remote_mpid;
- if (!cfg->n_cfm_mpid || !cfg->n_cfm_remote_mpid) {
+ if (!cfg->n_cfm_mpid) {
ofproto_port_clear_cfm(iface->port->bridge->ofproto, iface->ofp_port);
return;
}
s.mpid = *cfg->cfm_mpid;
- remote_mpid = *cfg->cfm_remote_mpid;
- s.remote_mpids = &remote_mpid;
- s.n_remote_mpids = 1;
-
s.interval = atoi(get_interface_other_config(iface->cfg, "cfm_interval",
"0"));
if (s.interval <= 0) {
s.interval = 1000;
}
+ extended_str = get_interface_other_config(iface->cfg, "cfm_extended",
+ "false");
+ s.extended = !strcasecmp("true", extended_str);
+
ofproto_port_set_cfm(iface->port->bridge->ofproto, iface->ofp_port, &s);
}