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:
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user