X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=6a4ebe58d2741155e9d679f41c92a34229019207;hb=35d25d444257d086411a4347f8142c53d5ca5d3f;hp=d0a5764d37394b8ba69578d8c80365d3c5876980;hpb=3fe8050596e3cff28c007b5d7c1ec9c461849995;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index d0a5764d..6a4ebe58 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -148,6 +148,7 @@ static void bridge_add_ofproto_ports(struct bridge *); static void bridge_del_ofproto_ports(struct bridge *); static void bridge_refresh_ofp_port(struct bridge *); static void bridge_configure_datapath_id(struct bridge *); +static void bridge_configure_flow_eviction_threshold(struct bridge *); static void bridge_configure_netflow(struct bridge *); static void bridge_configure_sflow(struct bridge *, int *sflow_bridge_number); static void bridge_configure_remotes(struct bridge *, @@ -195,7 +196,9 @@ static void iface_set_mac(struct iface *); 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 *iface); +static bool 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 *); static bool iface_is_synthetic(const struct iface *); @@ -214,6 +217,7 @@ bridge_init(const char *remote) { /* Create connection to database. */ idl = ovsdb_idl_create(remote, &ovsrec_idl_class, true); + ovsdb_idl_set_lock(idl, "ovs_vswitchd"); ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_cur_cfg); ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_statistics); @@ -409,6 +413,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) } bridge_configure_mirrors(br); bridge_configure_datapath_id(br); + bridge_configure_flow_eviction_threshold(br); bridge_configure_remotes(br, managers, n_managers); bridge_configure_netflow(br); bridge_configure_sflow(br, &sflow_bridge_number); @@ -866,6 +871,12 @@ bridge_add_ofproto_ports(struct bridge *br) iface->name, strerror(error)); } + /* Populate stats columns in new Interface rows. */ + if (iface->netdev && !iface->cfg->mtu) { + iface_refresh_stats(iface); + iface_refresh_status(iface); + } + /* Add the port, if necessary. */ if (iface->netdev && iface->ofp_port < 0) { uint16_t ofp_port; @@ -953,6 +964,22 @@ bridge_get_other_config(const struct ovsrec_bridge *br_cfg, const char *key) &ovsrec_bridge_col_other_config, key); } +/* Set Flow eviction threshold */ +static void +bridge_configure_flow_eviction_threshold(struct bridge *br) +{ + const char *threshold_str; + unsigned threshold; + + threshold_str = bridge_get_other_config(br->cfg, "flow-eviction-threshold"); + if (threshold_str) { + threshold = strtoul(threshold_str, NULL, 10); + } else { + threshold = OFPROTO_FLOW_EVICTON_THRESHOLD_DEFAULT; + } + ofproto_set_flow_eviction_threshold(br->ofproto, threshold); +} + static void bridge_pick_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN], struct iface **hw_addr_iface) @@ -1340,13 +1367,20 @@ nx_role_to_str(enum nx_role role) } static void -bridge_refresh_controller_status(const struct bridge *br) +refresh_controller_status(void) { + struct bridge *br; struct shash info; const struct ovsrec_controller *cfg; - ofproto_get_ofproto_controller_info(br->ofproto, &info); + shash_init(&info); + /* Accumulate status for controllers on all bridges. */ + HMAP_FOR_EACH (br, node, &all_bridges) { + ofproto_get_ofproto_controller_info(br->ofproto, &info); + } + + /* Update each controller in the database with current status. */ OVSREC_CONTROLLER_FOR_EACH(cfg, idl) { struct ofproto_controller_info *cinfo = shash_find_data(&info, cfg->target); @@ -1376,6 +1410,24 @@ bridge_run(void) bool database_changed; struct bridge *br; + /* (Re)configure if necessary. */ + database_changed = ovsdb_idl_run(idl); + if (ovsdb_idl_is_lock_contended(idl)) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + struct bridge *br, *next_br; + + VLOG_ERR_RL(&rl, "another ovs-vswitchd process is running, " + "disabling this process until it goes away"); + + HMAP_FOR_EACH_SAFE (br, next_br, node, &all_bridges) { + bridge_destroy(br); + } + return; + } else if (!ovsdb_idl_has_lock(idl)) { + return; + } + cfg = ovsrec_open_vswitch_first(idl); + /* Let each bridge do the work that it needs to do. */ datapath_destroyed = false; HMAP_FOR_EACH (br, node, &all_bridges) { @@ -1388,10 +1440,6 @@ bridge_run(void) } } - /* (Re)configure if necessary. */ - database_changed = ovsdb_idl_run(idl); - cfg = ovsrec_open_vswitch_first(idl); - /* Re-configure SSL. We do this on every trip through the main loop, * instead of just when the database changes, because the contents of the * key and certificate files can change without the database changing. @@ -1440,9 +1488,9 @@ bridge_run(void) iface_refresh_status(iface); } } - bridge_refresh_controller_status(br); } refresh_system_stats(cfg); + refresh_controller_status(); ovsdb_idl_txn_commit(txn); ovsdb_idl_txn_destroy(txn); /* XXX */ } @@ -1480,16 +1528,18 @@ bridge_run(void) void bridge_wait(void) { - struct bridge *br; - - HMAP_FOR_EACH (br, node, &all_bridges) { - ofproto_wait(br->ofproto); - } ovsdb_idl_wait(idl); - poll_timer_wait_until(stats_timer); + if (!hmap_is_empty(&all_bridges)) { + struct bridge *br; + + HMAP_FOR_EACH (br, node, &all_bridges) { + ofproto_wait(br->ofproto); + } + poll_timer_wait_until(stats_timer); - if (db_limiter > time_msec()) { - poll_timer_wait_until(db_limiter); + if (db_limiter > time_msec()) { + poll_timer_wait_until(db_limiter); + } } } @@ -2459,6 +2509,7 @@ iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos) } else { struct iface_delete_queues_cbdata cbdata; struct shash details; + bool queue_zero; size_t i; /* Configure top-level Qos for 'iface'. */ @@ -2474,16 +2525,28 @@ iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos) netdev_dump_queues(iface->netdev, iface_delete_queues, &cbdata); /* Configure queues for 'iface'. */ + queue_zero = false; for (i = 0; i < qos->n_queues; i++) { const struct ovsrec_queue *queue = qos->value_queues[i]; unsigned int queue_id = qos->key_queues[i]; + if (queue_id == 0) { + queue_zero = true; + } + shash_from_ovs_idl_map(queue->key_other_config, queue->value_other_config, queue->n_other_config, &details); netdev_set_queue(iface->netdev, queue_id, &details); shash_destroy(&details); } + if (!queue_zero) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + VLOG_WARN_RL(&rl, "interface %s: QoS configured without a default " + "queue (queue 0). Packets not directed to a " + "correctly configured queue may be dropped.", + iface->name); + } } netdev_set_policing(iface->netdev, @@ -2703,7 +2766,6 @@ mirror_configure(struct mirror *m, const struct ovsrec_mirror *cfg) &s.srcs, &s.n_srcs); mirror_collect_ports(m, cfg->select_dst_port, cfg->n_select_dst_port, &s.dsts, &s.n_dsts); - } /* Get VLAN selection. */