All the callers of the function already have a copy of the extracted
flow in their stack (or a few frames before).

This is useful for different resons:
* It forces the callers to also call flow_extract() on the packet, which
  is necessary to initialize the l2,l3,l4 pointers.
* It will be used in the userspace datapath to generate the RSS hash by
  a following commit
* It can be used by the userspace connection tracker to avoid extracting
  the l3 type again.

Signed-off-by: Daniele Di Proietto <diproiet...@vmware.com>
---
 lib/dpif.c                    |  4 +++-
 lib/dpif.h                    |  1 +
 ofproto/ofproto-dpif-upcall.c |  1 +
 ofproto/ofproto-dpif.c        | 10 ++++++++++
 4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/lib/dpif.c b/lib/dpif.c
index 5037ac6..e463cd8 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1081,6 +1081,7 @@ dpif_flow_dump_next(struct dpif_flow_dump_thread *thread,
 
 struct dpif_execute_helper_aux {
     struct dpif *dpif;
+    const struct flow *flow;
     int error;
 };
 
@@ -1126,6 +1127,7 @@ dpif_execute_helper_cb(void *aux_, struct dp_packet 
**packets, int cnt,
         }
 
         execute.packet = packet;
+        execute.flow = aux->flow;
         execute.needs_help = false;
         execute.probe = false;
         execute.mtu = 0;
@@ -1160,7 +1162,7 @@ dpif_execute_helper_cb(void *aux_, struct dp_packet 
**packets, int cnt,
 static int
 dpif_execute_with_help(struct dpif *dpif, struct dpif_execute *execute)
 {
-    struct dpif_execute_helper_aux aux = {dpif, 0};
+    struct dpif_execute_helper_aux aux = {dpif, execute->flow, 0};
     struct dp_packet *pp;
 
     COVERAGE_INC(dpif_execute_with_help);
diff --git a/lib/dpif.h b/lib/dpif.h
index 97d5d06..6788301 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -699,6 +699,7 @@ struct dpif_execute {
     bool probe;                     /* Suppress error messages. */
     unsigned int mtu;               /* Maximum transmission unit to fragment.
                                        0 if not a fragmented packet */
+    const struct flow *flow;         /* Flow extracted from 'packet'. */
 
     /* Input, but possibly modified as a side effect of execution. */
     struct dp_packet *packet;          /* Packet to execute. */
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 56f88c7..555c5b4 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -1338,6 +1338,7 @@ handle_upcalls(struct udpif *udpif, struct upcall 
*upcalls,
             op->ukey = NULL;
             op->dop.type = DPIF_OP_EXECUTE;
             op->dop.u.execute.packet = CONST_CAST(struct dp_packet *, packet);
+            op->dop.u.execute.flow = upcall->flow;
             odp_key_to_pkt_metadata(upcall->key, upcall->key_len,
                                     &op->dop.u.execute.packet->md);
             op->dop.u.execute.actions = upcall->odp_actions.data;
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 219933e..3bd26ac 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1061,6 +1061,7 @@ check_variable_length_userdata(struct dpif_backer *backer)
     struct ofpbuf actions;
     struct dpif_execute execute;
     struct dp_packet packet;
+    struct flow flow;
     size_t start;
     int error;
 
@@ -1083,11 +1084,14 @@ check_variable_length_userdata(struct dpif_backer 
*backer)
     eth = dp_packet_put_zeros(&packet, ETH_HEADER_LEN);
     eth->eth_type = htons(0x1234);
 
+    flow_extract(&packet, &flow);
+
     /* Execute the actions.  On older datapaths this fails with ERANGE, on
      * newer datapaths it succeeds. */
     execute.actions = actions.data;
     execute.actions_len = actions.size;
     execute.packet = &packet;
+    execute.flow = &flow;
     execute.needs_help = false;
     execute.probe = true;
     execute.mtu = 0;
@@ -1164,6 +1168,7 @@ check_masked_set_action(struct dpif_backer *backer)
     struct ofpbuf actions;
     struct dpif_execute execute;
     struct dp_packet packet;
+    struct flow flow;
     int error;
     struct ovs_key_ethernet key, mask;
 
@@ -1182,11 +1187,14 @@ check_masked_set_action(struct dpif_backer *backer)
     eth = dp_packet_put_zeros(&packet, ETH_HEADER_LEN);
     eth->eth_type = htons(0x1234);
 
+    flow_extract(&packet, &flow);
+
     /* Execute the actions.  On older datapaths this fails with EINVAL, on
      * newer datapaths it succeeds. */
     execute.actions = actions.data;
     execute.actions_len = actions.size;
     execute.packet = &packet;
+    execute.flow = &flow;
     execute.needs_help = false;
     execute.probe = true;
     execute.mtu = 0;
@@ -3708,6 +3716,7 @@ ofproto_dpif_execute_actions__(struct ofproto_dpif 
*ofproto,
 
     pkt_metadata_from_flow(&packet->md, flow);
     execute.packet = packet;
+    execute.flow = flow;
     execute.needs_help = (xout.slow & SLOW_ACTION) != 0;
     execute.probe = false;
     execute.mtu = 0;
@@ -4420,6 +4429,7 @@ nxt_resume(struct ofproto *ofproto_,
         .actions_len = odp_actions.size,
         .needs_help = (slow & SLOW_ACTION) != 0,
         .packet = &packet,
+        .flow = &headers,
     };
     dpif_execute(ofproto->backer->dpif, &execute);
 
-- 
2.1.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to