Mask values in a match according to its masks

A step towards match canonicalization.  When generating a match
structure, clear the bits outside of those indicated by the
masks.  Changes to test code to make consistent.

For 1.0, need only worry about IPv4 addrs.  Otherwise, use a simple
loop to iterative over bytes in the match.
diff --git a/c_gen/c_match.py b/c_gen/c_match.py
index 8befb3f..7353ae7 100644
--- a/c_gen/c_match.py
+++ b/c_gen/c_match.py
@@ -178,6 +178,18 @@
 } of_match_t;
 
 /**
+ * Mask the values in the match structure according to its fields
+ */
+static inline void of_match_values_mask(of_match_t *match)
+{
+    int idx;
+
+    for (idx = 0; idx < sizeof(of_match_fields_t); idx++) {
+        ((uint8_t *)&match->fields)[idx] &= ((uint8_t *)&match->masks)[idx];
+    }
+}
+
+/**
  * IP Mask map.  IP maks wildcards from OF 1.0 are interpretted as
  * indices into the map below.
  *
@@ -682,26 +694,14 @@
 
     of_match_v1_wildcards_get(src, &wc);
 """)
-    # Deal with nw fields first
-    out.write("""
-    /* Handle L3 src and dst wildcarding first */
-    /* @fixme Check mask values are properly treated for ipv4 src/dst */
-    if ((count = OF_MATCH_V1_WC_IPV4_DST_GET(wc)) < 32) {
-        of_match_v1_ipv4_dst_get(src, &dst->fields.ipv4_dst);
-        if (count > 0) { /* Not exact match */
-            dst->masks.ipv4_dst = ~(((uint32_t)1 << count) - 1);
-        } else {
-            OF_MATCH_MASK_IPV4_DST_EXACT_SET(dst);
-        }
-    }
-""")
     for key in sorted(match.of_v1_keys):
         if key in ["ipv4_src", "ipv4_dst"]: # Special cases for masks here
             out.write("""
     count = OF_MATCH_V1_WC_%(ku)s_GET(wc);
     dst->masks.%(key)s = of_ip_index_to_mask(count);
-    /* @todo Review if we should only get the addr when masks.%(key)s != 0 */
     of_match_v1_%(key)s_get(src, &dst->fields.%(key)s);
+    /* Clear the bits not indicated by mask; IP addrs are special for 1.0 */
+    dst->fields.%(key)s &= dst->masks.%(key)s;
 """ % dict(ku=key.upper(), key=key))
         else:
             out.write("""
@@ -749,6 +749,9 @@
 """ % dict(ku=key.upper(), key=key))
 
     out.write("""
+    /* Clear values outside of masks */
+    of_match_values_mask(dst);
+
     return OF_ERROR_NONE;
 }
 """)
@@ -808,6 +811,9 @@
         rv = of_list_oxm_next(&oxm_list, &oxm_entry);
     } /* end OXM iteration */
 
+    /* Clear values outside of masks */
+    of_match_values_mask(dst);
+
     return OF_ERROR_NONE;
 }
 """)
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 14ab24e..fab9f96 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -261,6 +261,9 @@
         match->masks.ipv4_src = 0xffff0000;
         match->masks.ipv4_dst = 0xfffff800;
     }
+
+    /* Restrict values according to masks */
+    of_match_values_mask(match);
     return value;
 }