* 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. */
/* 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
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()).
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'. */
/* 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)) {
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;
}
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);
}
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) {
bool vlan_splinters_changed;
struct bridge *br;
+ int stats_interval;
ovsrec_open_vswitch_init(&null_cfg);
}
}
+ /* 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;
ovsdb_idl_txn_destroy(txn); /* XXX */
}
- iface_stats_timer = time_msec() + IFACE_STATS_INTERVAL;
+ stats_timer = time_msec() + stats_timer_interval;
}
if (!status_txn) {
/* 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) {
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) {
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);
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'. */