ovs-parse-leaks: Fix typos in manpage.
[sliver-openvswitch.git] / vswitchd / bridge.c
index 3a9cfa9..fcd7a78 100644 (file)
@@ -195,7 +195,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 *);
 
@@ -866,6 +868,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;
@@ -1291,6 +1299,23 @@ iface_refresh_stats(struct iface *iface)
 #undef IFACE_STATS
 }
 
+static bool
+enable_system_stats(const struct ovsrec_open_vswitch *cfg)
+{
+    const char *enable;
+
+    /* Use other-config:enable-system-stats by preference. */
+    enable = get_ovsrec_key_value(&cfg->header_,
+                                  &ovsrec_open_vswitch_col_other_config,
+                                  "enable-statistics");
+    if (enable) {
+        return !strcmp(enable, "true");
+    }
+
+    /* Disable by default. */
+    return false;
+}
+
 static void
 refresh_system_stats(const struct ovsrec_open_vswitch *cfg)
 {
@@ -1298,7 +1323,9 @@ refresh_system_stats(const struct ovsrec_open_vswitch *cfg)
     struct shash stats;
 
     shash_init(&stats);
-    get_system_stats(&stats);
+    if (enable_system_stats(cfg)) {
+        get_system_stats(&stats);
+    }
 
     ovsdb_datum_from_shash(&datum, &stats);
     ovsdb_idl_txn_write(&cfg->header_, &ovsrec_open_vswitch_col_statistics,
@@ -1321,13 +1348,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);
@@ -1421,9 +1455,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 */
         }
@@ -2440,6 +2474,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'. */
@@ -2455,16 +2490,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,