netlink-socket: Adapt to Windows and MSVC.
[cascardo/ovs.git] / lib / meta-flow.c
index cd121bb..b76c11d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2011, 2012, 2013, 2014 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -52,6 +52,30 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
     /* ## -------- ## */
 
     {
+        MFF_DP_HASH, "dp_hash", NULL,
+        MF_FIELD_SIZES(be32),
+        MFM_FULLY,
+        MFS_HEXADECIMAL,
+        MFP_NONE,
+        false,
+        NXM_NX_DP_HASH, "NXM_NX_DP_HASH",
+        NXM_NX_DP_HASH, "NXM_NX_DP_HASH", 0,
+        OFPUTIL_P_NXM_OXM_ANY,
+        OFPUTIL_P_NXM_OXM_ANY,
+        -1,
+    }, {
+        MFF_RECIRC_ID, "recirc_id", NULL,
+        MF_FIELD_SIZES(be32),
+        MFM_NONE,
+        MFS_DECIMAL,
+        MFP_NONE,
+        false,
+        NXM_NX_RECIRC_ID, "NXM_NX_RECIRC_ID",
+        NXM_NX_RECIRC_ID, "NXM_NX_RECIRC_ID", 0,
+        OFPUTIL_P_NXM_OXM_ANY,
+        OFPUTIL_P_NXM_OXM_ANY,
+        -1,
+    }, {
         MFF_TUN_ID, "tun_id", "tunnel_id",
         MF_FIELD_SIZES(be64),
         MFM_FULLY,
@@ -59,7 +83,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         NXM_NX_TUN_ID, "NXM_NX_TUN_ID",
-        OXM_OF_TUNNEL_ID, "OXM_OF_TUNNEL_ID",
+        OXM_OF_TUNNEL_ID, "OXM_OF_TUNNEL_ID", OFP13_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         FLOW_U32OFS(tunnel.tun_id),
@@ -71,7 +95,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         NXM_NX_TUN_IPV4_SRC, "NXM_NX_TUN_IPV4_SRC",
-        NXM_NX_TUN_IPV4_SRC, "NXM_NX_TUN_IPV4_SRC",
+        NXM_NX_TUN_IPV4_SRC, "NXM_NX_TUN_IPV4_SRC", 0,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         FLOW_U32OFS(tunnel.ip_src),
@@ -83,7 +107,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         NXM_NX_TUN_IPV4_DST, "NXM_NX_TUN_IPV4_DST",
-        NXM_NX_TUN_IPV4_DST, "NXM_NX_TUN_IPV4_DST",
+        NXM_NX_TUN_IPV4_DST, "NXM_NX_TUN_IPV4_DST", 0,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         FLOW_U32OFS(tunnel.ip_dst),
@@ -95,7 +119,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         false,
         0, NULL,
-        0, NULL,
+        0, NULL, 0,
         OFPUTIL_P_NONE,
         OFPUTIL_P_NONE,
         -1,
@@ -107,7 +131,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         false,
         0, NULL,
-        0, NULL,
+        0, NULL, 0,
         OFPUTIL_P_NONE,
         OFPUTIL_P_NONE,
         -1,
@@ -119,7 +143,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         false,
         0, NULL,
-        0, NULL,
+        0, NULL, 0,
         OFPUTIL_P_NONE,
         OFPUTIL_P_NONE,
         -1,
@@ -131,7 +155,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         OXM_OF_METADATA, "OXM_OF_METADATA",
-        OXM_OF_METADATA, "OXM_OF_METADATA",
+        OXM_OF_METADATA, "OXM_OF_METADATA", OFP12_VERSION,
         OFPUTIL_P_NXM_OF11_UP,
         OFPUTIL_P_NXM_OF11_UP,
         -1,
@@ -143,7 +167,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         NXM_OF_IN_PORT, "NXM_OF_IN_PORT",
-        NXM_OF_IN_PORT, "NXM_OF_IN_PORT",
+        NXM_OF_IN_PORT, "NXM_OF_IN_PORT", 0,
         OFPUTIL_P_ANY,   /* OF11+ via mapping to 32 bits. */
         OFPUTIL_P_NONE,
         -1,
@@ -155,7 +179,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         OXM_OF_IN_PORT, "OXM_OF_IN_PORT",
-        OXM_OF_IN_PORT, "OXM_OF_IN_PORT",
+        OXM_OF_IN_PORT, "OXM_OF_IN_PORT", OFP12_VERSION,
         OFPUTIL_P_OF11_UP,
         OFPUTIL_P_NONE,
         -1,
@@ -167,7 +191,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         false,
         0, NULL,
-        0, NULL,
+        0, NULL, 0,
         OFPUTIL_P_NONE,
         OFPUTIL_P_NONE,
         -1,
@@ -179,7 +203,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         NXM_NX_PKT_MARK, "NXM_NX_PKT_MARK",
-        NXM_NX_PKT_MARK, "NXM_NX_PKT_MARK",
+        NXM_NX_PKT_MARK, "NXM_NX_PKT_MARK", 0,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -194,37 +218,45 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,                               \
         true,                                   \
         NXM_NX_REG(IDX), "NXM_NX_REG" #IDX,     \
-        NXM_NX_REG(IDX), "NXM_NX_REG" #IDX,     \
+        NXM_NX_REG(IDX), "NXM_NX_REG" #IDX, 0,  \
         OFPUTIL_P_NXM_OXM_ANY,                  \
         OFPUTIL_P_NXM_OXM_ANY,                  \
         -1,                                     \
     }
