2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 06:15:47 +00:00

dpif-netdev: Don't use metaflow to operate on userspace datapath fields.

If ofproto-dpif installs a flow into the userspace datapath that doesn't
include a mask, we need to synthesize an exact match one. This is currently
done using the metaflow infrastructure, iterating over each field and
setting it to all ones.

There is a conceptual mismatch here because metaflow is operating on
OpenFlow fields, not datapath ones. Even though they are generally very
similar, there are subtle differences, which is why it is necessary to
fix up the input port mask.

With Geneve options, the mapping is much more complicated and so the
situation is worse. The first issue is that the metaflow to flow
mapping can change over time, so we would need to do more revalidation
to track this. In addition, an upcoming patch will completely disconnect
the option format between ofproto-dpif and dpif-netdev, so the values
written by metaflow don't make sense at all.

When megaflows are turned off, ofproto-dpif internally generates masks
using flow_wildcards_init_for_packet(). Since that's the same as what
we want to do here, we can just use that instead of metaflow.

Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
This commit is contained in:
Jesse Gross
2015-07-16 09:05:33 -07:00
parent 18fd3a521b
commit 9f861c9182

View File

@@ -31,6 +31,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include "bitmap.h"
#include "cmap.h"
#include "csum.h"
#include "dp-packet.h"
@@ -44,7 +45,6 @@
#include "latch.h"
#include "list.h"
#include "match.h"
#include "meta-flow.h"
#include "netdev.h"
#include "netdev-dpdk.h"
#include "netdev-vport.h"
@@ -1879,13 +1879,13 @@ static int
dpif_netdev_mask_from_nlattrs(const struct nlattr *key, uint32_t key_len,
const struct nlattr *mask_key,
uint32_t mask_key_len, const struct flow *flow,
struct flow *mask)
struct flow_wildcards *wc)
{
if (mask_key_len) {
enum odp_key_fitness fitness;
fitness = odp_flow_key_to_mask(mask_key, mask_key_len, key, key_len,
mask, flow);
&wc->masks, flow);
if (fitness) {
/* This should not happen: it indicates that
* odp_flow_key_from_mask() and odp_flow_key_to_mask()
@@ -1907,31 +1907,9 @@ dpif_netdev_mask_from_nlattrs(const struct nlattr *key, uint32_t key_len,
return EINVAL;
}
} else {
enum mf_field_id id;
/* No mask key, unwildcard everything except fields whose
* prerequisities are not met. */
memset(mask, 0x0, sizeof *mask);
for (id = 0; id < MFF_N_IDS; ++id) {
/* Skip registers and metadata. */
if (!(id >= MFF_REG0 && id < MFF_REG0 + FLOW_N_REGS)
&& !(id >= MFF_XREG0 && id < MFF_XREG0 + FLOW_N_XREGS)
&& id != MFF_METADATA) {
const struct mf_field *mf = mf_from_id(id);
if (mf_are_prereqs_ok(mf, flow)) {
mf_mask_field(mf, mask);
}
}
}
flow_wildcards_init_for_packet(wc, flow);
}
/* Force unwildcard the in_port.
*
* We need to do this even in the case where we unwildcard "everything"
* above because "everything" only includes the 16-bit OpenFlow port number
* mask->in_port.ofp_port, which only covers half of the 32-bit datapath
* port number mask->in_port.odp_port. */
mask->in_port.odp_port = u32_to_odp(UINT32_MAX);
return 0;
}
@@ -2069,7 +2047,7 @@ dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put)
}
error = dpif_netdev_mask_from_nlattrs(put->key, put->key_len,
put->mask, put->mask_len,
&match.flow, &match.wc.masks);
&match.flow, &match.wc);
if (error) {
return error;
}