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 <je...@nicira.com>
---
 lib/nx-match.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/lib/nx-match.c b/lib/nx-match.c
index 21f291c..f51af08 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -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 & 
0xffffff80ffffffff; }
 
 static bool
 is_experimenter_oxm(uint64_t header)
@@ -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_int(nfi->nf.header, 0));
+                        hash_int(nxm_no_len(nfi->nf.header), 0));
             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);
@@ -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_int(header, 0),
+    header_no_len = nxm_no_len(header);
+
+    HMAP_FOR_EACH_IN_BUCKET (nfi, header_node, hash_int(header_no_len, 0),
                              &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;
-- 
2.1.0

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to