2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +00:00

dpif: Generate flow_hash for revalidators in dpif.

This patch shifts the responsibility for determining the hash for a flow
from the revalidation logic down to the dpif layer. This assists in
handling backward-compatibility for revalidation with the upcoming
unique flow identifier "UFID" patches.

A 128-bit UFID was selected to minimize the likelihood of hash conflicts.
Handler threads will not install a flow that has an identical UFID as
another flow, to prevent misattribution of stats and to ensure that the
correct flow key cache is used for revalidation.

For datapaths that do not support UFID, which is currently all
datapaths, the dpif will generate the UFID and pass it up during upcall
and flow_dump. This is generated based on the datapath flow key.

Later patches will add support for datapaths to store and interpret this
UFID, in which case the dpif has a responsibility to pass it through
transparently.

Signed-off-by: Joe Stringer <joestringer@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Joe Stringer
2014-09-24 15:24:39 +12:00
parent 468cdd91c3
commit 7af12bd7c8
5 changed files with 116 additions and 81 deletions

View File

@@ -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) {