vswitchd: Move fail-mode config to Bridge table
[sliver-openvswitch.git] / ofproto / ofproto.c
index 66b957e..69004bc 100644 (file)
@@ -274,6 +274,7 @@ struct ofproto {
     /* OpenFlow connections. */
     struct hmap controllers;   /* Controller "struct ofconn"s. */
     struct list all_conns;     /* Contains "struct ofconn"s. */
+    enum ofproto_fail_mode fail_mode;
     struct pvconn **listeners;
     size_t n_listeners;
     struct pvconn **snoops;
@@ -586,13 +587,40 @@ update_in_band_remotes(struct ofproto *ofproto)
     free(addrs);
 }
 
+static void
+update_fail_open(struct ofproto *p)
+{
+    struct ofconn *ofconn;
+
+    if (!hmap_is_empty(&p->controllers)
+            && p->fail_mode == OFPROTO_FAIL_STANDALONE) {
+        struct rconn **rconns;
+        size_t n;
+
+        if (!p->fail_open) {
+            p->fail_open = fail_open_create(p, p->switch_status);
+        }
+
+        n = 0;
+        rconns = xmalloc(hmap_count(&p->controllers) * sizeof *rconns);
+        HMAP_FOR_EACH (ofconn, struct ofconn, hmap_node, &p->controllers) {
+            rconns[n++] = ofconn->rconn;
+        }
+
+        fail_open_set_controllers(p->fail_open, rconns, n);
+        /* p->fail_open takes ownership of 'rconns'. */
+    } else {
+        fail_open_destroy(p->fail_open);
+        p->fail_open = NULL;
+    }
+}
+
 void
 ofproto_set_controllers(struct ofproto *p,
                         const struct ofproto_controller *controllers,
                         size_t n_controllers)
 {
     struct shash new_controllers;
-    enum ofproto_fail_mode fail_mode;
     struct ofconn *ofconn, *next;
     bool ss_exists;
     size_t i;
@@ -607,7 +635,6 @@ ofproto_set_controllers(struct ofproto *p,
         }
     }
 
-    fail_mode = OFPROTO_FAIL_STANDALONE;
     ss_exists = false;
     HMAP_FOR_EACH_SAFE (ofconn, next, struct ofconn, hmap_node,
                         &p->controllers) {
@@ -621,36 +648,13 @@ ofproto_set_controllers(struct ofproto *p,
             if (ofconn->ss) {
                 ss_exists = true;
             }
-            if (c->fail == OFPROTO_FAIL_SECURE) {
-                fail_mode = OFPROTO_FAIL_SECURE;
-            }
         }
     }
     shash_destroy(&new_controllers);
 
     update_in_band_remotes(p);
 
-    if (!hmap_is_empty(&p->controllers)
-        && fail_mode == OFPROTO_FAIL_STANDALONE) {
-        struct rconn **rconns;
-        size_t n;
-
-        if (!p->fail_open) {
-            p->fail_open = fail_open_create(p, p->switch_status);
-        }
-
-        n = 0;
-        rconns = xmalloc(hmap_count(&p->controllers) * sizeof *rconns);
-        HMAP_FOR_EACH (ofconn, struct ofconn, hmap_node, &p->controllers) {
-            rconns[n++] = ofconn->rconn;
-        }
-
-        fail_open_set_controllers(p->fail_open, rconns, n);
-        /* p->fail_open takes ownership of 'rconns'. */
-    } else {
-        fail_open_destroy(p->fail_open);
-        p->fail_open = NULL;
-    }
+    update_fail_open(p);
 
     if (!hmap_is_empty(&p->controllers) && !ss_exists) {
         ofconn = CONTAINER_OF(hmap_first(&p->controllers),
@@ -660,6 +664,13 @@ ofproto_set_controllers(struct ofproto *p,
     }
 }
 
+void
+ofproto_set_fail_mode(struct ofproto *p, enum ofproto_fail_mode fail_mode)
+{
+    p->fail_mode = fail_mode;
+    update_fail_open(p);
+}
+
 /* Drops the connections between 'ofproto' and all of its controllers, forcing
  * them to reconnect. */
 void