0, upcall_info->cmd);
        upcall->dp_ifindex = dp_ifindex;
 
-       nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY);
-       err = ovs_nla_put_flow(key, key, user_skb);
+       err = ovs_nla_put_key(key, key, OVS_PACKET_ATTR_KEY, false, user_skb);
        BUG_ON(err);
-       nla_nest_end(user_skb, nla);
 
        if (upcall_info->userdata)
                __nla_put(user_skb, OVS_PACKET_ATTR_USERDATA,
                + nla_total_size(acts->actions_len); /* OVS_FLOW_ATTR_ACTIONS */
 }
 
-/* Called with ovs_mutex or RCU read lock. */
-static int ovs_flow_cmd_fill_match(const struct sw_flow *flow,
-                                  struct sk_buff *skb)
-{
-       struct nlattr *nla;
-       int err;
-
-       /* Fill flow key. */
-       nla = nla_nest_start(skb, OVS_FLOW_ATTR_KEY);
-       if (!nla)
-               return -EMSGSIZE;
-
-       err = ovs_nla_put_flow(&flow->unmasked_key, &flow->unmasked_key, skb);
-       if (err)
-               return err;
-
-       nla_nest_end(skb, nla);
-
-       /* Fill flow mask. */
-       nla = nla_nest_start(skb, OVS_FLOW_ATTR_MASK);
-       if (!nla)
-               return -EMSGSIZE;
-
-       err = ovs_nla_put_flow(&flow->key, &flow->mask->key, skb);
-       if (err)
-               return err;
-
-       nla_nest_end(skb, nla);
-       return 0;
-}
-
 /* Called with ovs_mutex or RCU read lock. */
 static int ovs_flow_cmd_fill_stats(const struct sw_flow *flow,
                                   struct sk_buff *skb)
 
        ovs_header->dp_ifindex = dp_ifindex;
 
-       err = ovs_flow_cmd_fill_match(flow, skb);
+       err = ovs_nla_put_unmasked_key(flow, skb);
+       if (err)
+               goto error;
+
+       err = ovs_nla_put_mask(flow, skb);
        if (err)
                goto error;
 
 
        return metadata_from_nlattrs(&match, &attrs, a, false, log);
 }
 
-int ovs_nla_put_flow(const struct sw_flow_key *swkey,
-                    const struct sw_flow_key *output, struct sk_buff *skb)
+static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
+                            const struct sw_flow_key *output, bool is_mask,
+                            struct sk_buff *skb)
 {
        struct ovs_key_ethernet *eth_key;
        struct nlattr *nla, *encap;
-       bool is_mask = (swkey != output);
 
        if (nla_put_u32(skb, OVS_KEY_ATTR_RECIRC_ID, output->recirc_id))
                goto nla_put_failure;
        return -EMSGSIZE;
 }
 
+int ovs_nla_put_key(const struct sw_flow_key *swkey,
+                   const struct sw_flow_key *output, int attr, bool is_mask,
+                   struct sk_buff *skb)
+{
+       int err;
+       struct nlattr *nla;
+
+       nla = nla_nest_start(skb, attr);
+       if (!nla)
+               return -EMSGSIZE;
+       err = __ovs_nla_put_key(swkey, output, is_mask, skb);
+       if (err)
+               return err;
+       nla_nest_end(skb, nla);
+
+       return 0;
+}
+
+/* Called with ovs_mutex or RCU read lock. */
+int ovs_nla_put_unmasked_key(const struct sw_flow *flow, struct sk_buff *skb)
+{
+       return ovs_nla_put_key(&flow->unmasked_key, &flow->unmasked_key,
+                               OVS_FLOW_ATTR_KEY, false, skb);
+}
+
+/* Called with ovs_mutex or RCU read lock. */
+int ovs_nla_put_mask(const struct sw_flow *flow, struct sk_buff *skb)
+{
+       return ovs_nla_put_key(&flow->key, &flow->mask->key,
+                               OVS_FLOW_ATTR_MASK, true, skb);
+}
+
 #define MAX_ACTIONS_BUFSIZE    (32 * 1024)
 
 static struct sw_flow_actions *nla_alloc_flow_actions(int size, bool log)
 
 void ovs_match_init(struct sw_flow_match *match,
                    struct sw_flow_key *key, struct sw_flow_mask *mask);
 
-int ovs_nla_put_flow(const struct sw_flow_key *,
-                    const struct sw_flow_key *, struct sk_buff *);
+int ovs_nla_put_key(const struct sw_flow_key *, const struct sw_flow_key *,
+                   int attr, bool is_mask, struct sk_buff *);
 int ovs_nla_get_flow_metadata(const struct nlattr *, struct sw_flow_key *,
                              bool log);
 
+int ovs_nla_put_unmasked_key(const struct sw_flow *flow, struct sk_buff *skb);
+int ovs_nla_put_mask(const struct sw_flow *flow, struct sk_buff *skb);
+
 int ovs_nla_get_match(struct sw_flow_match *, const struct nlattr *key,
                      const struct nlattr *mask, bool log);
 int ovs_nla_put_egress_tunnel_key(struct sk_buff *,