-#if FLOW_N_REGS > 0
+#if FLOW_N_REGS == 8
     REGISTER(0),
-#endif
-#if FLOW_N_REGS > 1
     REGISTER(1),
-#endif
-#if FLOW_N_REGS > 2
     REGISTER(2),
-#endif
-#if FLOW_N_REGS > 3
     REGISTER(3),
-#endif
-#if FLOW_N_REGS > 4
     REGISTER(4),
-#endif
-#if FLOW_N_REGS > 5
     REGISTER(5),
-#endif
-#if FLOW_N_REGS > 6
     REGISTER(6),
-#endif
-#if FLOW_N_REGS > 7
     REGISTER(7),
+#else
+#error "Need to update mf_fields[] to match FLOW_N_REGS"
 #endif
-#if FLOW_N_REGS > 8
-#error
+
+#define XREGISTER(IDX)                                              \
+    {                                                               \
+        MFF_XREG##IDX, "xreg" #IDX, NULL,                           \
+        MF_FIELD_SIZES(be64),                                       \
+        MFM_FULLY,                                                  \
+        MFS_HEXADECIMAL,                                            \
+        MFP_NONE,                                                   \
+        true,                                                       \
+        OXM_OF_PKT_REG(IDX), "OXM_OF_PKT_REG" #IDX,                 \
+        OXM_OF_PKT_REG(IDX), "OXM_OF_PKT_REG" #IDX, OFP15_VERSION,  \
+        OFPUTIL_P_NXM_OXM_ANY,                                      \
+        OFPUTIL_P_NXM_OXM_ANY,                                      \
+        -1,                                                         \
+    }
+#if FLOW_N_XREGS == 4
+    XREGISTER(0),
+    XREGISTER(1),
+    XREGISTER(2),
+    XREGISTER(3),
+#else
+#error "Need to update mf_fields[] to match FLOW_N_XREGS"
 #endif
 
     /* ## -- ## */
@@ -239,7 +271,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         NXM_OF_ETH_SRC, "NXM_OF_ETH_SRC",
-        OXM_OF_ETH_SRC, "OXM_OF_ETH_SRC",
+        OXM_OF_ETH_SRC, "OXM_OF_ETH_SRC", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OF11_UP,   /* Bitwise masking only with NXM and OF11+! */
         -1,
@@ -251,7 +283,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         NXM_OF_ETH_DST, "NXM_OF_ETH_DST",
-        OXM_OF_ETH_DST, "OXM_OF_ETH_DST",
+        OXM_OF_ETH_DST, "OXM_OF_ETH_DST", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OF11_UP,   /* Bitwise masking only with NXM and OF11+! */
         -1,
@@ -263,7 +295,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         false,
         NXM_OF_ETH_TYPE, "NXM_OF_ETH_TYPE",
-        OXM_OF_ETH_TYPE, "OXM_OF_ETH_TYPE",
+        OXM_OF_ETH_TYPE, "OXM_OF_ETH_TYPE", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NONE,
         -1,
