#define WC_MASK_FIELD(WC, FIELD) \
memset(&(WC)->masks.FIELD, 0xff, sizeof (WC)->masks.FIELD)
+#define WC_MASK_FIELD_MASK(WC, FIELD, MASK) \
+ ((WC)->masks.FIELD |= (MASK))
#define WC_UNMASK_FIELD(WC, FIELD) \
memset(&(WC)->masks.FIELD, 0, sizeof (WC)->masks.FIELD)
/* 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.
+ * distinction here.
* The widest field this is ever called for an IPv6 address (16 bytes). */
void
-mf_mask_field_and_prereqs(const struct mf_field *mf, struct flow *mask)
+mf_mask_field_and_prereqs(const struct mf_field *mf, struct flow_wildcards *wc)
{
static union mf_value exact_match_mask = { .ipv6 = IN6ADDR_EXACT_INIT };
- mf_set_flow_value(mf, &exact_match_mask, mask);
+ mf_set_flow_value(mf, &exact_match_mask, &wc->masks);
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;
+ WC_MASK_FIELD(wc, tp_src);
+ WC_MASK_FIELD(wc, tp_dst);
/* Fall through. */
case MFP_TCP:
case MFP_UDP:
case MFP_ICMPV4:
case MFP_ICMPV6:
/* nw_frag always unwildcarded. */
- mask->nw_proto = 0xff;
+ WC_MASK_FIELD(wc, nw_proto);
/* Fall through. */
case MFP_ARP:
case MFP_IPV4:
case MFP_IPV6:
case MFP_MPLS:
case MFP_IP_ANY:
- mask->dl_type = OVS_BE16_MAX;
+ /* dl_type always unwildcarded. */
break;
case MFP_VLAN_VID:
- mask->vlan_tci |= htons(VLAN_CFI);
+ WC_MASK_FIELD_MASK(wc, vlan_tci, htons(VLAN_CFI));
break;
case MFP_NONE:
break;
/* Prerequisites. */
bool mf_are_prereqs_ok(const struct mf_field *, const struct flow *);
-void mf_mask_field_and_prereqs(const struct mf_field *, struct flow *mask);
+void mf_mask_field_and_prereqs(const struct mf_field *,
+ struct flow_wildcards *);
void mf_bitmap_set_field_and_prereqs(const struct mf_field *mf, struct
mf_bitmap *bm);
union mf_value src_value;
union mf_value dst_value;
- mf_mask_field_and_prereqs(move->dst.field, &wc->masks);
- mf_mask_field_and_prereqs(move->src.field, &wc->masks);
+ mf_mask_field_and_prereqs(move->dst.field, wc);
+ mf_mask_field_and_prereqs(move->src.field, wc);
/* A flow may wildcard nw_frag. Do nothing if setting a transport
* header field on a packet that does not have them. */
}
/* A flow may wildcard nw_frag. Do nothing if setting a trasport
* header field on a packet that does not have them. */
- mf_mask_field_and_prereqs(mf, &wc->masks);
+ mf_mask_field_and_prereqs(mf, wc);
if (mf_are_prereqs_ok(mf, flow)) {
mf_set_flow_value_masked(mf, &set_field->value,
&set_field->mask, flow);
flow_wildcards_init_catchall(ctx->wc);
/* Some fields we consider to always be examined. */
- memset(&ctx->wc->masks.in_port, 0xff, sizeof ctx->wc->masks.in_port);
- memset(&ctx->wc->masks.dl_type, 0xff, sizeof ctx->wc->masks.dl_type);
+ WC_MASK_FIELD(ctx->wc, in_port);
+ WC_MASK_FIELD(ctx->wc, dl_type);
if (is_ip_any(&ctx->xin->flow)) {
- ctx->wc->masks.nw_frag |= FLOW_NW_FRAG_MASK;
+ WC_MASK_FIELD_MASK(ctx->wc, nw_frag, FLOW_NW_FRAG_MASK);
}
if (ctx->xbridge->support.odp.recirc) {
/* Always exactly match recirc_id when datapath supports
* recirculation. */
- ctx->wc->masks.recirc_id = UINT32_MAX;
+ WC_MASK_FIELD(ctx->wc, recirc_id);
}
if (ctx->xbridge->netflow) {