ofproto: Allow client to pass down extra (IP,port) tuples for in-band.
authorBen Pfaff <blp@nicira.com>
Tue, 20 Apr 2010 23:36:01 +0000 (16:36 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 26 Apr 2010 18:02:12 +0000 (11:02 -0700)
ovs-vswitchd needs to be able to tell ofproto where the OVSDB managers are,
so that in-band control can allow traffic to it even if there is no
connection to the controller yet.  This adds the basis for that feature.

ofproto/ofproto.c
ofproto/ofproto.h

index 5f2f6f4c0c2ae60f0efede1d6f0f6492fea1048c..3f9cc90ed0bef4d9bef4654f8b5eccafd9f71c0a 100644 (file)
@@ -255,6 +255,9 @@ struct ofproto {
     /* In-band control. */
     struct in_band *in_band;
     long long int next_in_band_update;
+    struct sockaddr_in *extra_in_band_remotes;
+    size_t n_extra_remotes;
+
     /* Flow table. */
     struct classifier cls;
     bool need_revalidate;
@@ -525,11 +528,13 @@ update_in_band_remotes(struct ofproto *ofproto)
 {
     const struct ofconn *ofconn;
     struct sockaddr_in *addrs;
+    size_t max_addrs, n_addrs;
     bool discovery;
-    size_t n_addrs;
-
+    size_t i;
 
-    addrs = xmalloc(hmap_count(&ofproto->controllers) * sizeof *addrs);
+    /* Allocate enough memory for as many remotes as we could possibly have. */
+    max_addrs = ofproto->n_extra_remotes + hmap_count(&ofproto->controllers);
+    addrs = xmalloc(max_addrs * sizeof *addrs);
     n_addrs = 0;
 
     /* Add all the remotes. */
@@ -546,6 +551,9 @@ update_in_band_remotes(struct ofproto *ofproto)
             discovery = true;
         }
     }
+    for (i = 0; i < ofproto->n_extra_remotes; i++) {
+        addrs[n_addrs++] = ofproto->extra_in_band_remotes[i];
+    }
 
     /* Create or update or destroy in-band.
      *
@@ -642,6 +650,47 @@ ofproto_set_controllers(struct ofproto *p,
     }
 }
 
+static bool
+any_extras_changed(const struct ofproto *ofproto,
+                   const struct sockaddr_in *extras, size_t n)
+{
+    size_t i;
+
+    if (n != ofproto->n_extra_remotes) {
+        return true;
+    }
+
+    for (i = 0; i < n; i++) {
+        const struct sockaddr_in *old = &ofproto->extra_in_band_remotes[i];
+        const struct sockaddr_in *new = &extras[i];
+
+        if (old->sin_addr.s_addr != new->sin_addr.s_addr ||
+            old->sin_port != new->sin_port) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/* Sets the 'n' TCP port addresses in 'extras' as ones to which 'ofproto''s
+ * in-band control should guarantee access, in the same way that in-band
+ * control guarantees access to OpenFlow controllers. */
+void
+ofproto_set_extra_in_band_remotes(struct ofproto *ofproto,
+                                  const struct sockaddr_in *extras, size_t n)
+{
+    if (!any_extras_changed(ofproto, extras, n)) {
+        return;
+    }
+
+    free(ofproto->extra_in_band_remotes);
+    ofproto->n_extra_remotes = n;
+    ofproto->extra_in_band_remotes = xmemdup(extras, n * sizeof *extras);
+
+    update_in_band_remotes(ofproto);
+}
+
 void
 ofproto_set_desc(struct ofproto *p,
                  const char *mfr_desc, const char *hw_desc,
@@ -845,6 +894,7 @@ ofproto_destroy(struct ofproto *p)
 
     in_band_destroy(p->in_band);
     p->in_band = NULL;
+    free(p->extra_in_band_remotes);
 
     ofproto_flush_flows(p);
     classifier_destroy(&p->cls);
index 32d7623d0ad0cc65d7ebb8e6637c780a661e9bb4..c3d71e8d1bd7a0566ef573b21e043a526396d577 100644 (file)
@@ -104,6 +104,8 @@ bool ofproto_is_alive(const struct ofproto *);
 void ofproto_set_datapath_id(struct ofproto *, uint64_t datapath_id);
 void ofproto_set_controllers(struct ofproto *,
                              const struct ofproto_controller *, size_t n);
+void ofproto_set_extra_in_band_remotes(struct ofproto *,
+                                       const struct sockaddr_in *, size_t n);
 void ofproto_set_desc(struct ofproto *,
                       const char *mfr_desc, const char *hw_desc,
                       const char *sw_desc, const char *serial_desc,