@@ -277,7 +309,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         NXM_OF_VLAN_TCI, "NXM_OF_VLAN_TCI",
-        NXM_OF_VLAN_TCI, "NXM_OF_VLAN_TCI",
+        NXM_OF_VLAN_TCI, "NXM_OF_VLAN_TCI", 0,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -289,7 +321,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         0, NULL,
-        0, NULL,
+        0, NULL, 0,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -301,7 +333,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID",
-        OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID",
+        OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -313,7 +345,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_NONE,
         true,
         0, NULL,
-        0, NULL,
+        0, NULL, 0,
         OFPUTIL_P_ANY,   /* Will be mapped to NXM and OXM. */
         OFPUTIL_P_NONE,
         -1,
@@ -325,7 +357,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_VLAN_VID,
         true,
         OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP",
-        OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP",
+        OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP", OFP12_VERSION,
         OFPUTIL_P_ANY,   /* Will be mapped to OF10 and NXM. */
         OFPUTIL_P_NONE,
         -1,
@@ -342,7 +374,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_MPLS,
         true,
         OXM_OF_MPLS_LABEL, "OXM_OF_MPLS_LABEL",
-        OXM_OF_MPLS_LABEL, "OXM_OF_MPLS_LABEL",
+        OXM_OF_MPLS_LABEL, "OXM_OF_MPLS_LABEL", OFP12_VERSION,
         OFPUTIL_P_NXM_OF11_UP,
         OFPUTIL_P_NONE,
         -1,
@@ -354,7 +386,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_MPLS,
         true,
         OXM_OF_MPLS_TC, "OXM_OF_MPLS_TC",
-        OXM_OF_MPLS_TC, "OXM_OF_MPLS_TC",
+        OXM_OF_MPLS_TC, "OXM_OF_MPLS_TC", OFP12_VERSION,
         OFPUTIL_P_NXM_OF11_UP,
         OFPUTIL_P_NONE,
         -1,
@@ -366,7 +398,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_MPLS,
         false,
         OXM_OF_MPLS_BOS, "OXM_OF_MPLS_BOS",
-        OXM_OF_MPLS_BOS, "OXM_OF_MPLS_BOS",
+        OXM_OF_MPLS_BOS, "OXM_OF_MPLS_BOS", OFP13_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NONE,
         -1,
@@ -384,7 +416,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_IPV4,
         true,
         NXM_OF_IP_SRC, "NXM_OF_IP_SRC",
-        OXM_OF_IPV4_SRC, "OXM_OF_IPV4_SRC",
+        OXM_OF_IPV4_SRC, "OXM_OF_IPV4_SRC", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OF11_UP,
         FLOW_U32OFS(nw_src),
@@ -396,7 +428,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_IPV4,
         true,
         NXM_OF_IP_DST, "NXM_OF_IP_DST",
-        OXM_OF_IPV4_DST, "OXM_OF_IPV4_DST",
+        OXM_OF_IPV4_DST, "OXM_OF_IPV4_DST", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OF11_UP,
         FLOW_U32OFS(nw_dst),
@@ -410,7 +442,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_IPV6,
         true,
         NXM_NX_IPV6_SRC, "NXM_NX_IPV6_SRC",
-        OXM_OF_IPV6_SRC, "OXM_OF_IPV6_SRC",
+        OXM_OF_IPV6_SRC, "OXM_OF_IPV6_SRC", OFP12_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         FLOW_U32OFS(ipv6_src),
@@ -422,7 +454,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_IPV6,
         true,
         NXM_NX_IPV6_DST, "NXM_NX_IPV6_DST",
-        OXM_OF_IPV6_DST, "OXM_OF_IPV6_DST",
+        OXM_OF_IPV6_DST, "OXM_OF_IPV6_DST", OFP12_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         FLOW_U32OFS(ipv6_dst),
@@ -435,7 +467,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_IPV6,
         false,
         NXM_NX_IPV6_LABEL, "NXM_NX_IPV6_LABEL",
-        OXM_OF_IPV6_FLABEL, "OXM_OF_IPV6_FLABEL",
+        OXM_OF_IPV6_FLABEL, "OXM_OF_IPV6_FLABEL", OFP12_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -449,7 +481,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_IP_ANY,
         false,
         NXM_OF_IP_PROTO, "NXM_OF_IP_PROTO",
-        OXM_OF_IP_PROTO, "OXM_OF_IP_PROTO",
+        OXM_OF_IP_PROTO, "OXM_OF_IP_PROTO", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NONE,
         -1,
