NOT_REACHED();
}
+/* Set field and it's prerequisities in the mask.
+ * This is only ever called for writeable 'mf's, but we do not make the
+ * distinction here. */
+void
+mf_mask_field_and_prereqs(const struct mf_field *mf, struct flow *mask)
+{
+ static const union mf_value exact_match_mask = MF_EXACT_MASK_INITIALIZER;
+
+ mf_set_flow_value(mf, &exact_match_mask, mask);
+
+ switch (mf->prereqs) {
+ case MFP_ND:
+ case MFP_ND_SOLICIT:
+ case MFP_ND_ADVERT:
+ mask->tp_src = OVS_BE16_MAX;
+ mask->tp_dst = OVS_BE16_MAX;
+ /* Fall through. */
+ case MFP_TCP:
+ case MFP_UDP:
+ case MFP_SCTP:
+ case MFP_ICMPV4:
+ case MFP_ICMPV6:
+ mask->nw_proto = 0xff;
+ /* Fall through. */
+ case MFP_ARP:
+ case MFP_IPV4:
+ case MFP_IPV6:
+ case MFP_MPLS:
+ case MFP_IP_ANY:
+ mask->dl_type = OVS_BE16_MAX;
+ break;
+ case MFP_VLAN_VID:
+ mask->vlan_tci |= htons(VLAN_CFI);
+ break;
+ case MFP_NONE:
+ break;
+ }
+}
+
+
/* Returns true if 'value' may be a valid value *as part of a masked match*,
* false otherwise.
*
}
}
+/* Unwildcard 'mask' member field described by 'mf'. The caller is
+ * responsible for ensuring that 'mask' meets 'mf''s prerequisites. */
+void
+mf_mask_field(const struct mf_field *mf, struct flow *mask)
+{
+ static const union mf_value exact_match_mask = MF_EXACT_MASK_INITIALIZER;
+
+ /* For MFF_DL_VLAN, we cannot send a all 1's to flow_set_dl_vlan()
+ * as that will be considered as OFP10_VLAN_NONE. So consider it as a
+ * special case. For the rest, calling mf_set_flow_value() is good
+ * enough. */
+ if (mf->id == MFF_DL_VLAN) {
+ flow_set_dl_vlan(mask, htons(VLAN_VID_MASK));
+ } else {
+ mf_set_flow_value(mf, &exact_match_mask, mask);
+ }
+}
+
/* Sets 'flow' member field described by 'mf' to 'value'. The caller is
* responsible for ensuring that 'flow' meets 'mf''s prerequisites.*/
void