Signed-off-by: Jarno Rajahalme <jarno.rajaha...@nsn.com>
---
 ofproto/ofproto-dpif.c |   26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index d4c94f1..a5abe70 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -3849,16 +3849,24 @@ do_handle_upcalls(struct dpif_backer *backer, struct 
dpif_upcall *upcalls,
             continue;
         }
 
-        if (miss->key_fitness != ODP_FIT_PERFECT) {
+        if (miss->key_fitness == ODP_FIT_PERFECT) {
+            /* We have a perfect key fitness, keep the flow.
+             * This is safe because MISS_UPCALLs never have the
+             * packet modified by any actions before being passed to us. */
+
+            /* User kernel provided hash if available */
+            hash = (nl_attr_type(upcall->key) == OVS_KEY_ATTR_HASH)
+                ? nl_attr_get_u32(upcall->key) : flow_hash(&miss->flow, 0);
+        } else {
             /* The packet may have been modified since the key extraction,
              * or the kernel provided key may otherwise be insufficient.
              * Do full flow key extraction, but keep the metadata.
              */
             flow_extract_l2_onwards(upcall->packet, &miss->flow);
+            hash = flow_hash(&miss->flow, 0);
         }
 
         /* Add other packets to a to-do list. */
-        hash = flow_hash(&miss->flow, 0);
         existing_miss = flow_miss_find(&todo, &miss->flow, hash);
         if (!existing_miss) {
             hmap_insert(&todo, &miss->hmap_node, hash);
@@ -4150,7 +4158,12 @@ update_stats(struct dpif_backer *backer)
             netdev_vport_inc_rx(ofport->up.netdev, stats);
         }
 
-        key_hash = odp_flow_key_hash(key, key_len);
+        /* User kernel provided hash if available */
+        if (nl_attr_type(key) == OVS_KEY_ATTR_HASH) {
+            key_hash = nl_attr_get_u32(key);
+        } else {
+            key_hash = odp_flow_key_hash(key, key_len);
+        }
         subfacet = subfacet_find(ofproto, key, key_len, key_hash, &flow);
         switch (subfacet ? subfacet->path : SF_NOT_INSTALLED) {
         case SF_FAST_PATH:
@@ -4983,7 +4996,12 @@ subfacet_create(struct facet *facet, struct flow_miss 
*miss,
     uint32_t key_hash;
     struct subfacet *subfacet;
 
-    key_hash = odp_flow_key_hash(key, key_len);
+    /* User kernel provided hash if available */
+    if (nl_attr_type(key) == OVS_KEY_ATTR_HASH) {
+        key_hash = nl_attr_get_u32(key);
+    } else {
+        key_hash = odp_flow_key_hash(key, key_len);
+    }
 
     if (list_is_empty(&facet->subfacets)) {
         subfacet = &facet->one_subfacet;
-- 
1.7.10.4

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

Reply via email to