@@ -461,7 +493,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_IP_ANY,
         true,
         NXM_OF_IP_TOS, "NXM_OF_IP_TOS",
-        NXM_OF_IP_TOS, "NXM_OF_IP_TOS",
+        NXM_OF_IP_TOS, "NXM_OF_IP_TOS", 0,
         OFPUTIL_P_ANY,   /* Will be shifted for OXM. */
         OFPUTIL_P_NONE,
         -1,
@@ -473,7 +505,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_IP_ANY,
         true,
         OXM_OF_IP_DSCP, "OXM_OF_IP_DSCP",
-        OXM_OF_IP_DSCP, "OXM_OF_IP_DSCP",
+        OXM_OF_IP_DSCP, "OXM_OF_IP_DSCP", OFP12_VERSION,
         OFPUTIL_P_ANY,   /* Will be shifted for non-OXM. */
         OFPUTIL_P_NONE,
         -1,
@@ -485,7 +517,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_IP_ANY,
         true,
         NXM_NX_IP_ECN, "NXM_NX_IP_ECN",
-        OXM_OF_IP_ECN, "OXM_OF_IP_ECN",
+        OXM_OF_IP_ECN, "OXM_OF_IP_ECN", OFP12_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NONE,
         -1,
@@ -497,7 +529,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_IP_ANY,
         true,
         NXM_NX_IP_TTL, "NXM_NX_IP_TTL",
-        NXM_NX_IP_TTL, "NXM_NX_IP_TTL",
+        NXM_NX_IP_TTL, "NXM_NX_IP_TTL", 0,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NONE,
         -1,
@@ -509,7 +541,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_IP_ANY,
         false,
         NXM_NX_IP_FRAG, "NXM_NX_IP_FRAG",
-        NXM_NX_IP_FRAG, "NXM_NX_IP_FRAG",
+        NXM_NX_IP_FRAG, "NXM_NX_IP_FRAG", 0,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -523,7 +555,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ARP,
         true,
         NXM_OF_ARP_OP, "NXM_OF_ARP_OP",
-        OXM_OF_ARP_OP, "OXM_OF_ARP_OP",
+        OXM_OF_ARP_OP, "OXM_OF_ARP_OP", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NONE,
         -1,
@@ -535,7 +567,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ARP,
         true,
         NXM_OF_ARP_SPA, "NXM_OF_ARP_SPA",
-        OXM_OF_ARP_SPA, "OXM_OF_ARP_SPA",
+        OXM_OF_ARP_SPA, "OXM_OF_ARP_SPA", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OF11_UP,
         -1,
@@ -547,7 +579,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ARP,
         true,
         NXM_OF_ARP_TPA, "NXM_OF_ARP_TPA",
-        OXM_OF_ARP_TPA, "OXM_OF_ARP_TPA",
+        OXM_OF_ARP_TPA, "OXM_OF_ARP_TPA", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OF11_UP,
         -1,
@@ -559,7 +591,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ARP,
         true,
         NXM_NX_ARP_SHA, "NXM_NX_ARP_SHA",
-        OXM_OF_ARP_SHA, "OXM_OF_ARP_SHA",
+        OXM_OF_ARP_SHA, "OXM_OF_ARP_SHA", OFP12_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -571,7 +603,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ARP,
         true,
         NXM_NX_ARP_THA, "NXM_NX_ARP_THA",
-        OXM_OF_ARP_THA, "OXM_OF_ARP_THA",
+        OXM_OF_ARP_THA, "OXM_OF_ARP_THA", OFP12_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -589,7 +621,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_TCP,
         true,
         NXM_OF_TCP_SRC, "NXM_OF_TCP_SRC",
-        OXM_OF_TCP_SRC, "OXM_OF_TCP_SRC",
+        OXM_OF_TCP_SRC, "OXM_OF_TCP_SRC", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -601,7 +633,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_TCP,
         true,
         NXM_OF_TCP_DST, "NXM_OF_TCP_DST",
-        OXM_OF_TCP_DST, "OXM_OF_TCP_DST",
+        OXM_OF_TCP_DST, "OXM_OF_TCP_DST", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -613,7 +645,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_TCP,
         false,
         NXM_NX_TCP_FLAGS, "NXM_NX_TCP_FLAGS",
-        NXM_NX_TCP_FLAGS, "NXM_NX_TCP_FLAGS",
+        OXM_OF_TCP_FLAGS, "OXM_OF_TCP_FLAGS", OFP15_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -627,7 +659,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_UDP,
         true,
         NXM_OF_UDP_SRC, "NXM_OF_UDP_SRC",
