[ovs-dev] [reordering v2 2/2] ofproto-dpif-upcall: Use correct actions for slow-pathed flows.

Ben Pfaff blp at nicira.com
Tue Sep 17 23:08:22 UTC 2013


When a flow is slow-pathed, every packet needs to translated separately
and treated accordingly.  The code here (and the code that preceded it)
did translate every packet separately but ignored the actions, instead
using the actions from the initial translation that determined that the
flow needed to be slow-pathed.

Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 ofproto/ofproto-dpif-upcall.c |   28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 00d74b4..bb077a5 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -597,12 +597,14 @@ handle_miss_upcalls(struct udpif *udpif, struct list *upcalls)
 {
     struct dpif_op *opsp[FLOW_MISS_MAX_BATCH];
     struct dpif_op ops[FLOW_MISS_MAX_BATCH];
+    void *tmp_actions[FLOW_MISS_MAX_BATCH];
+    size_t n_tmp_actions, n_upcalls, n_ops;
     struct upcall *upcall, *next;
     struct flow_miss_batch *fmb;
-    size_t n_upcalls, n_ops, i;
     struct flow_miss *miss;
     unsigned int reval_seq;
     bool fail_open;
+    size_t i;
 
     /* Extract the flow from each upcall.  Construct in fmb->misses a hash
      * table that maps each unique flow to a 'struct flow_miss'.
@@ -741,18 +743,31 @@ handle_miss_upcalls(struct udpif *udpif, struct list *upcalls)
      * The loop fills 'ops' with an array of operations to execute in the
      * datapath. */
     n_ops = 0;
+    n_tmp_actions = 0;
     LIST_FOR_EACH (upcall, list_node, upcalls) {
         struct flow_miss *miss = upcall->flow_miss;
         struct ofpbuf *packet = upcall->dpif_upcall.packet;
+        struct nlattr *odp_actions;
+        size_t odp_actions_len;
 
         if (miss->xout.slow) {
             struct rule_dpif *rule;
+            struct xlate_out xout;
             struct xlate_in xin;
 
             rule_dpif_lookup(miss->ofproto, &miss->flow, NULL, &rule);
             xlate_in_init(&xin, miss->ofproto, &miss->flow, rule, 0, packet);
-            xlate_actions_for_side_effects(&xin);
+            xlate_actions(&xin, &xout);
             rule_dpif_unref(rule);
+
+            odp_actions = ofpbuf_steal_data(&xout.odp_actions);
+            odp_actions_len = xout.odp_actions.size;
+            xlate_out_uninit(&xout);
+
+            tmp_actions[n_tmp_actions++] = odp_actions;
+        } else {
+            odp_actions = miss->xout.odp_actions.data;
+            odp_actions_len = miss->xout.odp_actions.size;
         }
 
         if (miss->xout.odp_actions.size) {
@@ -776,8 +791,8 @@ handle_miss_upcalls(struct udpif *udpif, struct list *upcalls)
             op->u.execute.key = miss->key;
             op->u.execute.key_len = miss->key_len;
             op->u.execute.packet = packet;
-            op->u.execute.actions = miss->xout.odp_actions.data;
-            op->u.execute.actions_len = miss->xout.odp_actions.size;
+            op->u.execute.actions = odp_actions;
+            op->u.execute.actions_len = odp_actions_len;
         }
     }
 
@@ -787,6 +802,11 @@ handle_miss_upcalls(struct udpif *udpif, struct list *upcalls)
     }
     dpif_operate(udpif->dpif, opsp, n_ops);
 
+    /* Free temporary actions. */
+    for (i = 0; i < n_tmp_actions; i++) {
+        free(tmp_actions[i]);
+    }
+
     /* Special case for fail-open mode.
      *
      * If we are in fail-open mode, but we are connected to a controller too,
-- 
1.7.10.4




More information about the dev mailing list