struct sw_flow_mask mask;
        struct sk_buff *reply;
        struct datapath *dp;
+       struct sw_flow_key *key;
        struct sw_flow_actions *acts;
        struct sw_flow_match match;
        u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
        }
 
        /* Extract key. */
-       ovs_match_init(&match, &new_flow->key, false, &mask);
+       key = kzalloc(sizeof(*key), GFP_KERNEL);
+       if (!key) {
+               error = -ENOMEM;
+               goto err_kfree_key;
+       }
+
+       ovs_match_init(&match, key, false, &mask);
        error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
                                  a[OVS_FLOW_ATTR_MASK], log);
        if (error)
                goto err_kfree_flow;
 
+       ovs_flow_mask_key(&new_flow->key, key, true, &mask);
+
        /* Extract flow identifier. */
        error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
-                                      &new_flow->key, log);
+                                      key, log);
        if (error)
                goto err_kfree_flow;
 
-       /* unmasked key is needed to match when ufid is not used. */
-       if (ovs_identifier_is_key(&new_flow->id))
-               match.key = new_flow->id.unmasked_key;
-
-       ovs_flow_mask_key(&new_flow->key, &new_flow->key, true, &mask);
-
        /* Validate actions. */
        error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS],
                                     &new_flow->key, &acts, log);
        if (ovs_identifier_is_ufid(&new_flow->id))
                flow = ovs_flow_tbl_lookup_ufid(&dp->table, &new_flow->id);
        if (!flow)
-               flow = ovs_flow_tbl_lookup(&dp->table, &new_flow->key);
+               flow = ovs_flow_tbl_lookup(&dp->table, key);
        if (likely(!flow)) {
                rcu_assign_pointer(new_flow->sf_acts, acts);
 
 
        if (reply)
                ovs_notify(&dp_flow_genl_family, reply, info);
+
+       kfree(key);
        return 0;
 
 err_unlock_ovs:
        ovs_nla_free_flow_actions(acts);
 err_kfree_flow:
        ovs_flow_free(new_flow, false);
+err_kfree_key:
+       kfree(key);
 error:
        return error;
 }