cfm: Add ovsdb column "cfm_flap_count".
[sliver-openvswitch.git] / vswitchd / bridge.c
index 686eb93..fecae60 100644 (file)
@@ -18,6 +18,7 @@
 #include <errno.h>
 #include <inttypes.h>
 #include <stdlib.h>
+#include "async-append.h"
 #include "bfd.h"
 #include "bitmap.h"
 #include "bond.h"
@@ -375,6 +376,7 @@ bridge_init(const char *remote)
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_fault);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_fault_status);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_remote_mpids);
+    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_flap_count);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_health);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_remote_opstate);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_bfd_status);
@@ -472,10 +474,9 @@ collect_in_band_managers(const struct ovsrec_open_vswitch *ovs_cfg,
         SSET_FOR_EACH (target, &targets) {
             struct sockaddr_in *sin = &managers[n_managers];
 
-            if (stream_parse_target_with_default_ports(target,
-                                                       JSONRPC_TCP_PORT,
-                                                       JSONRPC_SSL_PORT,
-                                                       sin)) {
+            if (stream_parse_target_with_default_port(target,
+                                                      OVSDB_OLD_PORT,
+                                                      sin)) {
                 n_managers++;
             }
         }
@@ -501,6 +502,9 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
         smap_get_int(&ovs_cfg->other_config, "flow-eviction-threshold",
                      OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT));
 
+    ofproto_set_n_handler_threads(
+        smap_get_int(&ovs_cfg->other_config, "n-handler-threads", 0));
+
     bridge_configure_flow_miss_model(smap_get(&ovs_cfg->other_config,
                                               "force-miss-model"));
 
@@ -544,7 +548,6 @@ bridge_reconfigure_ofp(void)
     long long int deadline;
     struct bridge *br;
 
-    time_refresh();
     deadline = time_msec() + OFP_PORT_ACTION_WINDOW;
 
     /* The kernel will reject any attempt to add a given port to a datapath if
@@ -563,7 +566,6 @@ bridge_reconfigure_ofp(void)
             list_remove(&garbage->list_node);
             free(garbage);
 
-            time_refresh();
             if (time_msec() >= deadline) {
                 return false;
             }
@@ -576,7 +578,6 @@ bridge_reconfigure_ofp(void)
 
         HMAP_FOR_EACH_SAFE (if_cfg, next, hmap_node, &br->if_cfg_todo) {
             iface_create(br, if_cfg, OFPP_NONE);
-            time_refresh();
             if (time_msec() >= deadline) {
                 return false;
             }
@@ -1021,6 +1022,12 @@ bridge_configure_ipfix(struct bridge *br)
         if (be_cfg->obs_point_id) {
             be_opts.obs_point_id = *be_cfg->obs_point_id;
         }
+        if (be_cfg->cache_active_timeout) {
+            be_opts.cache_active_timeout = *be_cfg->cache_active_timeout;
+        }
+        if (be_cfg->cache_max_flows) {
+            be_opts.cache_max_flows = *be_cfg->cache_max_flows;
+        }
     }
 
     if (n_fe_opts > 0) {
@@ -1033,6 +1040,10 @@ bridge_configure_ipfix(struct bridge *br)
                 sset_init(&opts->targets);
                 sset_add_array(&opts->targets, fe_cfg->ipfix->targets,
                                fe_cfg->ipfix->n_targets);
+                opts->cache_active_timeout = fe_cfg->ipfix->cache_active_timeout
+                    ? *fe_cfg->ipfix->cache_active_timeout : 0;
+                opts->cache_max_flows = fe_cfg->ipfix->cache_max_flows
+                    ? *fe_cfg->ipfix->cache_max_flows : 0;
                 opts++;
             }
         }
@@ -1880,11 +1891,13 @@ iface_refresh_cfm_stats(struct iface *iface)
         ovsrec_interface_set_cfm_fault(cfg, NULL, 0);
         ovsrec_interface_set_cfm_fault_status(cfg, NULL, 0);
         ovsrec_interface_set_cfm_remote_opstate(cfg, NULL);
+        ovsrec_interface_set_cfm_flap_count(cfg, NULL, 0);
         ovsrec_interface_set_cfm_health(cfg, NULL, 0);
         ovsrec_interface_set_cfm_remote_mpids(cfg, NULL, 0);
     } else {
         const char *reasons[CFM_FAULT_N_REASONS];
         int64_t cfm_health = status.health;
+        int64_t cfm_flap_count = status.flap_count;
         bool faulted = status.faults != 0;
         size_t i, j;
 
@@ -1899,6 +1912,8 @@ iface_refresh_cfm_stats(struct iface *iface)
         }
         ovsrec_interface_set_cfm_fault_status(cfg, (char **) reasons, j);
 
+        ovsrec_interface_set_cfm_flap_count(cfg, &cfm_flap_count, 1);
+
         if (status.remote_opstate >= 0) {
             const char *remote_opstate = status.remote_opstate ? "up" : "down";
             ovsrec_interface_set_cfm_remote_opstate(cfg, remote_opstate);
@@ -1914,6 +1929,8 @@ iface_refresh_cfm_stats(struct iface *iface)
         } else {
             ovsrec_interface_set_cfm_health(cfg, NULL, 0);
         }
+
+        free(status.rmps);
     }
 }
 
@@ -2246,11 +2263,10 @@ instant_stats_run(void)
                 iface_refresh_cfm_stats(iface);
 
                 smap_init(&smap);
-                if (!ofproto_port_get_bfd_status(br->ofproto, iface->ofp_port,
-                                                 &smap)) {
-                    ovsrec_interface_set_bfd_status(iface->cfg, &smap);
-                    smap_destroy(&smap);
-                }
+                ofproto_port_get_bfd_status(br->ofproto, iface->ofp_port,
+                                            &smap);
+                ovsrec_interface_set_bfd_status(iface->cfg, &smap);
+                smap_destroy(&smap);
             }
         }
     }
@@ -2444,6 +2460,8 @@ bridge_run(void)
              * process that forked us to exit successfully. */
             daemonize_complete();
 
+            vlog_enable_async();
+
             VLOG_INFO_ONCE("%s (Open vSwitch) %s", program_name, VERSION);
         }
     }
