diff --git a/include/openvswitch/meta-flow.h b/include/openvswitch/meta-flow.h
index 83e2599..aac9945 100644
--- a/include/openvswitch/meta-flow.h
+++ b/include/openvswitch/meta-flow.h
@@ -1898,6 +1898,7 @@ void mf_get_mask(const struct mf_field *, const struct flow_wildcards *,
 /* Prerequisites. */
 bool mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow,
                        struct flow_wildcards *wc);
+bool mf_are_match_prereqs_ok(const struct mf_field *, const struct match *);
 
 static inline bool
 mf_is_l3_or_higher(const struct mf_field *mf)
@@ -1959,8 +1960,8 @@ void mf_subfield_swap(const struct mf_subfield *,
                       const struct mf_subfield *,
                       struct flow *flow, struct flow_wildcards *);
 
-enum ofperr mf_check_src(const struct mf_subfield *, const struct flow *);
-enum ofperr mf_check_dst(const struct mf_subfield *, const struct flow *);
+enum ofperr mf_check_src(const struct mf_subfield *, const struct match *);
+enum ofperr mf_check_dst(const struct mf_subfield *, const struct match *);
 
 /* Parsing and formatting. */
 char *mf_parse(const struct mf_field *, const char *,
diff --git a/include/openvswitch/ofp-actions.h b/include/openvswitch/ofp-actions.h
index 88f573d..53d6b44 100644
--- a/include/openvswitch/ofp-actions.h
+++ b/include/openvswitch/ofp-actions.h
@@ -954,11 +954,11 @@ ofpacts_pull_openflow_instructions(struct ofpbuf *openflow,
                                    const struct vl_mff_map *vl_mff_map,
                                    struct ofpbuf *ofpacts);
 enum ofperr ofpacts_check(struct ofpact[], size_t ofpacts_len,
-                          struct flow *, ofp_port_t max_ports,
+                          struct match *, ofp_port_t max_ports,
                           uint8_t table_id, uint8_t n_tables,
                           enum ofputil_protocol *usable_protocols);
 enum ofperr ofpacts_check_consistency(struct ofpact[], size_t ofpacts_len,
-                                      struct flow *, ofp_port_t max_ports,
+                                      struct match *, ofp_port_t max_ports,
                                       uint8_t table_id, uint8_t n_tables,
                                       enum ofputil_protocol usable_protocols);
 enum ofperr ofpact_check_output_port(ofp_port_t port, ofp_port_t max_ports);
diff --git a/lib/bundle.c b/lib/bundle.c
index 70a743b..620318e 100644
--- a/lib/bundle.c
+++ b/lib/bundle.c
@@ -105,13 +105,13 @@ bundle_execute(const struct ofpact_bundle *bundle,
 
 enum ofperr
 bundle_check(const struct ofpact_bundle *bundle, ofp_port_t max_ports,
-             const struct flow *flow)
+             const struct match *match)
 {
     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
     size_t i;
 
     if (bundle->dst.field) {
-        enum ofperr error = mf_check_dst(&bundle->dst, flow);
+        enum ofperr error = mf_check_dst(&bundle->dst, match);
         if (error) {
             return error;
         }
diff --git a/lib/bundle.h b/lib/bundle.h
index f5ce321..48b9b79 100644
--- a/lib/bundle.h
+++ b/lib/bundle.h
@@ -29,6 +29,7 @@
 struct ds;
 struct flow;
 struct flow_wildcards;
+struct match;
 struct ofpact_bundle;
 struct ofpbuf;
 
@@ -43,7 +44,7 @@ ofp_port_t bundle_execute(const struct ofpact_bundle *, const struct flow *,
                         bool (*slave_enabled)(ofp_port_t ofp_port, void *aux),
                         void *aux);
 enum ofperr bundle_check(const struct ofpact_bundle *, ofp_port_t max_ports,
-                         const struct flow *);
+                         const struct match *);
 char *bundle_parse(const char *, struct ofpbuf *ofpacts) OVS_WARN_UNUSED_RESULT;
 char *bundle_parse_load(const char *, struct ofpbuf *ofpacts)
     OVS_WARN_UNUSED_RESULT;
diff --git a/lib/learn.c b/lib/learn.c
index ce52c35..1990849 100644
--- a/lib/learn.c
+++ b/lib/learn.c
@@ -35,18 +35,18 @@
 /* Checks that 'learn' is a valid action on 'flow'.  Returns 0 if it is valid,
  * otherwise an OFPERR_*. */
 enum ofperr
-learn_check(const struct ofpact_learn *learn, const struct flow *flow)
+learn_check(const struct ofpact_learn *learn, const struct match *src_match)
 {
     const struct ofpact_learn_spec *spec;
-    struct match match;
+    struct match dst_match;
 
-    match_init_catchall(&match);
+    match_init_catchall(&dst_match);
     OFPACT_LEARN_SPEC_FOR_EACH (spec, learn) {
         enum ofperr error;
 
         /* Check the source. */
         if (spec->src_type == NX_LEARN_SRC_FIELD) {
-            error = mf_check_src(&spec->src, flow);
+            error = mf_check_src(&spec->src, src_match);
             if (error) {
                 return error;
             }
@@ -55,18 +55,19 @@ learn_check(const struct ofpact_learn *learn, const struct flow *flow)
         /* Check the destination. */
         switch (spec->dst_type) {
         case NX_LEARN_DST_MATCH:
-            error = mf_check_src(&spec->dst, &match.flow);
+            error = mf_check_src(&spec->dst, &dst_match);
             if (error) {
                 return error;
             }
             if (spec->src_type & NX_LEARN_SRC_IMMEDIATE) {
                 mf_write_subfield_value(&spec->dst,
-                                        ofpact_learn_spec_imm(spec), &match);
+                                        ofpact_learn_spec_imm(spec),
+                                        &dst_match);
             }
             break;
 
         case NX_LEARN_DST_LOAD:
-            error = mf_check_dst(&spec->dst, &match.flow);
+            error = mf_check_dst(&spec->dst, &dst_match);
             if (error) {
                 return error;
             }
diff --git a/lib/learn.h b/lib/learn.h
index adbbdf3..9dd41d3 100644
--- a/lib/learn.h
+++ b/lib/learn.h
@@ -23,6 +23,7 @@
 struct ds;
 struct flow;
 struct flow_wildcards;
+struct match;
 struct ofpbuf;
 struct ofpact_learn;
 struct ofputil_flow_mod;
@@ -33,7 +34,7 @@ struct nx_action_learn;
  * See lib/ofp-actions.c for NXAST_LEARN specification.
  */
 
-enum ofperr learn_check(const struct ofpact_learn *, const struct flow *);
+enum ofperr learn_check(const struct ofpact_learn *, const struct match *);
 void learn_execute(const struct ofpact_learn *, const struct flow *,
                    struct ofputil_flow_mod *, struct ofpbuf *ofpacts);
 void learn_mask(const struct ofpact_learn *, struct flow_wildcards *);
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 40704e6..9d635a3 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -379,10 +379,12 @@ mf_is_mask_valid(const struct mf_field *mf, const union mf_value *mask)
 }
 
 /* Returns true if 'flow' meets the prerequisites for 'mf', false otherwise.
+ * If a non-NULL 'mask' is passed, zero-valued matches can also be verified.
  * Sets inspected bits in 'wc', if non-NULL. */
-bool
-mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow,
-                  struct flow_wildcards *wc)
+static bool
+mf_are_prereqs_ok__(const struct mf_field *mf, const struct flow *flow,
+                    const struct flow_wildcards *mask OVS_UNUSED,
+                    struct flow_wildcards *wc)
 {
     switch (mf->prereqs) {
     case MFP_NONE:
@@ -401,6 +403,7 @@ mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow,
     case MFP_IP_ANY:
         return is_ip_any(flow);
     case MFP_TCP:
+        /* Matching !FRAG_LATER is not enforced (mask is not checked). */
         return is_tcp(flow, wc) && !(flow->nw_frag & FLOW_NW_FRAG_LATER);
     case MFP_UDP:
         return is_udp(flow, wc) && !(flow->nw_frag & FLOW_NW_FRAG_LATER);
@@ -421,6 +424,23 @@ mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow,
     OVS_NOT_REACHED();
 }
 
+/* Returns true if 'flow' meets the prerequisites for 'mf', false otherwise.
+ * Sets inspected bits in 'wc', if non-NULL. */
+bool
+mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow,
+                  struct flow_wildcards *wc)
+{
+    return mf_are_prereqs_ok__(mf, flow, NULL, wc);
+}
+
+/* Returns true if 'match' meets the prerequisites for 'mf', false otherwise.
+ */
+bool
+mf_are_match_prereqs_ok(const struct mf_field *mf, const struct match *match)
+{
+    return mf_are_prereqs_ok__(mf, &match->flow, &match->wc, NULL);
+}
+
 /* Returns true if 'value' may be a valid value *as part of a masked match*,
  * false otherwise.
  *
@@ -1948,7 +1968,7 @@ mf_set(const struct mf_field *mf,
 }
 
 static enum ofperr
-mf_check__(const struct mf_subfield *sf, const struct flow *flow,
+mf_check__(const struct mf_subfield *sf, const struct match *match,
            const char *type)
 {
     if (!sf->field) {
@@ -1966,7 +1986,7 @@ mf_check__(const struct mf_subfield *sf, const struct flow *flow,
                      "of %s field %s", sf->ofs, sf->n_bits,
                      sf->field->n_bits, type, sf->field->name);
         return OFPERR_OFPBAC_BAD_SET_LEN;
-    } else if (flow && !mf_are_prereqs_ok(sf->field, flow, NULL)) {
+    } else if (match && !mf_are_match_prereqs_ok(sf->field, match)) {
         VLOG_WARN_RL(&rl, "%s field %s lacks correct prerequisites",
                      type, sf->field->name);
         return OFPERR_OFPBAC_MATCH_INCONSISTENT;
@@ -2053,18 +2073,18 @@ mf_subfield_swap(const struct mf_subfield *a,
  * 0 if so, otherwise an OpenFlow error code (e.g. as returned by
  * ofp_mkerr()).  */
 enum ofperr
-mf_check_src(const struct mf_subfield *sf, const struct flow *flow)
+mf_check_src(const struct mf_subfield *sf, const struct match *match)
 {
-    return mf_check__(sf, flow, "source");
+    return mf_check__(sf, match, "source");
 }
 
 /* Checks whether 'sf' is valid for writing a subfield into 'flow'.  Returns 0
  * if so, otherwise an OpenFlow error code (e.g. as returned by
  * ofp_mkerr()). */
 enum ofperr
-mf_check_dst(const struct mf_subfield *sf, const struct flow *flow)
+mf_check_dst(const struct mf_subfield *sf, const struct match *match)
 {
-    int error = mf_check__(sf, flow, "destination");
+    int error = mf_check__(sf, match, "destination");
     if (!error && !sf->field->writable) {
         VLOG_WARN_RL(&rl, "destination field %s is not writable",
                      sf->field->name);
diff --git a/lib/multipath.c b/lib/multipath.c
index 8a1d1fa..e855a88 100644
--- a/lib/multipath.c
+++ b/lib/multipath.c
@@ -35,9 +35,9 @@
  * OFPERR_*. */
 enum ofperr
 multipath_check(const struct ofpact_multipath *mp,
-                const struct flow *flow)
+                const struct match *match)
 {
-    return mf_check_dst(&mp->dst, flow);
+    return mf_check_dst(&mp->dst, match);
 }
 
 /* multipath_execute(). */
diff --git a/lib/multipath.h b/lib/multipath.h
index 6dd3785..4158302 100644
--- a/lib/multipath.h
+++ b/lib/multipath.h
@@ -24,6 +24,7 @@
 struct ds;
 struct flow;
 struct flow_wildcards;
+struct match;
 struct nx_action_multipath;
 struct ofpact_multipath;
 struct ofpbuf;
@@ -31,7 +32,7 @@ struct ofpbuf;
 /* NXAST_MULTIPATH helper functions. */
 
 enum ofperr multipath_check(const struct ofpact_multipath *,
-                            const struct flow *);
+                            const struct match *);
 
 void multipath_execute(const struct ofpact_multipath *, struct flow *,
                        struct flow_wildcards *);
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 91401e2..95516a1 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -539,7 +539,7 @@ nx_pull_raw(const uint8_t *p, unsigned int match_len, bool strict,
                 *cookie = value.be64;
                 *cookie_mask = mask.be64;
             }
-        } else if (!mf_are_prereqs_ok(field, &match->flow, NULL)) {
+        } else if (!mf_are_match_prereqs_ok(field, match)) {
             error = OFPERR_OFPBMC_BAD_PREREQ;
         } else if (!mf_is_all_wild(field, &match->wc)) {
             error = OFPERR_OFPBMC_DUP_FIELD;
@@ -1663,16 +1663,17 @@ nxm_format_reg_move(const struct ofpact_reg_move *move, struct ds *s)
 
 
 enum ofperr
-nxm_reg_move_check(const struct ofpact_reg_move *move, const struct flow *flow)
+nxm_reg_move_check(const struct ofpact_reg_move *move,
+                   const struct match *match)
 {
     enum ofperr error;
 
-    error = mf_check_src(&move->src, flow);
+    error = mf_check_src(&move->src, match);
     if (error) {
         return error;
     }
 
-    return mf_check_dst(&move->dst, flow);
+    return mf_check_dst(&move->dst, match);
 }
 
 /* nxm_execute_reg_move(). */
@@ -1734,16 +1735,16 @@ nxm_format_stack_pop(const struct ofpact_stack *pop, struct ds *s)
 
 enum ofperr
 nxm_stack_push_check(const struct ofpact_stack *push,
-                     const struct flow *flow)
+                     const struct match *match)
 {
-    return mf_check_src(&push->subfield, flow);
+    return mf_check_src(&push->subfield, match);
 }
 
 enum ofperr
 nxm_stack_pop_check(const struct ofpact_stack *pop,
-                    const struct flow *flow)
+                    const struct match *match)
 {
-    return mf_check_dst(&pop->subfield, flow);
+    return mf_check_dst(&pop->subfield, match);
 }
 
 /* nxm_execute_stack_push(), nxm_execute_stack_pop().
diff --git a/lib/nx-match.h b/lib/nx-match.h
index 5dca24a..631ab48 100644
--- a/lib/nx-match.h
+++ b/lib/nx-match.h
@@ -116,7 +116,7 @@ char *nxm_parse_reg_move(struct ofpact_reg_move *, const char *)
 void nxm_format_reg_move(const struct ofpact_reg_move *, struct ds *);
 
 enum ofperr nxm_reg_move_check(const struct ofpact_reg_move *,
-                               const struct flow *);
+                               const struct match *);
 
 void nxm_reg_load(const struct mf_subfield *, uint64_t src_data,
                   struct flow *, struct flow_wildcards *);
@@ -128,9 +128,9 @@ void nxm_format_stack_push(const struct ofpact_stack *, struct ds *);
 void nxm_format_stack_pop(const struct ofpact_stack *, struct ds *);
 
 enum ofperr nxm_stack_push_check(const struct ofpact_stack *,
-                                 const  struct flow *);
+                                 const  struct match *);
 enum ofperr nxm_stack_pop_check(const struct ofpact_stack *,
-                               const struct flow *);
+                                const struct match *);
 void nx_stack_push(struct ofpbuf *stack, const void *v, uint8_t bytes);
 void nx_stack_push_bottom(struct ofpbuf *stack, const void *v, uint8_t bytes);
 void *nx_stack_pop(struct ofpbuf *stack, uint8_t *bytes);
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index ce80f57..2869e0f 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -7065,9 +7065,10 @@ inconsistent_match(enum ofputil_protocol *usable_protocols)
  * without context. */
 static enum ofperr
 ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
-               struct flow *flow, ofp_port_t max_ports,
+               struct match *match, ofp_port_t max_ports,
                uint8_t table_id, uint8_t n_tables)
 {
+    struct flow *flow = &match->flow;
     const struct ofpact_enqueue *enqueue;
     const struct mf_field *mf;
 
@@ -7089,14 +7090,14 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
         return 0;
 
     case OFPACT_OUTPUT_REG:
-        return mf_check_src(&ofpact_get_OUTPUT_REG(a)->src, flow);
+        return mf_check_src(&ofpact_get_OUTPUT_REG(a)->src, match);
 
     case OFPACT_OUTPUT_TRUNC:
         return ofpact_check_output_port(ofpact_get_OUTPUT_TRUNC(a)->port,
                                         max_ports);
 
     case OFPACT_BUNDLE:
-        return bundle_check(ofpact_get_BUNDLE(a), max_ports, flow);
+        return bundle_check(ofpact_get_BUNDLE(a), max_ports, match);
 
     case OFPACT_SET_VLAN_VID:
         /* Remember if we saw a vlan tag in the flow to aid translating to
@@ -7179,7 +7180,7 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
         return 0;
 
     case OFPACT_REG_MOVE:
-        return nxm_reg_move_check(ofpact_get_REG_MOVE(a), flow);
+        return nxm_reg_move_check(ofpact_get_REG_MOVE(a), match);
 
     case OFPACT_SET_FIELD:
         mf = ofpact_get_SET_FIELD(a)->field;
@@ -7202,10 +7203,10 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
         return 0;
 
     case OFPACT_STACK_PUSH:
-        return nxm_stack_push_check(ofpact_get_STACK_PUSH(a), flow);
+        return nxm_stack_push_check(ofpact_get_STACK_PUSH(a), match);
 
     case OFPACT_STACK_POP:
-        return nxm_stack_pop_check(ofpact_get_STACK_POP(a), flow);
+        return nxm_stack_pop_check(ofpact_get_STACK_POP(a), match);
 
     case OFPACT_SET_MPLS_LABEL:
     case OFPACT_SET_MPLS_TC:
@@ -7229,13 +7230,13 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
         return 0;
 
     case OFPACT_LEARN:
-        return learn_check(ofpact_get_LEARN(a), flow);
+        return learn_check(ofpact_get_LEARN(a), match);
 
     case OFPACT_CONJUNCTION:
         return 0;
 
     case OFPACT_MULTIPATH:
-        return multipath_check(ofpact_get_MULTIPATH(a), flow);
+        return multipath_check(ofpact_get_MULTIPATH(a), match);
 
     case OFPACT_NOTE:
     case OFPACT_EXIT:
@@ -7262,7 +7263,7 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
     case OFPACT_CLONE: {
         struct ofpact_nest *on = ofpact_get_CLONE(a);
         return ofpacts_check(on->actions, ofpact_nest_get_action_len(on),
-                             flow, max_ports, table_id, n_tables,
+                             match, max_ports, table_id, n_tables,
                              usable_protocols);
     }
 
@@ -7280,11 +7281,11 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
         }
 
         if (oc->zone_src.field) {
-            return mf_check_src(&oc->zone_src, flow);
+            return mf_check_src(&oc->zone_src, match);
         }
 
         return ofpacts_check(oc->actions, ofpact_ct_get_action_len(oc),
-                             flow, max_ports, table_id, n_tables,
+                             match, max_ports, table_id, n_tables,
                              usable_protocols);
     }
 
@@ -7312,7 +7313,7 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
         struct ofpact_nest *on = ofpact_get_WRITE_ACTIONS(a);
         enum ofputil_protocol p = *usable_protocols;
         return ofpacts_check(on->actions, ofpact_nest_get_action_len(on),
-                             flow, max_ports, table_id, n_tables, &p);
+                             match, max_ports, table_id, n_tables, &p);
     }
 
     case OFPACT_WRITE_METADATA:
@@ -7360,32 +7361,33 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
  * example of an inconsistency between match and actions is a flow that does
  * not match on an MPLS Ethertype but has an action that pops an MPLS label.)
  *
- * May annotate ofpacts with information gathered from the 'flow'.
+ * May annotate ofpacts with information gathered from the 'match'.
  *
- * May temporarily modify 'flow', but restores the changes before returning. */
+ * May temporarily modify 'match', but restores the changes before
+ * returning. */
 enum ofperr
 ofpacts_check(struct ofpact ofpacts[], size_t ofpacts_len,
-              struct flow *flow, ofp_port_t max_ports,
+              struct match *match, ofp_port_t max_ports,
               uint8_t table_id, uint8_t n_tables,
               enum ofputil_protocol *usable_protocols)
 {
     struct ofpact *a;
-    ovs_be16 dl_type = flow->dl_type;
-    ovs_be16 vlan_tci = flow->vlan_tci;
-    uint8_t nw_proto = flow->nw_proto;
+    ovs_be16 dl_type = match->flow.dl_type;
+    ovs_be16 vlan_tci = match->flow.vlan_tci;
+    uint8_t nw_proto = match->flow.nw_proto;
     enum ofperr error = 0;
 
     OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
-        error = ofpact_check__(usable_protocols, a, flow,
+        error = ofpact_check__(usable_protocols, a, match,
                                max_ports, table_id, n_tables);
         if (error) {
             break;
         }
     }
     /* Restore fields that may have been modified. */
-    flow->dl_type = dl_type;
-    flow->vlan_tci = vlan_tci;
-    flow->nw_proto = nw_proto;
+    match->flow.dl_type = dl_type;
+    match->flow.vlan_tci = vlan_tci;
+    match->flow.nw_proto = nw_proto;
     return error;
 }
 
@@ -7393,14 +7395,14 @@ ofpacts_check(struct ofpact ofpacts[], size_t ofpacts_len,
  * OFPERR_OFPBAC_MATCH_INCONSISTENT rather than clearing bits. */
 enum ofperr
 ofpacts_check_consistency(struct ofpact ofpacts[], size_t ofpacts_len,
-                          struct flow *flow, ofp_port_t max_ports,
+                          struct match *match, ofp_port_t max_ports,
                           uint8_t table_id, uint8_t n_tables,
                           enum ofputil_protocol usable_protocols)
 {
     enum ofputil_protocol p = usable_protocols;
     enum ofperr error;
 
-    error = ofpacts_check(ofpacts, ofpacts_len, flow, max_ports,
+    error = ofpacts_check(ofpacts, ofpacts_len, match, max_ports,
                           table_id, n_tables, &p);
     return (error ? error
             : p != usable_protocols ? OFPERR_OFPBAC_MATCH_INCONSISTENT
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index a6b9fcf..7826bc5 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -546,7 +546,7 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string,
         if (!error) {
             enum ofperr err;
 
-            err = ofpacts_check(ofpacts.data, ofpacts.size, &fm->match.flow,
+            err = ofpacts_check(ofpacts.data, ofpacts.size, &fm->match,
                                 OFPP_MAX, fm->table_id, 255, usable_protocols);
             if (!err && !*usable_protocols) {
                 err = OFPERR_OFPBAC_MATCH_INCONSISTENT;
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 0c9343e..7d40cbb 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1751,7 +1751,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
     }
 
     return ofpacts_check_consistency(fm->ofpacts, fm->ofpacts_len,
-                                     &fm->match.flow, max_port,
+                                     &fm->match, max_port,
                                      fm->table_id, max_table, protocol);
 }
 
diff --git a/ofproto/ofproto-dpif-trace.c b/ofproto/ofproto-dpif-trace.c
index b01a131..a5cc089 100644
--- a/ofproto/ofproto-dpif-trace.c
+++ b/ofproto/ofproto-dpif-trace.c
@@ -324,7 +324,7 @@ ofproto_unixctl_trace_actions(struct unixctl_conn *conn, int argc,
     struct ofpbuf ofpacts;
     struct dp_packet *packet;
     struct ds result;
-    struct flow flow;
+    struct match match;
     uint16_t in_port;
 
     /* Three kinds of error return values! */
@@ -354,12 +354,13 @@ ofproto_unixctl_trace_actions(struct unixctl_conn *conn, int argc,
         enforce_consistency = false;
     }
 
-    error = parse_flow_and_packet(argc, argv, &ofproto, &flow, &packet);
+    error = parse_flow_and_packet(argc, argv, &ofproto, &match.flow, &packet);
     if (error) {
         unixctl_command_reply_error(conn, error);
         free(error);
         goto exit;
     }
+    match_wc_init(&match, &match.flow);
 
     /* Do the same checks as handle_packet_out() in ofproto.c.
      *
@@ -371,18 +372,18 @@ ofproto_unixctl_trace_actions(struct unixctl_conn *conn, int argc,
      *
      * We skip the "meter" check here because meter is an instruction, not an
      * action, and thus cannot appear in ofpacts. */
-    in_port = ofp_to_u16(flow.in_port.ofp_port);
+    in_port = ofp_to_u16(match.flow.in_port.ofp_port);
     if (in_port >= ofproto->up.max_ports && in_port < ofp_to_u16(OFPP_MAX)) {
         unixctl_command_reply_error(conn, "invalid in_port");
         goto exit;
     }
     if (enforce_consistency) {
-        retval = ofpacts_check_consistency(ofpacts.data, ofpacts.size, &flow,
+        retval = ofpacts_check_consistency(ofpacts.data, ofpacts.size, &match,
                                            u16_to_ofp(ofproto->up.max_ports),
                                            0, ofproto->up.n_tables,
                                            usable_protocols);
     } else {
-        retval = ofpacts_check(ofpacts.data, ofpacts.size, &flow,
+        retval = ofpacts_check(ofpacts.data, ofpacts.size, &match,
                                u16_to_ofp(ofproto->up.max_ports), 0,
                                ofproto->up.n_tables, &usable_protocols);
     }
@@ -398,7 +399,7 @@ ofproto_unixctl_trace_actions(struct unixctl_conn *conn, int argc,
         goto exit;
     }
 
-    ofproto_trace(ofproto, &flow, packet,
+    ofproto_trace(ofproto, &match.flow, packet,
                   ofpacts.data, ofpacts.size, &result);
     unixctl_command_reply(conn, ds_cstr(&result));
 
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index ef4b1d9..35ec31d 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -3447,6 +3447,7 @@ ofproto_packet_out_init(struct ofproto *ofproto,
                         const struct ofputil_packet_out *po)
 {
     enum ofperr error;
+    struct match match;
 
     if (ofp_to_u16(po->in_port) >= ofproto->max_ports
         && ofp_to_u16(po->in_port) < ofp_to_u16(OFPP_MAX)) {
@@ -3471,8 +3472,8 @@ ofproto_packet_out_init(struct ofproto *ofproto,
      * actions aren't in any table.  This is OK as 'table_id' is only used to
      * check instructions (e.g., goto-table), which can't appear on the action
      * list of a packet-out. */
-    error = ofpacts_check_consistency(po->ofpacts, po->ofpacts_len,
-                                      opo->flow,
+    match_wc_init(&match, opo->flow);
+    error = ofpacts_check_consistency(po->ofpacts, po->ofpacts_len, &match,
                                       u16_to_ofp(ofproto->max_ports), 0,
                                       ofproto->n_tables,
                                       ofconn_get_protocol(ofconn));
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 77332e0..e317242 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -3880,12 +3880,12 @@ ofctl_parse_actions__(const char *version_s, bool instructions)
         if (!error && instructions) {
             /* Verify actions, enforce consistency. */
             enum ofputil_protocol protocol;
-            struct flow flow;
+            struct match match;
 
-            memset(&flow, 0, sizeof flow);
+            memset(&match, 0, sizeof match);
             protocol = ofputil_protocols_from_ofp_version(version);
             error = ofpacts_check_consistency(ofpacts.data, ofpacts.size,
-                                              &flow, OFPP_MAX,
+                                              &match, OFPP_MAX,
                                               table_id ? atoi(table_id) : 0,
                                               OFPTT_MAX + 1, protocol);
         }