-        OXM_OF_UDP_SRC, "OXM_OF_UDP_SRC",
+        OXM_OF_UDP_SRC, "OXM_OF_UDP_SRC", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -639,7 +671,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_UDP,
         true,
         NXM_OF_UDP_DST, "NXM_OF_UDP_DST",
-        OXM_OF_UDP_DST, "OXM_OF_UDP_DST",
+        OXM_OF_UDP_DST, "OXM_OF_UDP_DST", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -653,7 +685,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_SCTP,
         true,
         OXM_OF_SCTP_SRC, "OXM_OF_SCTP_SRC",
-        OXM_OF_SCTP_SRC, "OXM_OF_SCTP_SRC",
+        OXM_OF_SCTP_SRC, "OXM_OF_SCTP_SRC", OFP12_VERSION,
         OFPUTIL_P_NXM_OF11_UP,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -665,7 +697,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_SCTP,
         true,
         OXM_OF_SCTP_DST, "OXM_OF_SCTP_DST",
-        OXM_OF_SCTP_DST, "OXM_OF_SCTP_DST",
+        OXM_OF_SCTP_DST, "OXM_OF_SCTP_DST", OFP12_VERSION,
         OFPUTIL_P_NXM_OF11_UP,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -679,7 +711,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ICMPV4,
         false,
         NXM_OF_ICMP_TYPE, "NXM_OF_ICMP_TYPE",
-        OXM_OF_ICMPV4_TYPE, "OXM_OF_ICMPV4_TYPE",
+        OXM_OF_ICMPV4_TYPE, "OXM_OF_ICMPV4_TYPE", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NONE,
         -1,
@@ -691,7 +723,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ICMPV4,
         false,
         NXM_OF_ICMP_CODE, "NXM_OF_ICMP_CODE",
-        OXM_OF_ICMPV4_CODE, "OXM_OF_ICMPV4_CODE",
+        OXM_OF_ICMPV4_CODE, "OXM_OF_ICMPV4_CODE", OFP12_VERSION,
         OFPUTIL_P_ANY,
         OFPUTIL_P_NONE,
         -1,
@@ -705,7 +737,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ICMPV6,
         false,
         NXM_NX_ICMPV6_TYPE, "NXM_NX_ICMPV6_TYPE",
-        OXM_OF_ICMPV6_TYPE, "OXM_OF_ICMPV6_TYPE",
+        OXM_OF_ICMPV6_TYPE, "OXM_OF_ICMPV6_TYPE", OFP12_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NONE,
         -1,
@@ -717,7 +749,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ICMPV6,
         false,
         NXM_NX_ICMPV6_CODE, "NXM_NX_ICMPV6_CODE",
-        OXM_OF_ICMPV6_CODE, "OXM_OF_ICMPV6_CODE",
+        OXM_OF_ICMPV6_CODE, "OXM_OF_ICMPV6_CODE", OFP12_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NONE,
         -1,
@@ -735,7 +767,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ND,
         false,
         NXM_NX_ND_TARGET, "NXM_NX_ND_TARGET",
-        OXM_OF_IPV6_ND_TARGET, "OXM_OF_IPV6_ND_TARGET",
+        OXM_OF_IPV6_ND_TARGET, "OXM_OF_IPV6_ND_TARGET", OFP12_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -747,7 +779,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ND_SOLICIT,
         false,
         NXM_NX_ND_SLL, "NXM_NX_ND_SLL",
-        OXM_OF_IPV6_ND_SLL, "OXM_OF_IPV6_ND_SLL",
+        OXM_OF_IPV6_ND_SLL, "OXM_OF_IPV6_ND_SLL", OFP12_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -759,7 +791,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFP_ND_ADVERT,
         false,
         NXM_NX_ND_TLL, "NXM_NX_ND_TLL",
-        OXM_OF_IPV6_ND_TLL, "OXM_OF_IPV6_ND_TLL",
+        OXM_OF_IPV6_ND_TLL, "OXM_OF_IPV6_ND_TLL", OFP12_VERSION,
         OFPUTIL_P_NXM_OXM_ANY,
         OFPUTIL_P_NXM_OXM_ANY,
         -1,
@@ -870,6 +902,16 @@ mf_from_nxm_header__(uint32_t header)
     return NULL;
 }
 
