X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=fed5d71d3741280391230a3467a7dfa02bac97a3;hb=6586adf524275726f0482b219b50920a30f80570;hp=bcaf1d12d44d7a307820a6462044447bb874977d;hpb=bbb1951c485766b82b365b7f25ec917867b2ecf4;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index bcaf1d12..fed5d71d 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -238,6 +238,11 @@ static struct ovsdb_idl *idl; #define STATS_INTERVAL (5 * 1000) /* In milliseconds. */ static long long int stats_timer = LLONG_MIN; +/* Stores the time after which CFM statistics may be written to the database. + * Only updated when changes to the database require rate limiting. */ +#define CFM_LIMIT_INTERVAL (1 * 1000) /* In milliseconds. */ +static long long int cfm_limiter = LLONG_MIN; + static struct bridge *bridge_create(const struct ovsrec_bridge *br_cfg); static void bridge_destroy(struct bridge *); static struct bridge *bridge_lookup(const char *name); @@ -302,7 +307,7 @@ static void iface_set_mac(struct iface *); static void iface_set_ofport(const struct ovsrec_interface *, int64_t ofport); static void iface_update_qos(struct iface *, const struct ovsrec_qos *); static void iface_update_cfm(struct iface *); -static void iface_refresh_cfm_stats(struct iface *iface); +static bool iface_refresh_cfm_stats(struct iface *iface); static void iface_update_carrier(struct iface *); static bool iface_get_carrier(const struct iface *); @@ -1196,18 +1201,21 @@ iface_refresh_status(struct iface *iface) } } -static void +/* Writes 'iface''s CFM statistics to the database. Returns true if anything + * changed, false otherwise. */ +static bool iface_refresh_cfm_stats(struct iface *iface) { const struct ovsrec_monitor *mon; const struct cfm *cfm; + bool changed = false; size_t i; mon = iface->cfg->monitor; cfm = ofproto_iface_get_cfm(iface->port->bridge->ofproto, iface->dp_ifidx); if (!cfm || !mon) { - return; + return false; } for (i = 0; i < mon->n_remote_mps; i++) { @@ -1217,59 +1225,18 @@ iface_refresh_cfm_stats(struct iface *iface) mp = mon->remote_mps[i]; rmp = cfm_get_remote_mp(cfm, mp->mpid); - ovsrec_maintenance_point_set_fault(mp, &rmp->fault, 1); - } - - if (hmap_is_empty(&cfm->x_remote_mps)) { - ovsrec_monitor_set_unexpected_remote_mpids(mon, NULL, 0); - } else { - size_t length; - struct remote_mp *rmp; - int64_t *x_remote_mps; - - length = hmap_count(&cfm->x_remote_mps); - x_remote_mps = xzalloc(length * sizeof *x_remote_mps); - - i = 0; - HMAP_FOR_EACH (rmp, node, &cfm->x_remote_mps) { - x_remote_mps[i++] = rmp->mpid; + if (mp->n_fault != 1 || mp->fault[0] != rmp->fault) { + ovsrec_maintenance_point_set_fault(mp, &rmp->fault, 1); + changed = true; } - - ovsrec_monitor_set_unexpected_remote_mpids(mon, x_remote_mps, length); - free(x_remote_mps); } - if (hmap_is_empty(&cfm->x_remote_maids)) { - ovsrec_monitor_set_unexpected_remote_maids(mon, NULL, 0); - } else { - size_t length; - char **x_remote_maids; - struct remote_maid *rmaid; - - length = hmap_count(&cfm->x_remote_maids); - x_remote_maids = xzalloc(length * sizeof *x_remote_maids); - - i = 0; - HMAP_FOR_EACH (rmaid, node, &cfm->x_remote_maids) { - size_t j; - - x_remote_maids[i] = xzalloc(CCM_MAID_LEN * 2 + 1); - - for (j = 0; j < CCM_MAID_LEN; j++) { - snprintf(&x_remote_maids[i][j * 2], 3, "%02hhx", - rmaid->maid[j]); - } - i++; - } - ovsrec_monitor_set_unexpected_remote_maids(mon, x_remote_maids, length); - - for (i = 0; i < length; i++) { - free(x_remote_maids[i]); - } - free(x_remote_maids); + if (mon->n_fault != 1 || mon->fault[0] != cfm->fault) { + ovsrec_monitor_set_fault(mon, &cfm->fault, 1); + changed = true; } - ovsrec_monitor_set_fault(mon, &cfm->fault, 1); + return changed; } static void @@ -1447,7 +1414,6 @@ bridge_run(void) LIST_FOR_EACH (iface, port_elem, &port->ifaces) { iface_refresh_stats(iface); - iface_refresh_cfm_stats(iface); iface_refresh_status(iface); } } @@ -1460,6 +1426,31 @@ bridge_run(void) stats_timer = time_msec() + STATS_INTERVAL; } + + if (time_msec() >= cfm_limiter) { + struct ovsdb_idl_txn *txn; + bool changed = false; + + txn = ovsdb_idl_txn_create(idl); + LIST_FOR_EACH (br, node, &all_bridges) { + struct port *port; + + HMAP_FOR_EACH (port, hmap_node, &br->ports) { + struct iface *iface; + + LIST_FOR_EACH (iface, port_elem, &port->ifaces) { + changed = iface_refresh_cfm_stats(iface) || changed; + } + } + } + + if (changed) { + cfm_limiter = time_msec() + CFM_LIMIT_INTERVAL; + } + + ovsdb_idl_txn_commit(txn); + ovsdb_idl_txn_destroy(txn); + } } void @@ -1483,6 +1474,10 @@ bridge_wait(void) } ovsdb_idl_wait(idl); poll_timer_wait_until(stats_timer); + + if (cfm_limiter > time_msec()) { + poll_timer_wait_until(cfm_limiter); + } } /* Forces 'br' to revalidate all of its flows. This is appropriate when 'br''s @@ -3811,9 +3806,12 @@ lacp_send_pdu_cb(void *aux, const struct lacp_pdu *pdu) error = netdev_get_etheraddr(iface->netdev, ea); if (!error) { struct ofpbuf packet; + struct lacp_pdu *packet_pdu; - ofpbuf_init(&packet, ETH_HEADER_LEN + LACP_PDU_LEN); - compose_lacp_packet(&packet, ea, pdu); + ofpbuf_init(&packet, 0); + packet_pdu = compose_packet(&packet, eth_addr_lacp, ea, ETH_TYPE_LACP, + sizeof *packet_pdu); + memcpy(packet_pdu, pdu, sizeof *packet_pdu); ofproto_send_packet(iface->port->bridge->ofproto, iface->dp_ifidx, 0, &packet); ofpbuf_uninit(&packet); @@ -4582,7 +4580,7 @@ iface_update_cfm(struct iface *iface) struct cfm cfm; uint16_t *remote_mps; struct ovsrec_monitor *mon; - uint8_t ea[ETH_ADDR_LEN], maid[CCM_MAID_LEN]; + uint8_t maid[CCM_MAID_LEN]; mon = iface->cfg->monitor; @@ -4591,12 +4589,6 @@ iface_update_cfm(struct iface *iface) return; } - if (netdev_get_etheraddr(iface->netdev, ea)) { - VLOG_WARN("interface %s: Failed to get ethernet address. " - "Skipping Monitor.", iface->name); - return; - } - if (!cfm_generate_maid(mon->md_name, mon->ma_name, maid)) { VLOG_WARN("interface %s: Failed to generate MAID.", iface->name); return; @@ -4605,7 +4597,6 @@ iface_update_cfm(struct iface *iface) cfm.mpid = mon->mpid; cfm.interval = mon->interval ? *mon->interval : 1000; - memcpy(cfm.eth_src, ea, sizeof cfm.eth_src); memcpy(cfm.maid, maid, sizeof cfm.maid); remote_mps = xzalloc(mon->n_remote_mps * sizeof *remote_mps);