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

nx-match: Add parsing and serialisation of OXM matches.

This code, which leverages the existing NXM implementation,
adds parsing and serialisation of OXM matches. Test cases
have also been provided.

This patch only implements parsing and serialisation of OXM fields that
are already handled by NXM.

It should be noted that in OXM ports are 32bit whereas in NXM they
are 16 bit. This has been handled as a special case as all other field
widths are the same in both OXM and NXM.

This patch does not address differences in wildcarding between OXM and NXM.
It is planned that liberal wildcarding policy dictated by either OXM or
NXM will be implemented.

This patch also does not address any (subtle?) differences between
OXM and NXM treatment of specific fields. It is envisages that his
can be handled by subsequent patches.

Signed-off-by: Simon Horman <horms@verge.net.au>
[blp@nicira.com adjusted style, added a comment, changed in_port special
 case, enabled NXM extensions to OXM]
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Simon Horman
2012-06-11 09:56:12 -07:00
committed by Ben Pfaff
parent a9c34071ed
commit b5ae8913b2
7 changed files with 456 additions and 77 deletions

View File

@@ -441,6 +441,7 @@ struct nxm_field {
};
static struct hmap all_nxm_fields = HMAP_INITIALIZER(&all_nxm_fields);
static struct hmap all_oxm_fields = HMAP_INITIALIZER(&all_oxm_fields);
/* Rate limit for parse errors. These always indicate a bug in an OpenFlow
* controller and so there's not much point in showing a lot of them. */
@@ -476,40 +477,70 @@ mf_from_name(const char *name)
}
static void
add_nxm_field(uint32_t nxm_header, const struct mf_field *mf)
add_nxm_field(struct hmap *all_fields, uint32_t nxm_header,
const struct mf_field *mf)
{
struct nxm_field *f;
f = xmalloc(sizeof *f);
hmap_insert(&all_nxm_fields, &f->hmap_node, hash_int(nxm_header, 0));
hmap_insert(all_fields, &f->hmap_node, hash_int(nxm_header, 0));
f->nxm_header = nxm_header;
f->mf = mf;
}
static struct hmap *
get_all_fields(uint32_t header)
{
return IS_OXM_HEADER(header) ? &all_oxm_fields : &all_nxm_fields;
}
static void
nxm_init_add_field(const struct mf_field *mf, uint32_t header)
{
struct hmap *all_fields = get_all_fields(header);
if (!header) {
return;
}
add_nxm_field(all_fields, header, mf);
if (mf->maskable == MFM_NONE) {
return;
}
add_nxm_field(all_fields, NXM_MAKE_WILD_HEADER(header), mf);
}
#ifndef NDEBUG
static void
nxm_init_verify_field(const struct mf_field *mf, uint32_t header)
{
if (!header) {
return;
}
assert(mf_from_nxm_header(header) == mf);
/* Some OXM fields are not maskable while their NXM
* counterparts are, just skip this check for now */
if (mf->maskable == MFM_NONE || IS_OXM_HEADER(header)) {
return;
}
assert(mf_from_nxm_header(NXM_MAKE_WILD_HEADER(mf->nxm_header)) == mf);
}
#endif
static void
nxm_init(void)
{
const struct mf_field *mf;
for (mf = mf_fields; mf < &mf_fields[MFF_N_IDS]; mf++) {
if (mf->nxm_header) {
add_nxm_field(mf->nxm_header, mf);
if (mf->maskable != MFM_NONE) {
add_nxm_field(NXM_MAKE_WILD_HEADER(mf->nxm_header), mf);
}
}
nxm_init_add_field(mf, mf->nxm_header);
nxm_init_add_field(mf, mf->oxm_header);
}
#ifndef NDEBUG
/* Verify that the header values are unique. */
for (mf = mf_fields; mf < &mf_fields[MFF_N_IDS]; mf++) {
if (mf->nxm_header) {
assert(mf_from_nxm_header(mf->nxm_header) == mf);
if (mf->maskable != MFM_NONE) {
assert(mf_from_nxm_header(NXM_MAKE_WILD_HEADER(mf->nxm_header))
== mf);
}
}
nxm_init_verify_field(mf, mf->nxm_header);
nxm_init_verify_field(mf, mf->oxm_header);
}
#endif
}
@@ -518,13 +549,13 @@ const struct mf_field *
mf_from_nxm_header(uint32_t header)
{
const struct nxm_field *f;
struct hmap *all_fields = get_all_fields(header);
if (hmap_is_empty(&all_nxm_fields)) {
if (hmap_is_empty(all_fields)) {
nxm_init();
}
HMAP_FOR_EACH_IN_BUCKET (f, hmap_node, hash_int(header, 0),
&all_nxm_fields) {
HMAP_FOR_EACH_IN_BUCKET (f, hmap_node, hash_int(header, 0), all_fields) {
if (f->nxm_header == header) {
return f->mf;
}