+uint32_t
+mf_oxm_header(enum mf_field_id id, enum ofp_version oxm_version)
+{
+    const struct mf_field *field = mf_from_id(id);
+
+    return (oxm_version >= field->oxm_version
+            ? field->oxm_header
+            : field->nxm_header);
+}
+
 /* Returns true if 'wc' wildcards all the bits in field 'mf', false if 'wc'
  * specifies at least one bit in the field.
  *
@@ -879,6 +921,10 @@ bool
 mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
 {
     switch (mf->id) {
+    case MFF_DP_HASH:
+        return !wc->masks.dp_hash;
+    case MFF_RECIRC_ID:
+        return !wc->masks.recirc_id;
     case MFF_TUN_SRC:
         return !wc->masks.tunnel.ip_src;
     case MFF_TUN_DST:
@@ -899,6 +945,8 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
         return !wc->masks.pkt_mark;
     CASE_MFF_REGS:
         return !wc->masks.regs[mf->id - MFF_REG0];
+    CASE_MFF_XREGS:
+        return !flow_get_xreg(&wc->masks, mf->id - MFF_XREG0);
 
     case MFF_ETH_SRC:
         return eth_addr_is_zero(wc->masks.dl_src);
@@ -926,11 +974,11 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
         return !(wc->masks.vlan_tci & htons(VLAN_PCP_MASK));
 
     case MFF_MPLS_LABEL:
-        return !(wc->masks.mpls_lse & htonl(MPLS_LABEL_MASK));
+        return !(wc->masks.mpls_lse[0] & htonl(MPLS_LABEL_MASK));
     case MFF_MPLS_TC:
-        return !(wc->masks.mpls_lse & htonl(MPLS_TC_MASK));
+        return !(wc->masks.mpls_lse[1] & htonl(MPLS_TC_MASK));
     case MFF_MPLS_BOS:
-        return !(wc->masks.mpls_lse & htonl(MPLS_BOS_MASK));
+        return !(wc->masks.mpls_lse[2] & htonl(MPLS_BOS_MASK));
 
     case MFF_IPV4_SRC:
         return !wc->masks.nw_src;
@@ -985,7 +1033,7 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
 
     case MFF_N_IDS:
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -1016,21 +1064,7 @@ mf_is_mask_valid(const struct mf_field *mf, const union mf_value *mask)
         return true;
     }
 
-    NOT_REACHED();
-}
-
-static bool
-is_icmpv4(const struct flow *flow)
-{
-    return (flow->dl_type == htons(ETH_TYPE_IP)
-            && flow->nw_proto == IPPROTO_ICMP);
-}
-
-static bool
-is_icmpv6(const struct flow *flow)
-{
-    return (flow->dl_type == htons(ETH_TYPE_IPV6)
-            && flow->nw_proto == IPPROTO_ICMPV6);
+    OVS_NOT_REACHED();
 }
 
 /* Returns true if 'flow' meets the prerequisites for 'mf', false otherwise. */
@@ -1081,7 +1115,7 @@ mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow)
                 && (flow->tp_src == htons(ND_NEIGHBOR_ADVERT)));
     }
 
