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