diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index f184a35a1..ea8702397 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -1563,24 +1563,44 @@ get_dpif_flow_stats(const struct dp_netdev_flow *netdev_flow, } } +/* Converts to the dpif_flow format, using 'key_buf' and 'mask_buf' for + * storing the netlink-formatted key/mask. 'key_buf' may be the same as + * 'mask_buf'. Actions will be returned without copying, by relying on RCU to + * protect them. */ static void -dp_netdev_flow_to_dpif_flow(const struct dp_netdev_flow *netdev_flow, - struct ofpbuf *buffer, struct dpif_flow *flow) +dp_netdev_flow_to_dpif_flow(const struct dpif *dpif, + const struct dp_netdev_flow *netdev_flow, + struct ofpbuf *key_buf, struct ofpbuf *mask_buf, + struct dpif_flow *flow) { struct flow_wildcards wc; struct dp_netdev_actions *actions; + size_t offset; miniflow_expand(&netdev_flow->cr.mask->mf, &wc.masks); - odp_flow_key_from_mask(buffer, &wc.masks, &netdev_flow->flow, + + /* Key */ + offset = ofpbuf_size(key_buf); + flow->key = ofpbuf_tail(key_buf); + odp_flow_key_from_flow(key_buf, &netdev_flow->flow, &wc.masks, + netdev_flow->flow.in_port.odp_port, true); + flow->key_len = ofpbuf_size(key_buf) - offset; + + /* Mask */ + offset = ofpbuf_size(mask_buf); + flow->mask = ofpbuf_tail(mask_buf); + odp_flow_key_from_mask(mask_buf, &wc.masks, &netdev_flow->flow, odp_to_u32(wc.masks.in_port.odp_port), SIZE_MAX, true); - flow->mask = ofpbuf_data(buffer); - flow->mask_len = ofpbuf_size(buffer); + flow->mask_len = ofpbuf_size(mask_buf) - offset; + /* Actions */ actions = dp_netdev_flow_get_actions(netdev_flow); flow->actions = actions->actions; flow->actions_len = actions->size; + dpif_flow_hash(dpif, &netdev_flow->flow, sizeof netdev_flow->flow, + &flow->ufid); get_dpif_flow_stats(netdev_flow, &flow->stats); } @@ -1692,7 +1712,8 @@ dpif_netdev_flow_get(const struct dpif *dpif, const struct dpif_flow_get *get) netdev_flow = dp_netdev_find_flow(dp, &key); if (netdev_flow) { - dp_netdev_flow_to_dpif_flow(netdev_flow, get->buffer, get->flow); + dp_netdev_flow_to_dpif_flow(dpif, netdev_flow, get->buffer, + get->buffer, get->flow); } else { error = ENOENT; } @@ -1969,34 +1990,11 @@ dpif_netdev_flow_dump_next(struct dpif_flow_dump_thread *thread_, struct odputil_keybuf *keybuf = &thread->keybuf[i]; struct dp_netdev_flow *netdev_flow = netdev_flows[i]; struct dpif_flow *f = &flows[i]; - struct dp_netdev_actions *dp_actions; - struct flow_wildcards wc; - struct ofpbuf buf; + struct ofpbuf key, mask; - miniflow_expand(&netdev_flow->cr.mask->mf, &wc.masks); - - /* Key. */ - ofpbuf_use_stack(&buf, keybuf, sizeof *keybuf); - odp_flow_key_from_flow(&buf, &netdev_flow->flow, &wc.masks, - netdev_flow->flow.in_port.odp_port, true); - f->key = ofpbuf_data(&buf); - f->key_len = ofpbuf_size(&buf); - - /* Mask. */ - ofpbuf_use_stack(&buf, maskbuf, sizeof *maskbuf); - odp_flow_key_from_mask(&buf, &wc.masks, &netdev_flow->flow, - odp_to_u32(wc.masks.in_port.odp_port), - SIZE_MAX, true); - f->mask = ofpbuf_data(&buf); - f->mask_len = ofpbuf_size(&buf); - - /* Actions. */ - dp_actions = dp_netdev_flow_get_actions(netdev_flow); - f->actions = dp_actions->actions; - f->actions_len = dp_actions->size; - - /* Stats. */ - get_dpif_flow_stats(netdev_flow, &f->stats); + ofpbuf_use_stack(&key, keybuf, sizeof *keybuf); + ofpbuf_use_stack(&mask, maskbuf, sizeof *maskbuf); + dp_netdev_flow_to_dpif_flow(&dpif->dpif, netdev_flow, &key, &mask, f); } return n_flows; @@ -2621,7 +2619,7 @@ dp_netdev_count_packet(struct dp_netdev *dp, enum dp_stat_type type, int cnt) static int dp_netdev_upcall(struct dp_netdev *dp, struct dpif_packet *packet_, - struct flow *flow, struct flow_wildcards *wc, + struct flow *flow, struct flow_wildcards *wc, ovs_u128 *ufid, enum dpif_upcall_type type, const struct nlattr *userdata, struct ofpbuf *actions, struct ofpbuf *put_actions) { @@ -2657,7 +2655,7 @@ dp_netdev_upcall(struct dp_netdev *dp, struct dpif_packet *packet_, ds_destroy(&ds); } - return dp->upcall_cb(packet, flow, type, userdata, actions, wc, + return dp->upcall_cb(packet, flow, ufid, type, userdata, actions, wc, put_actions, dp->upcall_aux); } @@ -2842,6 +2840,7 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd, if (OVS_UNLIKELY(any_miss) && !fat_rwlock_tryrdlock(&dp->upcall_rwlock)) { uint64_t actions_stub[512 / 8], slow_stub[512 / 8]; struct ofpbuf actions, put_actions; + ovs_u128 ufid; ofpbuf_use_stub(&actions, actions_stub, sizeof actions_stub); ofpbuf_use_stub(&put_actions, slow_stub, sizeof slow_stub); @@ -2870,8 +2869,9 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd, ofpbuf_clear(&actions); ofpbuf_clear(&put_actions); + dpif_flow_hash(dp->dpif, &match.flow, sizeof match.flow, &ufid); error = dp_netdev_upcall(dp, packets[i], &match.flow, &match.wc, - DPIF_UC_MISS, NULL, &actions, + &ufid, DPIF_UC_MISS, NULL, &actions, &put_actions); if (OVS_UNLIKELY(error && error != ENOSPC)) { continue; @@ -3100,6 +3100,7 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt, const struct nlattr *userdata; struct ofpbuf actions; struct flow flow; + ovs_u128 ufid; userdata = nl_attr_find_nested(a, OVS_USERSPACE_ATTR_USERDATA); ofpbuf_init(&actions, 0); @@ -3110,8 +3111,9 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt, ofpbuf_clear(&actions); flow_extract(&packets[i]->ofpbuf, &packets[i]->md, &flow); - error = dp_netdev_upcall(dp, packets[i], &flow, NULL, - DPIF_UC_ACTION, userdata, &actions, + dpif_flow_hash(dp->dpif, &flow, sizeof flow, &ufid); + error = dp_netdev_upcall(dp, packets[i], &flow, NULL, &ufid, + DPIF_UC_ACTION, userdata,&actions, NULL); if (!error || error == ENOSPC) { dp_netdev_execute_actions(pmd, &packets[i], 1, may_steal, diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index d90fdd9e9..6c0cc0746 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -133,7 +133,7 @@ static int dpif_netlink_flow_transact(struct dpif_netlink_flow *request, struct ofpbuf **bufp); static void dpif_netlink_flow_get_stats(const struct dpif_netlink_flow *, struct dpif_flow_stats *); -static void dpif_netlink_flow_to_dpif_flow(struct dpif_flow *, +static void dpif_netlink_flow_to_dpif_flow(struct dpif *, struct dpif_flow *, const struct dpif_netlink_flow *); /* One of the dpif channels between the kernel and userspace. */ @@ -1364,7 +1364,7 @@ dpif_netlink_flow_dump_thread_destroy(struct dpif_flow_dump_thread *thread_) } static void -dpif_netlink_flow_to_dpif_flow(struct dpif_flow *dpif_flow, +dpif_netlink_flow_to_dpif_flow(struct dpif *dpif, struct dpif_flow *dpif_flow, const struct dpif_netlink_flow *datapath_flow) { dpif_flow->key = datapath_flow->key; @@ -1373,6 +1373,8 @@ dpif_netlink_flow_to_dpif_flow(struct dpif_flow *dpif_flow, dpif_flow->mask_len = datapath_flow->mask_len; dpif_flow->actions = datapath_flow->actions; dpif_flow->actions_len = datapath_flow->actions_len; + dpif_flow_hash(dpif, datapath_flow->key, datapath_flow->key_len, + &dpif_flow->ufid); dpif_netlink_flow_get_stats(datapath_flow, &dpif_flow->stats); } @@ -1410,7 +1412,8 @@ dpif_netlink_flow_dump_next(struct dpif_flow_dump_thread *thread_, if (datapath_flow.actions) { /* Common case: the flow includes actions. */ - dpif_netlink_flow_to_dpif_flow(&flows[n_flows++], &datapath_flow); + dpif_netlink_flow_to_dpif_flow(&dpif->dpif, &flows[n_flows++], + &datapath_flow); } else { /* Rare case: the flow does not include actions. Retrieve this * individual flow again to get the actions. */ @@ -1429,7 +1432,8 @@ dpif_netlink_flow_dump_next(struct dpif_flow_dump_thread *thread_, /* Save this flow. Then exit, because we only have one buffer to * handle this case. */ - dpif_netlink_flow_to_dpif_flow(&flows[n_flows++], &datapath_flow); + dpif_netlink_flow_to_dpif_flow(&dpif->dpif, &flows[n_flows++], + &datapath_flow); break; } } @@ -1600,7 +1604,8 @@ dpif_netlink_operate__(struct dpif_netlink *dpif, op->error = dpif_netlink_flow_from_ofpbuf(&reply, txn->reply); if (!op->error) { - dpif_netlink_flow_to_dpif_flow(get->flow, &reply); + dpif_netlink_flow_to_dpif_flow(&dpif->dpif, get->flow, + &reply); } } break; @@ -1853,8 +1858,8 @@ dpif_netlink_queue_to_priority(const struct dpif *dpif OVS_UNUSED, } static int -parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall, - int *dp_ifindex) +parse_odp_packet(const struct dpif_netlink *dpif, struct ofpbuf *buf, + struct dpif_upcall *upcall, int *dp_ifindex) { static const struct nl_policy ovs_packet_policy[] = { /* Always present. */ @@ -1898,6 +1903,7 @@ parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall, upcall->key = CONST_CAST(struct nlattr *, nl_attr_get(a[OVS_PACKET_ATTR_KEY])); upcall->key_len = nl_attr_get_size(a[OVS_PACKET_ATTR_KEY]); + dpif_flow_hash(&dpif->dpif, upcall->key, upcall->key_len, &upcall->ufid); upcall->userdata = a[OVS_PACKET_ATTR_USERDATA]; upcall->out_tun_key = a[OVS_PACKET_ATTR_EGRESS_TUN_KEY]; @@ -2046,7 +2052,7 @@ dpif_netlink_recv__(struct dpif_netlink *dpif, uint32_t handler_id, return error; } - error = parse_odp_packet(buf, upcall, &dp_ifindex); + error = parse_odp_packet(dpif, buf, upcall, &dp_ifindex); if (!error && dp_ifindex == dpif->dp_ifindex) { return 0; } else if (error) { diff --git a/lib/dpif.c b/lib/dpif.c index d6de5a1b3..e39d7cde8 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -831,6 +831,21 @@ dpif_flow_stats_format(const struct dpif_flow_stats *stats, struct ds *s) } } +/* Places the hash of the 'key_len' bytes starting at 'key' into '*hash'. */ +void +dpif_flow_hash(const struct dpif *dpif OVS_UNUSED, + const void *key, size_t key_len, ovs_u128 *hash) +{ + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; + static uint32_t secret; + + if (ovsthread_once_start(&once)) { + secret = random_uint32(); + ovsthread_once_done(&once); + } + hash_bytes128(key, key_len, secret, hash); +} + /* Deletes all flows from 'dpif'. Returns 0 if successful, otherwise a * positive errno value. */ int diff --git a/lib/dpif.h b/lib/dpif.h index 598e609ae..9e49b2040 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -515,6 +515,8 @@ enum dpif_flow_put_flags { DPIF_FP_PROBE = 1 << 3 /* Suppress error messages, if any. */ }; +void dpif_flow_hash(const struct dpif *, const void *key, size_t key_len, + ovs_u128 *hash); int dpif_flow_flush(struct dpif *); int dpif_flow_put(struct dpif *, enum dpif_flow_put_flags, const struct nlattr *key, size_t key_len, @@ -571,6 +573,7 @@ struct dpif_flow { size_t mask_len; /* 'mask' length in bytes. */ const struct nlattr *actions; /* Actions, as OVS_ACTION_ATTR_ */ size_t actions_len; /* 'actions' length in bytes. */ + ovs_u128 ufid; /* Unique flow identifier. */ struct dpif_flow_stats stats; /* Flow statistics. */ }; int dpif_flow_dump_next(struct dpif_flow_dump_thread *, @@ -735,6 +738,7 @@ struct dpif_upcall { struct ofpbuf packet; /* Packet data. */ struct nlattr *key; /* Flow key. */ size_t key_len; /* Length of 'key' in bytes. */ + ovs_u128 ufid; /* Unique flow identifier for 'key'. */ /* DPIF_UC_ACTION only. */ struct nlattr *userdata; /* Argument to OVS_ACTION_ATTR_USERSPACE. */ @@ -743,9 +747,9 @@ struct dpif_upcall { /* A callback to process an upcall, currently implemented only by dpif-netdev. * - * The caller provides the 'packet' and 'flow' to process, the 'type' of the - * upcall, and if 'type' is DPIF_UC_ACTION then the 'userdata' attached to the - * action. + * The caller provides the 'packet' and 'flow' to process, the corresponding + * 'ufid' as generated by dpif_flow_hash(), the 'type' of the upcall, and if + * 'type' is DPIF_UC_ACTION then the 'userdata' attached to the action. * * The callback must fill in 'actions' with the datapath actions to apply to * 'packet'. 'wc' and 'put_actions' will either be both null or both nonnull. @@ -760,6 +764,7 @@ struct dpif_upcall { * flow should be installed, or some otherwise a positive errno value. */ typedef int upcall_callback(const struct ofpbuf *packet, const struct flow *flow, + ovs_u128 *ufid, enum dpif_upcall_type type, const struct nlattr *userdata, struct ofpbuf *actions, diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 9b8f8a043..0b1b597de 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -99,8 +99,6 @@ struct udpif { struct dpif *dpif; /* Datapath handle. */ struct dpif_backer *backer; /* Opaque dpif_backer pointer. */ - uint32_t secret; /* Random seed for upcall hash. */ - struct handler *handlers; /* Upcall handlers. */ size_t n_handlers; @@ -158,6 +156,7 @@ struct upcall { * dpif-netdev. If a modification is absolutely necessary, a const cast * may be used with other datapaths. */ const struct flow *flow; /* Parsed representation of the packet. */ + const ovs_u128 *ufid; /* Unique identifier for 'flow'. */ const struct ofpbuf *packet; /* Packet associated with this upcall. */ ofp_port_t in_port; /* OpenFlow in port, or OFPP_NONE. */ @@ -208,6 +207,7 @@ struct udpif_key { const struct nlattr *mask; /* Datapath flow mask. */ size_t mask_len; /* Length of 'mask'. */ struct ofpbuf *actions; /* Datapath flow actions as nlattrs. */ + ovs_u128 ufid; /* Unique flow identifier. */ uint32_t hash; /* Pre-computed hash for 'key'. */ struct ovs_mutex mutex; /* Guards the following. */ @@ -263,15 +263,14 @@ static void upcall_unixctl_dump_wait(struct unixctl_conn *conn, int argc, static void upcall_unixctl_purge(struct unixctl_conn *conn, int argc, const char *argv[], void *aux); -static struct udpif_key *ukey_create_from_upcall(const struct udpif *, - const struct upcall *); +static struct udpif_key *ukey_create_from_upcall(const struct upcall *); static struct udpif_key *ukey_create_from_dpif_flow(const struct udpif *, const struct dpif_flow *); static bool ukey_install_start(struct udpif *, struct udpif_key *ukey); static bool ukey_install_finish(struct udpif_key *ukey, int error); static bool ukey_install(struct udpif *udpif, struct udpif_key *ukey); -static struct udpif_key *ukey_lookup(struct udpif *udpif, uint32_t hash, - const struct nlattr *key, size_t key_len); +static struct udpif_key *ukey_lookup(struct udpif *udpif, + const ovs_u128 *ufid); static int ukey_acquire(struct udpif *, const struct dpif_flow *, struct udpif_key **result); static void ukey_delete__(struct udpif_key *); @@ -281,7 +280,8 @@ static enum upcall_type classify_upcall(enum dpif_upcall_type type, static int upcall_receive(struct upcall *, const struct dpif_backer *, const struct ofpbuf *packet, enum dpif_upcall_type, - const struct nlattr *userdata, const struct flow *); + const struct nlattr *userdata, const struct flow *, + const ovs_u128 *ufid); static void upcall_uninit(struct upcall *); static upcall_callback upcall_cb; @@ -313,7 +313,6 @@ udpif_create(struct dpif_backer *backer, struct dpif *dpif) udpif->dpif = dpif; udpif->backer = backer; atomic_init(&udpif->flow_limit, MIN(ofproto_flow_limit, 10000)); - udpif->secret = random_uint32(); udpif->reval_seq = seq_create(); udpif->dump_seq = seq_create(); latch_init(&udpif->exit_latch); @@ -637,7 +636,8 @@ recv_upcalls(struct handler *handler) } error = upcall_receive(upcall, udpif->backer, &dupcall->packet, - dupcall->type, dupcall->userdata, flow); + dupcall->type, dupcall->userdata, flow, + &dupcall->ufid); if (error) { if (error == ENODEV) { /* Received packet on datapath port for which we couldn't @@ -654,6 +654,7 @@ recv_upcalls(struct handler *handler) upcall->key = dupcall->key; upcall->key_len = dupcall->key_len; + upcall->ufid = &dupcall->ufid; upcall->out_tun_key = dupcall->out_tun_key; @@ -861,7 +862,8 @@ compose_slow_path(struct udpif *udpif, struct xlate_out *xout, static int upcall_receive(struct upcall *upcall, const struct dpif_backer *backer, const struct ofpbuf *packet, enum dpif_upcall_type type, - const struct nlattr *userdata, const struct flow *flow) + const struct nlattr *userdata, const struct flow *flow, + const ovs_u128 *ufid) { int error; @@ -873,6 +875,7 @@ upcall_receive(struct upcall *upcall, const struct dpif_backer *backer, upcall->flow = flow; upcall->packet = packet; + upcall->ufid = ufid; upcall->type = type; upcall->userdata = userdata; ofpbuf_init(&upcall->put_actions, 0); @@ -955,7 +958,7 @@ upcall_xlate(struct udpif *udpif, struct upcall *upcall, &upcall->put_actions); } - upcall->ukey = ukey_create_from_upcall(udpif, upcall); + upcall->ukey = ukey_create_from_upcall(upcall); } static void @@ -973,7 +976,7 @@ upcall_uninit(struct upcall *upcall) } static int -upcall_cb(const struct ofpbuf *packet, const struct flow *flow, +upcall_cb(const struct ofpbuf *packet, const struct flow *flow, ovs_u128 *ufid, enum dpif_upcall_type type, const struct nlattr *userdata, struct ofpbuf *actions, struct flow_wildcards *wc, struct ofpbuf *put_actions, void *aux) @@ -988,7 +991,7 @@ upcall_cb(const struct ofpbuf *packet, const struct flow *flow, atomic_read_relaxed(&udpif->flow_limit, &flow_limit); error = upcall_receive(&upcall, udpif->backer, packet, type, userdata, - flow); + flow, ufid); if (error) { return error; } @@ -1156,6 +1159,7 @@ handle_upcalls(struct udpif *udpif, struct upcall *upcalls, upcall->ukey_persists = true; op = &ops[n_ops++]; + op->ukey = ukey; op->dop.type = DPIF_OP_FLOW_PUT; op->dop.u.flow_put.flags = DPIF_FP_CREATE; @@ -1210,15 +1214,21 @@ handle_upcalls(struct udpif *udpif, struct upcall *upcalls, } } +static uint32_t +get_ufid_hash(const ovs_u128 *ufid) +{ + return ufid->u32[0]; +} + static struct udpif_key * -ukey_lookup(struct udpif *udpif, uint32_t hash, const struct nlattr *key, - size_t key_len) +ukey_lookup(struct udpif *udpif, const ovs_u128 *ufid) { struct udpif_key *ukey; - struct cmap *cmap = &udpif->ukeys[hash % N_UMAPS].cmap; + int idx = get_ufid_hash(ufid) % N_UMAPS; + struct cmap *cmap = &udpif->ukeys[idx].cmap; - CMAP_FOR_EACH_WITH_HASH (ukey, cmap_node, hash, cmap) { - if (ukey->key_len == key_len && !memcmp(ukey->key, key, key_len)) { + CMAP_FOR_EACH_WITH_HASH (ukey, cmap_node, get_ufid_hash(ufid), cmap) { + if (ovs_u128_equal(&ukey->ufid, ufid)) { return ukey; } } @@ -1226,10 +1236,9 @@ ukey_lookup(struct udpif *udpif, uint32_t hash, const struct nlattr *key, } static struct udpif_key * -ukey_create__(const struct udpif *udpif, - const struct nlattr *key, size_t key_len, +ukey_create__(const struct nlattr *key, size_t key_len, const struct nlattr *mask, size_t mask_len, - const struct ofpbuf *actions, + const ovs_u128 *ufid, const struct ofpbuf *actions, uint64_t dump_seq, uint64_t reval_seq, long long int used) OVS_NO_THREAD_SAFETY_ANALYSIS { @@ -1241,7 +1250,8 @@ ukey_create__(const struct udpif *udpif, memcpy(&ukey->maskbuf, mask, mask_len); ukey->mask = &ukey->maskbuf.nla; ukey->mask_len = mask_len; - ukey->hash = hash_bytes(ukey->key, ukey->key_len, udpif->secret); + ukey->ufid = *ufid; + ukey->hash = get_ufid_hash(&ukey->ufid); ukey->actions = ofpbuf_clone(actions); ovs_mutex_init(&ukey->mutex); @@ -1257,7 +1267,7 @@ ukey_create__(const struct udpif *udpif, } static struct udpif_key * -ukey_create_from_upcall(const struct udpif *udpif, const struct upcall *upcall) +ukey_create_from_upcall(const struct upcall *upcall) { struct odputil_keybuf keystub, maskstub; struct ofpbuf keybuf, maskbuf; @@ -1284,9 +1294,9 @@ ukey_create_from_upcall(const struct udpif *udpif, const struct upcall *upcall) UINT32_MAX, max_mpls, recirc); } - return ukey_create__(udpif, ofpbuf_data(&keybuf), ofpbuf_size(&keybuf), + return ukey_create__(ofpbuf_data(&keybuf), ofpbuf_size(&keybuf), ofpbuf_data(&maskbuf), ofpbuf_size(&maskbuf), - &upcall->put_actions, upcall->dump_seq, + upcall->ufid, &upcall->put_actions, upcall->dump_seq, upcall->reval_seq, 0); } @@ -1300,8 +1310,8 @@ ukey_create_from_dpif_flow(const struct udpif *udpif, dump_seq = seq_read(udpif->dump_seq); reval_seq = seq_read(udpif->reval_seq); ofpbuf_use_const(&actions, &flow->actions, flow->actions_len); - return ukey_create__(udpif, flow->key, flow->key_len, - flow->mask, flow->mask_len, &actions, + return ukey_create__(flow->key, flow->key_len, + flow->mask, flow->mask_len, &flow->ufid, &actions, dump_seq, reval_seq, flow->stats.used); } @@ -1321,8 +1331,7 @@ ukey_install_start(struct udpif *udpif, struct udpif_key *new_ukey) idx = new_ukey->hash % N_UMAPS; umap = &udpif->ukeys[idx]; ovs_mutex_lock(&umap->mutex); - old_ukey = ukey_lookup(udpif, new_ukey->hash, new_ukey->key, - new_ukey->key_len); + old_ukey = ukey_lookup(udpif, &new_ukey->ufid); if (old_ukey) { /* Uncommon case: A ukey is already installed with the same UFID. */ if (old_ukey->key_len == new_ukey->key_len @@ -1393,11 +1402,9 @@ ukey_acquire(struct udpif *udpif, const struct dpif_flow *flow, OVS_TRY_LOCK(true, (*result)->mutex) { struct udpif_key *ukey; - uint32_t hash; bool locked = false; - hash = hash_bytes(flow->key, flow->key_len, udpif->secret); - ukey = ukey_lookup(udpif, hash, flow->key, flow->key_len); + ukey = ukey_lookup(udpif, &flow->ufid); if (ukey) { if (!ovs_mutex_trylock(&ukey->mutex)) { locked = true;