datapath: Simplify flow mask cache delete.
[cascardo/ovs.git] / vswitchd / bridge.c
index 84e9ab8..5dcd3ba 100644 (file)
@@ -172,9 +172,15 @@ static uint64_t connectivity_seqno = LLONG_MIN;
  * we check the return status of each update transaction and do not start new
  * update if the previous transaction status is 'TXN_INCOMPLETE'.
  *
- * 'statux_txn' is NULL if there is no ongoing status update.
+ * 'status_txn' is NULL if there is no ongoing status update.
+ *
+ * If the previous database transaction was incomplete or failed (is not
+ * 'TXN_SUCCESS' or 'TXN_UNCHANGED'), 'force_status_commit' is set to true.
+ * This means that 'status_txn' must be committed next iteration of bridge_run()
+ * even if the connectivity or netdev sequence numbers do not change.
  */
 static struct ovsdb_idl_txn *status_txn;
+static bool force_status_commit = true;
 
 /* When the status update transaction returns 'TXN_INCOMPLETE', should register a
  * timeout in 'STATUS_CHECK_AGAIN_MSEC' to check again. */
@@ -182,13 +188,8 @@ static struct ovsdb_idl_txn *status_txn;
 
 /* Each time this timer expires, the bridge fetches interface and mirror
  * statistics and pushes them into the database. */
-#define IFACE_STATS_INTERVAL (5 * 1000) /* In milliseconds. */
-static long long int iface_stats_timer = LLONG_MIN;
-
-/* Set to true to allow experimental use of OpenFlow 1.4.
- * This is false initially because OpenFlow 1.4 is not yet safe to use: it can
- * abort due to unimplemented features. */
-static bool allow_of14;
+static int stats_timer_interval;
+static long long int stats_timer = LLONG_MIN;
 
 /* In some datapaths, creating and destroying OpenFlow ports can be extremely
  * expensive.  This can cause bridge_reconfigure() to take a long time during
@@ -452,14 +453,6 @@ bridge_exit(void)
     ovsdb_idl_destroy(idl);
 }
 
-/* Enables use of OpenFlow 1.4.  This is off by default because OpenFlow 1.4 is
- * not yet safe to use: it can abort due to unimplemented features. */
-void
-bridge_enable_of14(void)
-{
-    allow_of14 = true;
-}
-
 /* Looks at the list of managers in 'ovs_cfg' and extracts their remote IP
  * addresses and ports into '*managersp' and '*n_managersp'.  The caller is
  * responsible for freeing '*managersp' (with free()).
@@ -626,13 +619,6 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
         bridge_configure_stp(br);
         bridge_configure_tables(br);
         bridge_configure_dp_desc(br);
-
-        if (smap_get(&br->cfg->other_config, "flow-eviction-threshold")) {
-            /* XXX: Remove this warning message eventually. */
-            VLOG_WARN_ONCE("As of June 2013, flow-eviction-threshold has been"
-                           " moved to the Open_vSwitch table.  Ignoring its"
-                           " setting in the bridge table.");
-        }
     }
     free(managers);
 
@@ -990,17 +976,11 @@ bridge_configure_datapath_id(struct bridge *br)
 static uint32_t
 bridge_get_allowed_versions(struct bridge *br)
 {
-    uint32_t allowed_versions;
-
     if (!br->cfg->n_protocols)
         return 0;
 
-    allowed_versions = ofputil_versions_from_strings(br->cfg->protocols,
-                                                     br->cfg->n_protocols);
-    if (!allow_of14) {
-        allowed_versions &= ~(1u << OFP14_VERSION);
-    }
-    return allowed_versions;
+    return ofputil_versions_from_strings(br->cfg->protocols,
+                                         br->cfg->n_protocols);
 }
 
 /* Set NetFlow configuration on 'br'. */
