* value, called "nxm_mask". For each 1-bit in position J in nxm_mask, the
* nx_match matches only packets for which bit J in the given field's value
* matches bit J in nxm_value. A 0-bit in nxm_mask causes the
- * corresponding bits in nxm_value and the field's value to be ignored.
- * (The sense of the nxm_mask bits is the opposite of that used by the
- * "wildcards" member of struct ofp10_match.)
+ * corresponding bit in nxm_value is ignored (it should be 0; Open vSwitch
+ * may enforce this someday), as is the corresponding bit in the field's
+ * value. (The sense of the nxm_mask bits is the opposite of that used by
+ * the "wildcards" member of struct ofp10_match.)
*
* When nxm_hasmask is 1, nxm_length is always even.
*
return header;
}
+/* Given NXM/OXM value 'value' and mask 'mask', each 'width' bytes long,
+ * checks for any 1-bit in the value where there is a 0-bit in the mask. If it
+ * finds one, logs a warning. */
+static void
+check_mask_consistency(const uint8_t *p, const struct mf_field *mf)
+{
+ unsigned int width = mf->n_bytes;
+ const uint8_t *value = p + 4;
+ const uint8_t *mask = p + 4 + width;
+ unsigned int i;
+
+ for (i = 0; i < width; i++) {
+ if (value[i] & ~mask[i]) {
+ if (!VLOG_DROP_WARN(&rl)) {
+ char *s = nx_match_to_string(p, width * 2 + 4);
+ VLOG_WARN_RL(&rl, "NXM/OXM entry %s has 1-bits in value for "
+ "bits wildcarded by the mask. (Future versions "
+ "of OVS may report this as an OpenFlow error.)",
+ s);
+ break;
+ }
+ }
+ }
+}
+
static enum ofperr
nx_pull_raw(const uint8_t *p, unsigned int match_len, bool strict,
struct match *match, ovs_be64 *cookie, ovs_be64 *cookie_mask)
error = OFPERR_OFPBMC_BAD_MASK;
} else {
error = 0;
+ check_mask_consistency(p, mf);
mf_set(mf, &value, &mask, match);
}
}
00011e04(12345678)
00011f08(12345678/12345678)
])
-AT_CHECK([ovs-ofctl --strict parse-nx-match < nx-match.txt], [0], [dnl
+AT_CHECK([ovs-ofctl -vPATTERN:'console:%c|%p|%m' --strict parse-nx-match < nx-match.txt], [0], [dnl
<any>
# in port
NXM_NX_REG0_W(12345678/12345678)
nx_pull_match() returned error OFPBMC_BAD_FIELD
nx_pull_match() returned error OFPBMC_BAD_FIELD
+], [stderr])
+
+# Check that at least the first warning made it. (It's rate-limited
+# so a variable number could show up, especially under valgrind etc.)
+AT_CHECK([grep 'has 1-bits in value' stderr | sed 1q], [0], [dnl
+nx_match|WARN|NXM/OXM entry NXM_OF_ETH_DST_W(ffffffffffff/010000000000) has 1-bits in value for bits wildcarded by the mask. (Future versions of OVS may report this as an OpenFlow error.)
])
+
+# Check that there wasn't any other stderr output.
+AT_CHECK([grep -v 'has 1-bits in value' stderr], [1])
AT_CLEANUP
AT_SETUP([ovs-ofctl parse-ofp10-match])
# Invalid field number.
01020304(1111/2222)
])
-AT_CHECK([ovs-ofctl --strict parse-oxm < oxm.txt], [0], [dnl
+AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' --strict parse-oxm < oxm.txt],
+ [0], [dnl
<any>
# in port
# Invalid field number.
nx_pull_match() returned error OFPBMC_BAD_FIELD
+], [stderr])
+
+# Check that at least the first warning made it. (It's rate-limited
+# so a variable number could show up, especially under valgrind etc.)
+AT_CHECK([grep 'has 1-bits in value' stderr | sed 1q], [0], [dnl
+nx_match|WARN|NXM/OXM entry OXM_OF_METADATA_W(1234567890abcdef/ffff0000ffff0000) has 1-bits in value for bits wildcarded by the mask. (Future versions of OVS may report this as an OpenFlow error.)
])
+
+# Check that there wasn't any other stderr output.
+AT_CHECK([grep -v 'has 1-bits in value' stderr], [1])
AT_CLEANUP
AT_SETUP([ovs-ofctl parse-oxm loose])