[ovs-dev] [PATCH] vswitch: Add other-config:in-band-queue to set queue for in-band control.

Ben Pfaff blp at nicira.com
Tue Nov 2 17:46:37 UTC 2010


Until now, in-band control traffic has always gone to the default queue,
typically queue 0.  It makes sense to be able to assing control traffic to
its own queue, so this commit enables that.

Bug #3653.
---
 ofproto/in-band.c    |   53 ++++++++++++++++++++++++++++++++++++++++---------
 ofproto/in-band.h    |    1 +
 ofproto/ofproto.c    |   19 +++++++++++++++++-
 ofproto/ofproto.h    |    1 +
 vswitchd/bridge.c    |   12 ++++++++--
 vswitchd/vswitch.xml |    8 +++++++
 6 files changed, 80 insertions(+), 14 deletions(-)

diff --git a/ofproto/in-band.c b/ofproto/in-band.c
index 639f9f5..f868ed3 100644
--- a/ofproto/in-band.c
+++ b/ofproto/in-band.c
@@ -240,6 +240,7 @@ struct in_band_remote {
 struct in_band {
     struct ofproto *ofproto;
     struct status_category *ss_cat;
+    int queue_id, prev_queue_id;
 
     /* Remote information. */
     time_t next_remote_refresh; /* Refresh timer. */
@@ -664,14 +665,33 @@ drop_rules(struct in_band *ib)
 static void
 add_rule(struct in_band *ib, const struct in_band_rule *rule)
 {
-    union ofp_action action;
-
-    action.type = htons(OFPAT_OUTPUT);
-    action.output.len = htons(sizeof action);
-    action.output.port = htons(OFPP_NORMAL);
-    action.output.max_len = htons(0);
-    ofproto_add_flow(ib->ofproto, &rule->flow, rule->wildcards,
-                     rule->priority, &action, 1, 0);
+    struct {
+        struct nx_action_set_queue nxsq;
+        struct ofp_action_output oao;
+    } actions;
+
+    memset(&actions, 0, sizeof actions);
+
+    actions.oao.type = htons(OFPAT_OUTPUT);
+    actions.oao.len = htons(sizeof actions.oao);
+    actions.oao.port = htons(OFPP_NORMAL);
+    actions.oao.max_len = htons(0);
+
+    if (ib->queue_id < 0) {
+        ofproto_add_flow(ib->ofproto, &rule->flow, rule->wildcards,
+                         rule->priority, (union ofp_action *) &actions.oao,
+                         1, 0);
+    } else {
+        actions.nxsq.type = htons(OFPAT_VENDOR);
+        actions.nxsq.len = htons(sizeof actions.nxsq);
+        actions.nxsq.vendor = htonl(NX_VENDOR_ID);
+        actions.nxsq.subtype = htons(NXAST_SET_QUEUE);
+        actions.nxsq.queue_id = htonl(ib->queue_id);
+
+        ofproto_add_flow(ib->ofproto, &rule->flow, rule->wildcards,
+                         rule->priority, (union ofp_action *) &actions,
+                         sizeof actions / sizeof(union ofp_action), 0);
+    }
 }
 
 /* Inserts flows into the flow table for the current state of 'ib'. */
@@ -706,15 +726,17 @@ compare_macs(const void *a, const void *b)
 void
 in_band_run(struct in_band *ib)
 {
+    bool local_change, remote_change, queue_id_change;
     struct in_band_remote *r;
-    bool local_change, remote_change;
 
     local_change = refresh_local(ib);
     remote_change = refresh_remotes(ib);
-    if (!local_change && !remote_change) {
+    queue_id_change = ib->queue_id != ib->prev_queue_id;
+    if (!local_change && !remote_change && !queue_id_change) {
         /* Nothing changed, nothing to do. */
         return;
     }
+    ib->prev_queue_id = ib->queue_id;
 
     /* Drop old rules. */
     drop_rules(ib);
@@ -787,6 +809,7 @@ in_band_create(struct ofproto *ofproto, struct dpif *dpif,
     in_band->ofproto = ofproto;
     in_band->ss_cat = switch_status_register(ss, "in-band",
                                              in_band_status_cb, in_band);
+    in_band->queue_id = in_band->prev_queue_id = -1;
     in_band->next_remote_refresh = TIME_MIN;
     in_band->next_local_refresh = TIME_MIN;
     in_band->local_netdev = local_netdev;
@@ -857,3 +880,13 @@ in_band_set_remotes(struct in_band *ib,
     /* Force refresh in next call to in_band_run(). */
     ib->next_remote_refresh = TIME_MIN;
 }
+
+/* Sets the OpenFlow queue used by flows set up by 'ib' to 'queue_id'.  If
+ * 'queue_id' is negative, 'ib' will not set any queue (which is also the
+ * default). */
+void
+in_band_set_queue(struct in_band *ib, int queue_id)
+{
+    ib->queue_id = queue_id;
+}
+
diff --git a/ofproto/in-band.h b/ofproto/in-band.h
index 27a5fe5..23a30ce 100644
--- a/ofproto/in-band.h
+++ b/ofproto/in-band.h
@@ -31,6 +31,7 @@ int in_band_create(struct ofproto *, struct dpif *, struct switch_status *,
                    struct in_band **);
 void in_band_destroy(struct in_band *);
 
+void in_band_set_queue(struct in_band *, int queue_id);
 void in_band_set_remotes(struct in_band *,
                          const struct sockaddr_in *, size_t n);
 
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 0caeef0..d2bf30d 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -290,6 +290,7 @@ struct ofproto {
     long long int next_in_band_update;
     struct sockaddr_in *extra_in_band_remotes;
     size_t n_extra_remotes;
+    int in_band_queue;
 
     /* Flow table. */
     struct classifier cls;
@@ -394,11 +395,14 @@ ofproto_create(const char *datapath, const char *datapath_type,
 
     /* Initialize submodules. */
     p->switch_status = switch_status_create(p);
-    p->in_band = NULL;
     p->fail_open = NULL;
     p->netflow = NULL;
     p->sflow = NULL;
 
+    /* Initialize in-band control. */
+    p->in_band = NULL;
+    p->in_band_queue = -1;
+
     /* Initialize flow table. */
     classifier_init(&p->cls);
     p->need_revalidate = false;
@@ -586,6 +590,7 @@ update_in_band_remotes(struct ofproto *ofproto)
         if (ofproto->in_band) {
             in_band_set_remotes(ofproto->in_band, addrs, n_addrs);
         }
+        in_band_set_queue(ofproto->in_band, ofproto->in_band_queue);
         ofproto->next_in_band_update = time_msec() + 1000;
     } else {
         in_band_destroy(ofproto->in_band);
@@ -762,6 +767,18 @@ ofproto_set_extra_in_band_remotes(struct ofproto *ofproto,
     update_in_band_remotes(ofproto);
 }
 
+/* Sets the OpenFlow queue used by flows set up by in-band control on
+ * 'ofproto' to 'queue_id'.  If 'queue_id' is negative, then in-band control
+ * flows will use the default queue. */
+void
+ofproto_set_in_band_queue(struct ofproto *ofproto, int queue_id)
+{
+    if (queue_id != ofproto->in_band_queue) {
+        ofproto->in_band_queue = queue_id;
+        update_in_band_remotes(ofproto);
+    }
+}
+
 void
 ofproto_set_desc(struct ofproto *p,
                  const char *mfr_desc, const char *hw_desc,
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index 362ea26..f169408 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -105,6 +105,7 @@ void ofproto_set_fail_mode(struct ofproto *, enum ofproto_fail_mode fail_mode);
 void ofproto_reconnect_controllers(struct ofproto *);
 void ofproto_set_extra_in_band_remotes(struct ofproto *,
                                        const struct sockaddr_in *, size_t n);
+void ofproto_set_in_band_queue(struct ofproto *, int queue_id);
 void ofproto_set_desc(struct ofproto *,
                       const char *mfr_desc, const char *hw_desc,
                       const char *sw_desc, const char *serial_desc,
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 53a24e3..9f513d5 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -1701,23 +1701,29 @@ bridge_reconfigure_remotes(struct bridge *br,
                            const struct sockaddr_in *managers,
                            size_t n_managers)
 {
+    const char *disable_ib_str, *queue_id_str;
+    bool disable_in_band = false;
+    int queue_id;
+
     struct ovsrec_controller **controllers;
     size_t n_controllers;
     bool had_primary;
-    const char *disable_ib_str;
-    bool disable_in_band = false;
 
     struct ofproto_controller *ocs;
     size_t n_ocs;
     size_t i;
 
-
     /* Check if we should disable in-band control on this bridge. */
     disable_ib_str = bridge_get_other_config(br->cfg, "disable-in-band");
     if (disable_ib_str && !strcmp(disable_ib_str, "true")) {
         disable_in_band = true;
     }
 
+    /* Set OpenFlow queue ID for in-band control. */
+    queue_id_str = bridge_get_other_config(br->cfg, "in-band-queue");
+    queue_id = queue_id_str ? strtol(queue_id_str, NULL, 10) : -1;
+    ofproto_set_in_band_queue(br->ofproto, queue_id);
+
     if (disable_in_band) {
         ofproto_set_extra_in_band_remotes(br->ofproto, NULL, 0);
     } else {
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index 8151807..9c38010 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -338,6 +338,14 @@
             <var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var>
             to set the hardware address of the local port and influence the
             datapath ID.</dd>
+          <dt><code>in-band-queue</code></dt>
+          <dd>
+            A queue ID as a nonnegative integer.  This sets the OpenFlow queue
+            ID that will be used by flows set up by in-band control on this
+            bridge.  If unset, or if the port used by an in-band control flow
+            does not have QoS configured, or if the port does not have a queue
+            with the specified ID, the default queue is used instead.
+          </dd>
         </dl>
       </column>
     </group>
-- 
1.7.1





More information about the dev mailing list