Skip to content

Commit

Permalink
dpif-netdev: Don't use metaflow to operate on userspace datapath fields.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jessegross committed Aug 6, 2015
1 parent 18fd3a5 commit 9f861c9
Showing 1 changed file with 5 additions and 27 deletions.
32 changes: 5 additions & 27 deletions lib/dpif-netdev.c
Expand Up @@ -31,6 +31,7 @@
#include <sys/stat.h>
#include <unistd.h>

#include "bitmap.h"
#include "cmap.h"
#include "csum.h"
#include "dp-packet.h"
Expand All @@ -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"
Expand Down Expand Up @@ -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()
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 9f861c9

Please sign in to comment.