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;
}
""")