cfm: Support random VLAN tag for CCM PDUs.
[sliver-openvswitch.git] / vswitchd / bridge.c
index f6cf119..6449333 100644 (file)
@@ -50,7 +50,7 @@
 #include "util.h"
 #include "unixctl.h"
 #include "vlandev.h"
-#include "vswitchd/vswitch-idl.h"
+#include "vswitch-idl.h"
 #include "xenserver.h"
 #include "vlog.h"
 #include "sflow_api.h"
@@ -438,8 +438,12 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
      * has at least one iface, every "struct iface" has a valid ofp_port and
      * netdev. */
     HMAP_FOR_EACH_SAFE (br, next, node, &all_bridges) {
-        if (!br->ofproto && !bridge_add_ofprotos(br)) {
-            bridge_destroy(br);
+        if (!br->ofproto) {
+            if (bridge_add_ofprotos(br)) {
+                bridge_del_ofproto_ports(br);
+            } else {
+                bridge_destroy(br);
+            }
         }
     }
     HMAP_FOR_EACH (br, node, &all_bridges) {
@@ -842,7 +846,7 @@ port_configure_stp(const struct ofproto *ofproto, struct port *port,
     if (config_str) {
         port_s->path_cost = strtoul(config_str, NULL, 10);
     } else {
-        uint32_t current;
+        enum netdev_features current;
 
         if (netdev_get_features(iface->netdev, &current, NULL, NULL, NULL)) {
             /* Couldn't get speed, so assume 100Mb/s. */
@@ -1479,8 +1483,8 @@ iface_refresh_status(struct iface *iface)
 {
     struct shash sh;
 
+    enum netdev_features current;
     enum netdev_flags flags;
-    uint32_t current;
     int64_t bps;
     int mtu;
     int64_t mtu_64;
@@ -2084,7 +2088,7 @@ qos_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
 
     iface = iface_find(argv[1]);
     if (!iface) {
-        unixctl_command_reply(conn, 501, "no such interface");
+        unixctl_command_reply_error(conn, "no such interface");
         return;
     }
 
@@ -2104,10 +2108,10 @@ qos_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
         if (error) {
             ds_put_format(&ds, "failed to dump queues: %s", strerror(error));
         }
-        unixctl_command_reply(conn, 200, ds_cstr(&ds));
+        unixctl_command_reply(conn, ds_cstr(&ds));
     } else {
         ds_put_format(&ds, "QoS not configured on %s\n", iface->name);
-        unixctl_command_reply(conn, 501, ds_cstr(&ds));
+        unixctl_command_reply_error(conn, ds_cstr(&ds));
     }
 
     shash_destroy_free_data(&sh);
@@ -2189,14 +2193,14 @@ bridge_unixctl_dump_flows(struct unixctl_conn *conn, int argc OVS_UNUSED,
 
     br = bridge_lookup(argv[1]);
     if (!br) {
-        unixctl_command_reply(conn, 501, "Unknown bridge");
+        unixctl_command_reply_error(conn, "Unknown bridge");
         return;
     }
 
     ds_init(&results);
     ofproto_get_all_flows(br->ofproto, &results);
 
-    unixctl_command_reply(conn, 200, ds_cstr(&results));
+    unixctl_command_reply(conn, ds_cstr(&results));
     ds_destroy(&results);
 }
 
@@ -2211,7 +2215,7 @@ bridge_unixctl_reconnect(struct unixctl_conn *conn, int argc,
     if (argc > 1) {
         br = bridge_lookup(argv[1]);
         if (!br) {
-            unixctl_command_reply(conn, 501, "Unknown bridge");
+            unixctl_command_reply_error(conn,  "Unknown bridge");
             return;
         }
         ofproto_reconnect_controllers(br->ofproto);
@@ -2220,7 +2224,7 @@ bridge_unixctl_reconnect(struct unixctl_conn *conn, int argc,
             ofproto_reconnect_controllers(br->ofproto);
         }
     }
-    unixctl_command_reply(conn, 200, NULL);
+    unixctl_command_reply(conn, NULL);
 }
 
 static size_t
@@ -3196,11 +3200,9 @@ iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos)
             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);
+            shash_init(&details);
+            netdev_set_queue(iface->netdev, 0, &details);
+            shash_destroy(&details);
         }
     }
 
@@ -3224,6 +3226,7 @@ iface_configure_cfm(struct iface *iface)
 {
     const struct ovsrec_interface *cfg = iface->cfg;
     const char *extended_str, *opstate_str;
+    const char *cfm_ccm_vlan;
     struct cfm_settings s;
 
     if (!cfg->n_cfm_mpid) {
@@ -3234,14 +3237,22 @@ iface_configure_cfm(struct iface *iface)
     s.mpid = *cfg->cfm_mpid;
     s.interval = atoi(get_interface_other_config(iface->cfg, "cfm_interval",
                                                  "0"));
-    s.ccm_vlan = atoi(get_interface_other_config(iface->cfg, "cfm_ccm_vlan",
-                                                 "0"));
+    cfm_ccm_vlan = get_interface_other_config(iface->cfg, "cfm_ccm_vlan", "0");
     s.ccm_pcp = atoi(get_interface_other_config(iface->cfg, "cfm_ccm_pcp",
                                                 "0"));
     if (s.interval <= 0) {
         s.interval = 1000;
     }
 
+    if (!strcasecmp("random", cfm_ccm_vlan)) {
+        s.ccm_vlan = CFM_RANDOM_VLAN;
+    } else {
+        s.ccm_vlan = atoi(cfm_ccm_vlan);
+        if (s.ccm_vlan == CFM_RANDOM_VLAN) {
+            s.ccm_vlan = 0;
+        }
+    }
+
     extended_str = get_interface_other_config(iface->cfg, "cfm_extended",
                                               "false");
     s.extended = !strcasecmp("true", extended_str);