@@ -1567,7 +1547,6 @@ iface_create(struct bridge *br, const struct ovsrec_interface *iface_cfg,
 
     /* Populate initial status in database. */
     iface_refresh_stats(iface);
-    iface_refresh_netdev_status(iface);
 
     /* Add bond fake iface if necessary. */
     if (port_is_bond_fake_iface(port)) {
@@ -1840,7 +1819,8 @@ iface_refresh_netdev_status(struct iface *iface)
         return;
     }
 
-    if (iface->change_seq == netdev_get_change_seq(iface->netdev)) {
+    if (iface->change_seq == netdev_get_change_seq(iface->netdev)
+        && !force_status_commit) {
         return;
     }
 
@@ -1933,7 +1913,8 @@ iface_refresh_ofproto_status(struct iface *iface)
 
     smap_init(&smap);
     error = ofproto_port_get_bfd_status(iface->port->bridge->ofproto,
-                                        iface->ofp_port, &smap);
+                                        iface->ofp_port, force_status_commit,
+                                        &smap);
     if (error >= 0) {
         ovsrec_interface_set_bfd_status(iface->cfg, &smap);
     }
@@ -1950,7 +1931,8 @@ iface_refresh_cfm_stats(struct iface *iface)
     int error;
 
     error = ofproto_port_get_cfm_status(iface->port->bridge->ofproto,
-                                        iface->ofp_port, &status);
+                                        iface->ofp_port, force_status_commit,
+                                        &status);
     if (error < 0) {
         /* Do nothing if there is no status change since last update. */
     } else if (error > 0) {
@@ -2282,6 +2264,7 @@ bridge_run(void)
 
     bool vlan_splinters_changed;
     struct bridge *br;
+    int stats_interval;
 
     ovsrec_open_vswitch_init(&null_cfg);
 
@@ -2387,8 +2370,22 @@ bridge_run(void)
         }
     }
 
+    /* Statistics update interval should always be greater than or equal to
+     * 5000 ms. */
+    if (cfg) {
+        stats_interval = MAX(smap_get_int(&cfg->other_config,
+                                          "stats-update-interval",
+                                          5000), 5000);
+    } else {
+        stats_interval = 5000;
+    }
+    if (stats_timer_interval != stats_interval) {
+        stats_timer_interval = stats_interval;
+        stats_timer = LLONG_MIN;
+    }
+
     /* Refresh interface and mirror stats if necessary. */
-    if (time_msec() >= iface_stats_timer) {
+    if (time_msec() >= stats_timer) {
         if (cfg) {
             struct ovsdb_idl_txn *txn;
 
@@ -2417,7 +2414,7 @@ bridge_run(void)
             ovsdb_idl_txn_destroy(txn); /* XXX */
         }
 
-        iface_stats_timer = time_msec() + IFACE_STATS_INTERVAL;
+        stats_timer = time_msec() + stats_timer_interval;
     }
 
     if (!status_txn) {
@@ -2425,7 +2422,7 @@ bridge_run(void)
 
         /* Check the need to update status. */
         seq = seq_read(connectivity_seq_get());
-        if (seq != connectivity_seqno) {
+        if (seq != connectivity_seqno || force_status_commit) {
             connectivity_seqno = seq;
             status_txn = ovsdb_idl_txn_create(idl);
             HMAP_FOR_EACH (br, node, &all_bridges) {
@@ -2449,6 +2446,17 @@ bridge_run(void)
         enum ovsdb_idl_txn_status status;
 
         status = ovsdb_idl_txn_commit(status_txn);
+
+        /* If the transaction is incomplete or fails, 'status_txn'
+         * needs to be committed next iteration of bridge_run() even if
+         * connectivity or netdev sequence numbers do not change. */
+        if (status == TXN_SUCCESS || status == TXN_UNCHANGED)
+        {
+            force_status_commit = false;
+        } else {
+            force_status_commit = true;
+        }
+
         /* Do not destroy "status_txn" if the transaction is
          * "TXN_INCOMPLETE". */
         if (status != TXN_INCOMPLETE) {
@@ -2484,14 +2492,15 @@ bridge_wait(void)
         HMAP_FOR_EACH (br, node, &all_bridges) {
             ofproto_wait(br->ofproto);
         }
-        poll_timer_wait_until(iface_stats_timer);
+
+        poll_timer_wait_until(stats_timer);
     }
 
-    /* If the status database transaction is 'TXN_INCOMPLETE' in this run,
-     * register a timeout in 'STATUS_CHECK_AGAIN_MSEC'.  Else, wait on the
-     * global connectivity sequence number.  Note, this also helps batch
-     * multiple status changes into one transaction. */
-    if (status_txn) {
+    /* If the status database transaction is 'TXN_INCOMPLETE' or is
+     * unsuccessful, register a timeout in 'STATUS_CHECK_AGAIN_MSEC'.  Else,
+     * wait on the global connectivity sequence number.  Note, this also helps
+     * batch multiple status changes into one transaction. */
+    if (force_status_commit) {
         poll_timer_wait_until(time_msec() + STATUS_CHECK_AGAIN_MSEC);
     } else {
         seq_wait(connectivity_seq_get(), connectivity_seqno);
@@ -2845,6 +2854,7 @@ bridge_ofproto_controller_for_mgmt(const struct bridge *br,
     oc->rate_limit = 0;
     oc->burst_limit = 0;
     oc->enable_async_msgs = true;
+    oc->dscp = 0;
 }
 
 /* Converts ovsrec_controller 'c' into an ofproto_controller in 'oc'.  */