X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=6c271fb7acf80807d733d2b859b827537ff46a02;hb=c84d769c147830be5aa99ed3e6bdc92af15abd5d;hp=952049e4166eeb33c451b3f37879264bfdbf4122;hpb=e5ae7df8c7f44cb2d6f42daaab1d3c26c7a88ae3;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 952049e4..6c271fb7 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -57,6 +57,7 @@ #include "socket-util.h" #include "stream-ssl.h" #include "svec.h" +#include "system-stats.h" #include "timeval.h" #include "util.h" #include "unixctl.h" @@ -188,10 +189,10 @@ static struct list all_bridges = LIST_INITIALIZER(&all_bridges); /* OVSDB IDL used to obtain configuration. */ static struct ovsdb_idl *idl; -/* Each time this timer expires, the bridge fetches statistics for every - * interface and pushes them into the database. */ -#define IFACE_STATS_INTERVAL (5 * 1000) /* In milliseconds. */ -static long long int iface_stats_timer = LLONG_MIN; +/* Each time this timer expires, the bridge fetches systems and interface + * statistics and pushes them into the database. */ +#define STATS_INTERVAL (5 * 1000) /* In milliseconds. */ +static long long int stats_timer = LLONG_MIN; static struct bridge *bridge_create(const struct ovsrec_bridge *br_cfg); static void bridge_destroy(struct bridge *); @@ -244,7 +245,7 @@ static void mirror_reconfigure(struct bridge *); static void mirror_reconfigure_one(struct mirror *, struct ovsrec_mirror *); static bool vlan_is_mirrored(const struct mirror *, int vlan); -static struct iface *iface_create(struct port *port, +static struct iface *iface_create(struct port *port, const struct ovsrec_interface *if_cfg); static void iface_destroy(struct iface *); static struct iface *iface_lookup(const struct bridge *, const char *name); @@ -306,7 +307,7 @@ bridge_configure_once(const struct ovsrec_open_vswitch *cfg) } already_configured_once = true; - iface_stats_timer = time_msec() + IFACE_STATS_INTERVAL; + stats_timer = time_msec() + STATS_INTERVAL; /* Get all the configured bridges' names from 'cfg' into 'bridge_names'. */ svec_init(&bridge_names); @@ -373,6 +374,20 @@ set_up_iface(const struct ovsrec_interface *iface_cfg, struct iface *iface, xstrdup(iface_cfg->value_options[i])); } + /* Include 'other_config' keys in hash of netdev options. The + * namespace of 'other_config' and 'options' must be disjoint. + * Prefer 'options' keys over 'other_config' keys. */ + for (i = 0; i < iface_cfg->n_other_config; i++) { + char *value = xstrdup(iface_cfg->value_other_config[i]); + if (!shash_add_once(&options, iface_cfg->key_other_config[i], + value)) { + VLOG_WARN("%s: \"other_config\" key %s conflicts with existing " + "\"other_config\" or \"options\" entry...ignoring", + iface_cfg->name, iface_cfg->key_other_config[i]); + free(value); + } + } + if (create) { struct netdev_options netdev_options; @@ -632,7 +647,6 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) struct odp_port *dpif_ports; size_t n_dpif_ports; struct shash cur_ifaces, want_ifaces; - struct shash_node *node; /* Get the set of interfaces currently in this datapath. */ dpif_port_list(br->dpif, &dpif_ports, &n_dpif_ports); @@ -752,7 +766,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) opts.collectors.n = nf_cfg->n_targets; opts.collectors.names = nf_cfg->targets; if (ofproto_set_netflow(br->ofproto, &opts)) { - VLOG_ERR("bridge %s: problem setting netflow collectors", + VLOG_ERR("bridge %s: problem setting netflow collectors", br->name); } } else { @@ -765,7 +779,6 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) struct ovsrec_controller **controllers; struct ofproto_sflow_options oso; size_t n_controllers; - size_t i; memset(&oso, 0, sizeof oso); @@ -1098,6 +1111,20 @@ iface_refresh_stats(struct iface *iface) ovsrec_interface_set_statistics(iface->cfg, keys, values, n); } +static void +refresh_system_stats(const struct ovsrec_open_vswitch *cfg) +{ + struct ovsdb_datum datum; + struct shash stats; + + shash_init(&stats); + get_system_stats(&stats); + + ovsdb_datum_from_shash(&datum, &stats); + ovsdb_idl_txn_write(&cfg->header_, &ovsrec_open_vswitch_col_statistics, + &datum); +} + void bridge_run(void) { @@ -1153,28 +1180,31 @@ bridge_run(void) } #endif - /* Refresh interface stats if necessary. */ - if (time_msec() >= iface_stats_timer) { - struct ovsdb_idl_txn *txn; + /* Refresh system and interface stats if necessary. */ + if (time_msec() >= stats_timer) { + if (cfg) { + struct ovsdb_idl_txn *txn; - txn = ovsdb_idl_txn_create(idl); - LIST_FOR_EACH (br, struct bridge, node, &all_bridges) { - size_t i; + txn = ovsdb_idl_txn_create(idl); + LIST_FOR_EACH (br, struct bridge, node, &all_bridges) { + size_t i; - for (i = 0; i < br->n_ports; i++) { - struct port *port = br->ports[i]; - size_t j; + for (i = 0; i < br->n_ports; i++) { + struct port *port = br->ports[i]; + size_t j; - for (j = 0; j < port->n_ifaces; j++) { - struct iface *iface = port->ifaces[j]; - iface_refresh_stats(iface); + for (j = 0; j < port->n_ifaces; j++) { + struct iface *iface = port->ifaces[j]; + iface_refresh_stats(iface); + } } } + refresh_system_stats(cfg); + ovsdb_idl_txn_commit(txn); + ovsdb_idl_txn_destroy(txn); /* XXX */ } - ovsdb_idl_txn_commit(txn); - ovsdb_idl_txn_destroy(txn); /* XXX */ - iface_stats_timer = time_msec() + IFACE_STATS_INTERVAL; + stats_timer = time_msec() + STATS_INTERVAL; } } @@ -1193,7 +1223,7 @@ bridge_wait(void) bond_wait(br); } ovsdb_idl_wait(idl); - poll_timer_wait_until(iface_stats_timer); + poll_timer_wait_until(stats_timer); } /* Forces 'br' to revalidate all of its flows. This is appropriate when 'br''s @@ -1350,7 +1380,7 @@ bridge_unixctl_dump_flows(struct unixctl_conn *conn, { struct bridge *br; struct ds results; - + br = bridge_lookup(args); if (!br) { unixctl_command_reply(conn, 501, "Unknown bridge"); @@ -2361,7 +2391,7 @@ is_admissible(struct bridge *br, const flow_t *flow, bool have_packet, static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); VLOG_WARN_RL(&rl, "bridge %s: received packet on unknown " - "interface %"PRIu16, br->name, flow->in_port); + "interface %"PRIu16, br->name, flow->in_port); } *in_portp = NULL; @@ -2822,7 +2852,6 @@ bond_rebalance_port(struct port *port) * smallest hashes instead of the biggest ones. There is little * reason behind this decision; we could use the opposite sort * order to shift away big hashes ahead of small ones. */ - size_t i; bool order_swapped; for (i = 0; i < from->n_hashes; i++) { @@ -3407,7 +3436,6 @@ port_reconfigure(struct port *port, const struct ovsrec_port *cfg) trunks = NULL; if (vlan < 0 && cfg->n_trunks) { size_t n_errors; - size_t i; trunks = bitmap_allocate(4096); n_errors = 0; @@ -3570,15 +3598,15 @@ port_update_bond_compat(struct port *port) /* We need to make the same determination as the Linux bonding * code to determine whether a slave should be consider "up". - * The Linux function bond_miimon_inspect() supports four + * The Linux function bond_miimon_inspect() supports four * BOND_LINK_* states: - * + * * - BOND_LINK_UP: carrier detected, updelay has passed. * - BOND_LINK_FAIL: carrier lost, downdelay in progress. * - BOND_LINK_DOWN: carrier lost, downdelay has passed. * - BOND_LINK_BACK: carrier detected, updelay in progress. * - * The function bond_info_show_slave() only considers BOND_LINK_UP + * The function bond_info_show_slave() only considers BOND_LINK_UP * to be "up" and anything else to be "down". */ slave->up = iface->enabled && iface->delay_expires == LLONG_MAX;