-    NOT_REACHED();
+    OVS_NOT_REACHED();
 }
 
 /* Set field and it's prerequisities in the mask.
@@ -1138,6 +1172,8 @@ bool
 mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
 {
     switch (mf->id) {
+    case MFF_DP_HASH:
+    case MFF_RECIRC_ID:
     case MFF_TUN_ID:
     case MFF_TUN_SRC:
     case MFF_TUN_DST:
@@ -1149,6 +1185,7 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
     case MFF_SKB_PRIORITY:
     case MFF_PKT_MARK:
     CASE_MFF_REGS:
+    CASE_MFF_XREGS:
     case MFF_ETH_SRC:
     case MFF_ETH_DST:
     case MFF_ETH_TYPE:
@@ -1220,7 +1257,7 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
 
     case MFF_N_IDS:
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -1231,6 +1268,12 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
              union mf_value *value)
 {
     switch (mf->id) {
+    case MFF_DP_HASH:
+        value->be32 = htonl(flow->dp_hash);
+        break;
+    case MFF_RECIRC_ID:
+        value->be32 = htonl(flow->recirc_id);
+        break;
     case MFF_TUN_ID:
         value->be64 = flow->tunnel.tun_id;
         break;
@@ -1273,6 +1316,10 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
         value->be32 = htonl(flow->regs[mf->id - MFF_REG0]);
         break;
 
+    CASE_MFF_XREGS:
+        value->be64 = htonll(flow_get_xreg(flow, mf->id - MFF_XREG0));
+        break;
+
     case MFF_ETH_SRC:
         memcpy(value->mac, flow->dl_src, ETH_ADDR_LEN);
         break;
@@ -1302,15 +1349,15 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
         break;
 
     case MFF_MPLS_LABEL:
-        value->be32 = htonl(mpls_lse_to_label(flow->mpls_lse));
+        value->be32 = htonl(mpls_lse_to_label(flow->mpls_lse[0]));
         break;
 
     case MFF_MPLS_TC:
-        value->u8 = mpls_lse_to_tc(flow->mpls_lse);
+        value->u8 = mpls_lse_to_tc(flow->mpls_lse[0]);
         break;
 
     case MFF_MPLS_BOS:
-        value->u8 = mpls_lse_to_bos(flow->mpls_lse);
+        value->u8 = mpls_lse_to_bos(flow->mpls_lse[0]);
         break;
 
     case MFF_IPV4_SRC:
@@ -1411,7 +1458,7 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
 
     case MFF_N_IDS:
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -1423,6 +1470,12 @@ mf_set_value(const struct mf_field *mf,
              const union mf_value *value, struct match *match)
 {
     switch (mf->id) {
+    case MFF_DP_HASH:
+        match_set_dp_hash(match, ntohl(value->be32));
+        break;
+    case MFF_RECIRC_ID:
+        match_set_recirc_id(match, ntohl(value->be32));
+        break;
     case MFF_TUN_ID:
         match_set_tun_id(match, value->be64);
         break;
@@ -1469,6 +1522,10 @@ mf_set_value(const struct mf_field *mf,
         match_set_reg(match, mf->id - MFF_REG0, ntohl(value->be32));
         break;
 
+    CASE_MFF_XREGS:
+        match_set_xreg(match, mf->id - MFF_XREG0, ntohll(value->be64));
+        break;
+
     case MFF_ETH_SRC:
         match_set_dl_src(match, value->mac);
         break;
@@ -1498,15 +1555,15 @@ mf_set_value(const struct mf_field *mf,
         break;
 
     case MFF_MPLS_LABEL:
-        match_set_mpls_label(match, value->be32);
+        match_set_mpls_label(match, 0, value->be32);
         break;
 
     case MFF_MPLS_TC:
-        match_set_mpls_tc(match, value->u8);
+        match_set_mpls_tc(match, 0, value->u8);
         break;
 
     case MFF_MPLS_BOS:
-        match_set_mpls_bos(match, value->u8);
+        match_set_mpls_bos(match, 0, value->u8);
         break;
 
     case MFF_IPV4_SRC:
@@ -1607,7 +1664,7 @@ mf_set_value(const struct mf_field *mf,
 
     case MFF_N_IDS:
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -1636,6 +1693,12 @@ mf_set_flow_value(const struct mf_field *mf,
                   const union mf_value *value, struct flow *flow)
 {
     switch (mf->id) {
+    case MFF_DP_HASH:
+        flow->dp_hash = ntohl(value->be32);
+        break;
+    case MFF_RECIRC_ID:
+        flow->recirc_id = ntohl(value->be32);
+        break;
     case MFF_TUN_ID:
         flow->tunnel.tun_id = value->be64;
         break;
@@ -1682,6 +1745,10 @@ mf_set_flow_value(const struct mf_field *mf,
         flow->regs[mf->id - MFF_REG0] = ntohl(value->be32);
         break;
 
+    CASE_MFF_XREGS:
+        flow_set_xreg(flow, mf->id - MFF_XREG0, ntohll(value->be64));
+        break;
+
     case MFF_ETH_SRC:
         memcpy(flow->dl_src, value->mac, ETH_ADDR_LEN);
         break;
@@ -1711,15 +1778,15 @@ mf_set_flow_value(const struct mf_field *mf,
         break;
 
     case MFF_MPLS_LABEL:
-        flow_set_mpls_label(flow, value->be32);
+        flow_set_mpls_label(flow, 0, value->be32);
         break;
 
     case MFF_MPLS_TC:
-        flow_set_mpls_tc(flow, value->u8);
+        flow_set_mpls_tc(flow, 0, value->u8);
         break;
 
     case MFF_MPLS_BOS:
-        flow_set_mpls_bos(flow, value->u8);
+        flow_set_mpls_bos(flow, 0, value->u8);
         break;
 
     case MFF_IPV4_SRC:
@@ -1766,7 +1833,7 @@ mf_set_flow_value(const struct mf_field *mf,
         break;
 
     case MFF_IP_FRAG:
-        flow->nw_frag &= value->u8;
+        flow->nw_frag = value->u8 & FLOW_NW_FRAG_MASK;
         break;
 
     case MFF_ARP_OP:
@@ -1823,7 +1890,7 @@ mf_set_flow_value(const struct mf_field *mf,
 
     case MFF_N_IDS:
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -1848,6 +1915,14 @@ void
 mf_set_wild(const struct mf_field *mf, struct match *match)
 {
     switch (mf->id) {
+    case MFF_DP_HASH:
+        match->flow.dp_hash = 0;
+        match->wc.masks.dp_hash = 0;
+        break;
+    case MFF_RECIRC_ID:
+        match->flow.recirc_id = 0;
+        match->wc.masks.recirc_id = 0;
+        break;
     case MFF_TUN_ID:
         match_set_tun_id_masked(match, htonll(0), htonll(0));
         break;
@@ -1891,6 +1966,10 @@ mf_set_wild(const struct mf_field *mf, struct match *match)
         match_set_reg_masked(match, mf->id - MFF_REG0, 0, 0);
         break;
 
+    CASE_MFF_XREGS:
+        match_set_xreg_masked(match, mf->id - MFF_XREG0, 0, 0);
+        break;
+
     case MFF_ETH_SRC:
         memset(match->flow.dl_src, 0, ETH_ADDR_LEN);
         memset(match->wc.masks.dl_src, 0, ETH_ADDR_LEN);
@@ -1921,15 +2000,15 @@ mf_set_wild(const struct mf_field *mf, struct match *match)
         break;
 
     case MFF_MPLS_LABEL:
-        match_set_any_mpls_label(match);
+        match_set_any_mpls_label(match, 0);
         break;
 
     case MFF_MPLS_TC:
-        match_set_any_mpls_tc(match);
+        match_set_any_mpls_tc(match, 0);
         break;
 
     case MFF_MPLS_BOS:
-        match_set_any_mpls_bos(match);
+        match_set_any_mpls_bos(match, 0);
         break;
 
     case MFF_IPV4_SRC:
@@ -2031,7 +2110,7 @@ mf_set_wild(const struct mf_field *mf, struct match *match)
 
     case MFF_N_IDS:
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -2060,6 +2139,7 @@ mf_set(const struct mf_field *mf,
     }
 
     switch (mf->id) {
+    case MFF_RECIRC_ID:
     case MFF_IN_PORT:
     case MFF_IN_PORT_OXM:
     case MFF_SKB_PRIORITY:
@@ -2082,6 +2162,9 @@ mf_set(const struct mf_field *mf,
     case MFF_ICMPV6_CODE:
         return OFPUTIL_P_NONE;
 
+    case MFF_DP_HASH:
+        match_set_dp_hash_masked(match, ntohl(value->be32), ntohl(mask->be32));
+        break;
     case MFF_TUN_ID:
         match_set_tun_id_masked(match, value->be64, mask->be64);
         break;
@@ -2110,6 +2193,11 @@ mf_set(const struct mf_field *mf,
                              ntohl(value->be32), ntohl(mask->be32));
         break;
 
+    CASE_MFF_XREGS:
+        match_set_xreg_masked(match, mf->id - MFF_XREG0,
+                              ntohll(value->be64), ntohll(mask->be64));
+        break;
+
     case MFF_PKT_MARK:
         match_set_pkt_mark_masked(match, ntohl(value->be32),
                                   ntohl(mask->be32));
@@ -2199,7 +2287,7 @@ mf_set(const struct mf_field *mf,
 
     case MFF_N_IDS:
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 
     return mf->usable_protocols_bitwise;
@@ -2673,7 +2761,7 @@ mf_parse(const struct mf_field *mf, const char *s,
         break;
 
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 
     if (!error && !mf_is_mask_valid(mf, mask)) {
@@ -2827,7 +2915,7 @@ mf_format(const struct mf_field *mf,
         break;
 
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 \f