Skip to content

Commit

Permalink
nx-match: Support variable length header lookup.
Browse files Browse the repository at this point in the history
Currently we treat the entire NXM/OXM header, including length,
as an ID to define a field. However, this does not allow for
multiple lengths of a particular field.

If a field has been marked as variable, we should ignore the length
when looking up the field and only use the class and field. We
continue to use the length for non-variable fields to ensure that
we don't accept something that can never match.

Signed-off-by: Jesse Gross <[email protected]>
  • Loading branch information
jessegross committed Jun 25, 2015
1 parent f047e84 commit 899bb63
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions lib/nx-match.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ static int nxm_class(uint64_t header) { return header >> 48; }
static int nxm_field(uint64_t header) { return (header >> 41) & 0x7f; }
static bool nxm_hasmask(uint64_t header) { return (header >> 40) & 1; }
static int nxm_length(uint64_t header) { return (header >> 32) & 0xff; }
static uint64_t nxm_no_len(uint64_t header) { return header & 0xffffff80ffffffffULL; }

static bool
is_experimenter_oxm(uint64_t header)
Expand Down Expand Up @@ -1893,7 +1894,7 @@ nxm_init(void)
for (struct nxm_field_index *nfi = all_nxm_fields;
nfi < &all_nxm_fields[ARRAY_SIZE(all_nxm_fields)]; nfi++) {
hmap_insert(&nxm_header_map, &nfi->header_node,
hash_uint64(nfi->nf.header));
hash_uint64(nxm_no_len(nfi->nf.header)));
hmap_insert(&nxm_name_map, &nfi->name_node,
hash_string(nfi->nf.name, 0));
list_push_back(&nxm_mf_map[nfi->nf.id], &nfi->mf_node);
Expand All @@ -1906,16 +1907,24 @@ static const struct nxm_field *
nxm_field_by_header(uint64_t header)
{
const struct nxm_field_index *nfi;
uint64_t header_no_len;

nxm_init();
if (nxm_hasmask(header)) {
header = nxm_make_exact_header(header);
}

HMAP_FOR_EACH_IN_BUCKET (nfi, header_node, hash_uint64(header),
header_no_len = nxm_no_len(header);

HMAP_FOR_EACH_IN_BUCKET (nfi, header_node, hash_uint64(header_no_len),
&nxm_header_map) {
if (header == nfi->nf.header) {
return &nfi->nf;
if (header_no_len == nxm_no_len(nfi->nf.header)) {
if (nxm_length(header) == nxm_length(nfi->nf.header) ||
mf_from_id(nfi->nf.id)->variable_len) {
return &nfi->nf;
} else {
return NULL;
}
}
}
return NULL;
Expand Down

0 comments on commit 899bb63

Please sign in to comment.