@@ -2539,13 +2557,11 @@ struct qos_unixctl_show_cbdata {
 };
 
 static void
-qos_unixctl_show_cb(unsigned int queue_id,
-                    const struct smap *details,
-                    void *aux)
+qos_unixctl_show_queue(unsigned int queue_id,
+                       const struct smap *details,
+                       struct iface *iface,
+                       struct ds *ds)
 {
-    struct qos_unixctl_show_cbdata *data = aux;
-    struct ds *ds = data->ds;
-    struct iface *iface = data->iface;
     struct netdev_queue_stats stats;
     struct smap_node *node;
     int error;
@@ -2589,8 +2605,6 @@ qos_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
     struct iface *iface;
     const char *type;
     struct smap_node *node;
-    struct qos_unixctl_show_cbdata data;
-    int error;
 
     iface = iface_find(argv[1]);
     if (!iface) {
@@ -2601,20 +2615,22 @@ qos_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
     netdev_get_qos(iface->netdev, &type, &smap);
 
     if (*type != '\0') {
+        struct netdev_queue_dump dump;
+        struct smap details;
+        unsigned int queue_id;
+
         ds_put_format(&ds, "QoS: %s %s\n", iface->name, type);
 
         SMAP_FOR_EACH (node, &smap) {
             ds_put_format(&ds, "%s: %s\n", node->key, node->value);
         }
 
-        data.ds = &ds;
-        data.iface = iface;
-        error = netdev_dump_queues(iface->netdev, qos_unixctl_show_cb, &data);
-
-        if (error) {
-            ds_put_format(&ds, "failed to dump queues: %s",
-                          ovs_strerror(error));
+        smap_init(&details);
+        NETDEV_QUEUE_FOR_EACH (&queue_id, &details, &dump, iface->netdev) {
+            qos_unixctl_show_queue(queue_id, &details, iface, &ds);
         }
+        smap_destroy(&details);
+
         unixctl_command_reply(conn, ds_cstr(&ds));
     } else {
         ds_put_format(&ds, "QoS not configured on %s\n", iface->name);
@@ -3587,11 +3603,6 @@ iface_clear_db_record(const struct ovsrec_interface *if_cfg)
     }
 }
 
-struct iface_delete_queues_cbdata {
-    struct netdev *netdev;
-    const struct ovsdb_datum *queues;
-};
-
 static bool
 queue_ids_include(const struct ovsdb_datum *queues, int64_t target)
 {
@@ -3601,17 +3612,6 @@ queue_ids_include(const struct ovsdb_datum *queues, int64_t target)
     return ovsdb_datum_find_key(queues, &atom, OVSDB_TYPE_INTEGER) != UINT_MAX;
 }
 
-static void
-iface_delete_queues(unsigned int queue_id,
-                    const struct smap *details OVS_UNUSED, void *cbdata_)
-{
-    struct iface_delete_queues_cbdata *cbdata = cbdata_;
-
-    if (!queue_ids_include(cbdata->queues, queue_id)) {
-        netdev_delete_queue(cbdata->netdev, queue_id);
-    }
-}
-
 static void
 iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos)
 {
@@ -3622,7 +3622,10 @@ iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos)
     if (!qos || qos->type[0] == '\0' || qos->n_queues < 1) {
         netdev_set_qos(iface->netdev, NULL, NULL);
     } else {
-        struct iface_delete_queues_cbdata cbdata;
+        const struct ovsdb_datum *queues;
+        struct netdev_queue_dump dump;
+        unsigned int queue_id;
+        struct smap details;
         bool queue_zero;
         size_t i;
 
@@ -3630,10 +3633,15 @@ iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos)
         netdev_set_qos(iface->netdev, qos->type, &qos->other_config);
 
         /* Deconfigure queues that were deleted. */
-        cbdata.netdev = iface->netdev;
-        cbdata.queues = ovsrec_qos_get_queues(qos, OVSDB_TYPE_INTEGER,
-                                              OVSDB_TYPE_UUID);
-        netdev_dump_queues(iface->netdev, iface_delete_queues, &cbdata);
+        queues = ovsrec_qos_get_queues(qos, OVSDB_TYPE_INTEGER,
+                                       OVSDB_TYPE_UUID);
+        smap_init(&details);
+        NETDEV_QUEUE_FOR_EACH (&queue_id, &details, &dump, iface->netdev) {
+            if (!queue_ids_include(queues, queue_id)) {
+                netdev_delete_queue(iface->netdev, queue_id);
+            }
+        }
+        smap_destroy(&details);
 
         /* Configure queues for 'iface'. */
         queue_zero = false;
@@ -4087,10 +4095,10 @@ collect_splinter_vlans(const struct ovsrec_open_vswitch *ovs_cfg)
                 if (!netdev_open(vlan_dev->name, "system", &netdev)) {
                     if (!netdev_get_in4(netdev, NULL, NULL) ||
                         !netdev_get_in6(netdev, NULL)) {
-                        vlandev_del(vlan_dev->name);
-                    } else {
                         /* It has an IP address configured, so we don't own
                          * it.  Don't delete it. */
+                    } else {
+                        vlandev_del(vlan_dev->name);
                     }
                     netdev_close(netdev);
                 }