ofproto-dpif: Use megaflows.
authorJustin Pettit <jpettit@nicira.com>
Tue, 21 May 2013 00:48:49 +0000 (17:48 -0700)
committerJustin Pettit <jpettit@nicira.com>
Fri, 21 Jun 2013 00:12:01 +0000 (17:12 -0700)
The commit configures the masks generated from megaflows and pushes
them through the dpif layer.

With this commit and a wildcard supporting OVS kernel module,
ovs-vswitchd's flow setup rate is very close to that of the Linux
bridge.

Signed-off-by: Justin Pettit <jpettit@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
NEWS
PORTING
ofproto/ofproto-dpif.c

diff --git a/NEWS b/NEWS
index aae3378..7b43447 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,10 @@ post-v1.11.0
 
 v1.11.0 - xx xxx xxxx
 ---------------------
 
 v1.11.0 - xx xxx xxxx
 ---------------------
+    - Support for megaflows, which allows wildcarding in the kernel (and
+      any dpif implementation that supports wildcards).  Depending on
+      the flow table and switch configuration, flow set up rates are
+      close to the Linux bridge.
     - The "tutorial" directory contains a new tutorial for some advanced
       Open vSwitch features.
     - Stable bond mode has been removed.
     - The "tutorial" directory contains a new tutorial for some advanced
       Open vSwitch features.
     - Stable bond mode has been removed.
diff --git a/PORTING b/PORTING
index ffde296..53c19d3 100644 (file)
--- a/PORTING
+++ b/PORTING
@@ -148,9 +148,9 @@ depends on a few different factors:
 
     * A dpif provider is usually easier to implement, but most
       appropriate for software switching.  It "explodes" wildcard
 
     * A dpif provider is usually easier to implement, but most
       appropriate for software switching.  It "explodes" wildcard
-      rules into exact-match entries.  This allows fast hash lookups
-      in software, but makes inefficient use of TCAMs in hardware
-      that support wildcarding.
+      rules into exact-match entries (with an optional wildcard mask).
+      This allows fast hash lookups in software, but makes
+      inefficient use of TCAMs in hardware that support wildcarding.
 
 The following sections describe how to implement each kind of port.
 
 
 The following sections describe how to implement each kind of port.
 
@@ -175,18 +175,26 @@ Writing a dpif Provider
 
 Open vSwitch has a built-in ofproto provider named "ofproto-dpif",
 which is built on top of a library for manipulating datapaths, called
 
 Open vSwitch has a built-in ofproto provider named "ofproto-dpif",
 which is built on top of a library for manipulating datapaths, called
-"dpif".  A "datapath" is a simple flow table, one that supports only
-exact-match flows, that is, flows without wildcards.  When a packet
-arrives on a network device, the datapath looks for it in this
-exact-match table.  If there is a match, then it performs the
-associated actions.  If there is no match, the datapath passes the
-packet up to ofproto-dpif, which maintains an OpenFlow flow table
-(that supports wildcards).  If the packet matches in this flow table,
-then ofproto-dpif executes its actions and inserts a new exact-match
-entry into the dpif flow table.  (Otherwise, ofproto-dpif passes the
+"dpif".  A "datapath" is a simple flow table, one that is only required
+to support exact-match flows, that is, flows without wildcards.  When a
+packet arrives on a network device, the datapath looks for it in this
+table.  If there is a match, then it performs the associated actions.
+If there is no match, the datapath passes the packet up to ofproto-dpif,
+which maintains the full OpenFlow flow table.  If the packet matches in
+this flow table, then ofproto-dpif executes its actions and inserts a
+new entry into the dpif flow table.  (Otherwise, ofproto-dpif passes the
 packet up to ofproto to send the packet to the OpenFlow controller, if
 one is configured.)
 
 packet up to ofproto to send the packet to the OpenFlow controller, if
 one is configured.)
 
+When calculating the dpif flow, ofproto-dpif generates an exact-match
+flow that describes the missed packet.  It makes an effort to figure out
+what fields can be wildcarded based on the switch's configuration and
+OpenFlow flow table.  The dpif is free to ignore the suggested wildcards
+and only support the exact-match entry.  However, if the dpif supports
+wildcarding, then it can use the masks to match multiple flows with
+fewer entries and potentially significantly reduce the number of flow
+misses handled by ofproto-dpif.
+
 The "dpif" library in turn delegates much of its functionality to a
 "dpif provider".  The following diagram shows how dpif providers fit
 into the Open vSwitch architecture:
 The "dpif" library in turn delegates much of its functionality to a
 "dpif provider".  The following diagram shows how dpif providers fit
 into the Open vSwitch architecture:
index cf85b24..986f9a7 100644 (file)
@@ -3247,6 +3247,9 @@ struct flow_miss_op {
     struct xlate_out xout;
     bool xout_garbage;           /* 'xout' needs to be uninitialized? */
 
     struct xlate_out xout;
     bool xout_garbage;           /* 'xout' needs to be uninitialized? */
 
+    struct ofpbuf mask;          /* Flow mask for "put" ops. */
+    struct odputil_keybuf maskbuf;
+
     /* If this is a "put" op, then a pointer to the subfacet that should
      * be marked as uninstalled if the operation fails. */
     struct subfacet *subfacet;
     /* If this is a "put" op, then a pointer to the subfacet that should
      * be marked as uninstalled if the operation fails. */
     struct subfacet *subfacet;
@@ -3318,6 +3321,7 @@ init_flow_miss_execute_op(struct flow_miss *miss, struct ofpbuf *packet,
     op->dpif_op.u.execute.key = miss->key;
     op->dpif_op.u.execute.key_len = miss->key_len;
     op->dpif_op.u.execute.packet = packet;
     op->dpif_op.u.execute.key = miss->key;
     op->dpif_op.u.execute.key_len = miss->key_len;
     op->dpif_op.u.execute.packet = packet;
+    ofpbuf_use_stack(&op->mask, &op->maskbuf, sizeof op->maskbuf);
 }
 
 /* Helper for handle_flow_miss_without_facet() and
 }
 
 /* Helper for handle_flow_miss_without_facet() and
@@ -3465,14 +3469,19 @@ handle_flow_miss_with_facet(struct flow_miss *miss, struct facet *facet,
 
         subfacet->path = want_path;
 
 
         subfacet->path = want_path;
 
+        ofpbuf_use_stack(&op->mask, &op->maskbuf, sizeof op->maskbuf);
+        odp_flow_key_from_mask(&op->mask, &facet->xout.wc.masks,
+                               &miss->flow, UINT32_MAX);
+
         op->xout_garbage = false;
         op->dpif_op.type = DPIF_OP_FLOW_PUT;
         op->subfacet = subfacet;
         put->flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
         put->key = miss->key;
         put->key_len = miss->key_len;
         op->xout_garbage = false;
         op->dpif_op.type = DPIF_OP_FLOW_PUT;
         op->subfacet = subfacet;
         put->flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
         put->key = miss->key;
         put->key_len = miss->key_len;
-        put->mask = NULL;
-        put->mask_len = 0;
+        put->mask = op->mask.data;
+        put->mask_len = op->mask.size;
+
         if (want_path == SF_FAST_PATH) {
             put->actions = facet->xout.odp_actions.data;
             put->actions_len = facet->xout.odp_actions.size;
         if (want_path == SF_FAST_PATH) {
             put->actions = facet->xout.odp_actions.data;
             put->actions_len = facet->xout.odp_actions.size;
@@ -5030,6 +5039,8 @@ subfacet_install(struct subfacet *subfacet, const struct ofpbuf *odp_actions,
     enum subfacet_path path = facet->xout.slow ? SF_SLOW_PATH : SF_FAST_PATH;
     const struct nlattr *actions = odp_actions->data;
     size_t actions_len = odp_actions->size;
     enum subfacet_path path = facet->xout.slow ? SF_SLOW_PATH : SF_FAST_PATH;
     const struct nlattr *actions = odp_actions->data;
     size_t actions_len = odp_actions->size;
+    struct odputil_keybuf maskbuf;
+    struct ofpbuf mask;
 
     uint64_t slow_path_stub[128 / 8];
     enum dpif_flow_put_flags flags;
 
     uint64_t slow_path_stub[128 / 8];
     enum dpif_flow_put_flags flags;
@@ -5046,8 +5057,12 @@ subfacet_install(struct subfacet *subfacet, const struct ofpbuf *odp_actions,
                           &actions, &actions_len);
     }
 
                           &actions, &actions_len);
     }
 
-    ret = dpif_flow_put(ofproto->backer->dpif, flags, subfacet->key,
-                        subfacet->key_len,  NULL, 0,
+    ofpbuf_use_stack(&mask, &maskbuf, sizeof maskbuf);
+    odp_flow_key_from_mask(&mask, &facet->xout.wc.masks,
+                           &facet->flow, UINT32_MAX);
+
+    ret = dpif_flow_put(subfacet->backer->dpif, flags, subfacet->key,
+                        subfacet->key_len,  mask.data, mask.size,
                         actions, actions_len, stats);
 
     if (stats) {
                         actions, actions_len, stats);
 
     if (stats) {