This may be used in a similar way to nxm_mf_fields
to handle parsing and serialisation of OXM TLVs.

Signed-off-by: Simon Horman <ho...@verge.net.au>
---
 include/openflow/openflow-1.2.h |    1 +
 lib/meta-flow.c                 |  404 +++++++++++++++++++++++++++++++++++++++
 lib/meta-flow.h                 |   16 ++
 3 files changed, 421 insertions(+)

diff --git a/include/openflow/openflow-1.2.h b/include/openflow/openflow-1.2.h
index 0fafe2c..eefc48b 100644
--- a/include/openflow/openflow-1.2.h
+++ b/include/openflow/openflow-1.2.h
@@ -114,6 +114,7 @@ enum oxm12_ofb_match_fields {
     OFPXMT12_OFB_IPV6_ND_TLL,    /* Target link-layer for ND. */
     OFPXMT12_OFB_MPLS_LABEL,     /* MPLS label. */
     OFPXMT12_OFB_MPLS_TC,        /* MPLS TC. */
+    OFPXMT12_OFB_MAX
 };
 
 /* OXM implementation makes use of NXM as they are the same format
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index d4a7072..cabd83c 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -399,6 +399,352 @@ static const struct mf_field nxm_mf_fields[MFF_N_IDS] = {
     }
 };
 
+static const struct mf_field oxm_mf_fields[OFPXMT12_OFB_MAX] = {
+    /* ## -------- ## */
+    /* ## metadata ## */
+    /* ## -------- ## */
+
+    {
+        MFF_IN_PORT, "in_port", NULL,
+        MF_FIELD_SIZES(be32),
+        MFM_NONE, FWW_IN_PORT,
+        MFS_OFP_PORT,
+        MFP_NONE,
+        false,
+        OXM_OF_IN_PORT, "OXM_OF_IN_PORT",
+    },
+    {
+        MFF_IN_PHY_PORT, "in_phy_port", NULL,
+        MF_FIELD_SIZES(be32),
+        MFM_NONE, 0,
+        MFS_DECIMAL,
+        MFP_IN_PORT,
+        false,
+        OXM_OF_IN_PHY_PORT, "OXM_OF_IN_PHY_PORT",
+    },
+    {
+        MFF_METADATA, "metadata", NULL,
+        MF_FIELD_SIZES(be64),
+        MFM_FULLY, 0,
+        MFS_HEXADECIMAL,
+        MFP_NONE,
+        false,
+        OXM_OF_METADATA, "OXM_OF_METADATA",
+    },
+
+    /* ## -- ## */
+    /* ## L2 ## */
+    /* ## -- ## */
+
+    {
+        MFF_ETH_DST, "eth_dst", NULL,
+        MF_FIELD_SIZES(mac),
+        MFM_MCAST, 0,
+        MFS_ETHERNET,
+        MFP_NONE,
+        true,
+        OXM_OF_ETH_DST, "OXM_OF_ETH_DST",
+    },
+    {
+        MFF_ETH_SRC, "eth_src", NULL,
+        MF_FIELD_SIZES(mac),
+        MFM_MCAST, FWW_DL_SRC,
+        MFS_ETHERNET,
+        MFP_NONE,
+        true,
+        OXM_OF_ETH_SRC, "OXM_OF_ETH_SRC",
+    }, {
+        MFF_ETH_TYPE, "eth_type", NULL,
+        MF_FIELD_SIZES(be16),
+        MFM_NONE, FWW_DL_TYPE,
+        MFS_HEXADECIMAL,
+        MFP_NONE,
+        false,
+        OXM_OF_ETH_TYPE, "OXM_OF_ETH_TYPE",
+    },
+
+    {
+        MFF_VLAN_VID, "dl_vlan", NULL,
+        sizeof(ovs_be16), 12,
+        MFM_NONE, 0,
+        MFS_DECIMAL,
+        MFP_NONE,
+        true,
+        OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID"
+    }, {
+        MFF_VLAN_PCP, "dl_vlan_pcp", NULL,
+        1, 3,
+        MFM_NONE, 0,
+        MFS_DECIMAL,
+        MFP_VID,
+        true,
+        OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP"
+    },
+
+    /* ## ------ ## */
+    /* ## L"2.5" ## */
+    /* ## ------ ## */
+
+    {
+        MFF_MPLS_LABEL, "mpls_label", NULL,
+        5, 20,
+        MFM_NONE, 0,
+        MFS_DECIMAL,
+        MFP_MPLS_ANY,
+        true,
+        OXM_OF_MPLS_LABEL, "OXM_OF_MPLS_LABEL"
+    }, {
+        MFF_MPLS_TC, "mpls_tc", NULL,
+        1, 3,
+        MFM_NONE, 0,
+        MFS_DECIMAL,
+        MFP_MPLS_ANY,
+        true,
+        OXM_OF_MPLS_TC, "OXM_OF_MPLS_TC"
+    },
+
+    /* ## -- ## */
+    /* ## L3 ## */
+    /* ## -- ## */
+
+    {
+        MFF_IP_DSCP, "ip_dscp", NULL,
+       1, 6,
+        MFM_NONE, FWW_NW_DSCP,
+        MFS_DECIMAL,
+        MFP_IP_ANY,
+        true,
+        OXM_OF_IP_DSCP, "OXM_OF_IP_DSCP"
+    }, {
+        MFF_IP_ECN, "ip_ecn", NULL,
+        1, 2,
+        MFM_NONE, FWW_NW_ECN,
+        MFS_DECIMAL,
+        MFP_IP_ANY,
+        true,
+        OXM_OF_IP_ECN, "OXM_OF_IP_ECN",
+    }, {
+        MFF_IP_PROTO, "ip_proto", NULL,
+        MF_FIELD_SIZES(u8),
+        MFM_NONE, FWW_NW_PROTO,
+        MFS_DECIMAL,
+        MFP_IP_ANY,
+        false,
+        OXM_OF_IP_PROTO, "OXM_OF_IP_PROTO",
+    },
+
+    {
+        MFF_IPV4_SRC, "ipv4_src", NULL,
+        MF_FIELD_SIZES(be32),
+        MFM_CIDR, 0,
+        MFS_IPV4,
+        MFP_IPV4,
+        true,
+        OXM_OF_IPV4_SRC, "OXM_OF_IPV4_SRC",
+    }, {
+        MFF_IPV4_DST, "ip_dst", NULL,
+        MF_FIELD_SIZES(be32),
+        MFM_CIDR, 0,
+        MFS_IPV4,
+        MFP_IPV4,
+        true,
+        OXM_OF_IPV4_DST, "OXM_OF_IPV4_DST",
+    },
+
+    {
+        MFF_IPV6_SRC, "ipv6_src", NULL,
+        MF_FIELD_SIZES(ipv6),
+        MFM_CIDR, 0,
+        MFS_IPV6,
+        MFP_IPV6,
+        true,
+        OXM_OF_IPV6_SRC, "OXM_OF_IPV6_SRC",
+    }, {
+        MFF_IPV6_DST, "ipv6_dst", NULL,
+        MF_FIELD_SIZES(ipv6),
+        MFM_CIDR, 0,
+        MFS_IPV6,
+        MFP_IPV6,
+        true,
+        OXM_OF_IPV6_DST, "OXM_OF_IPV6_DST",
+    },
+    {
+        MFF_IPV6_LABEL, "ipv6_flabel", NULL,
+        5, 20,
+        MFM_NONE, FWW_IPV6_LABEL,
+        MFS_HEXADECIMAL,
+        MFP_IPV6,
+        false,
+        OXM_OF_IPV6_FLABEL, "OXM_OF_IPV6_FLABEL",
+    },
+
+    {
+        MFF_ARP_OP, "arp_op", NULL,
+        MF_FIELD_SIZES(be16),
+        MFM_NONE, FWW_NW_PROTO,
+        MFS_DECIMAL,
+        MFP_ARP,
+        false,
+        OXM_OF_ARP_OP, "OXM_OF_ARP_OP",
+    }, {
+        MFF_ARP_SPA, "arp_spa", NULL,
+        MF_FIELD_SIZES(be32),
+        MFM_CIDR, 0,
+        MFS_IPV4,
+        MFP_ARP,
+        false,
+        OXM_OF_ARP_SPA, "OXM_OF_ARP_SPA",
+    }, {
+        MFF_ARP_TPA, "arp_tpa", NULL,
+        MF_FIELD_SIZES(be32),
+        MFM_CIDR, 0,
+        MFS_IPV4,
+        MFP_ARP,
+        false,
+        OXM_OF_ARP_TPA, "OXM_OF_ARP_TPA",
+    }, {
+        MFF_ARP_SHA, "arp_sha", NULL,
+        MF_FIELD_SIZES(mac),
+        MFM_NONE, FWW_ARP_SHA,
+        MFS_ETHERNET,
+        MFP_ARP,
+        false,
+        OXM_OF_ARP_SHA, "OXM_OF_ARP_SHA",
+    }, {
+        MFF_ARP_THA, "arp_tha", NULL,
+        MF_FIELD_SIZES(mac),
+        MFM_NONE, FWW_ARP_THA,
+        MFS_ETHERNET,
+        MFP_ARP,
+        false,
+        OXM_OF_ARP_THA, "OXM_OF_ARP_THA",
+    },
+
+    /* ## -- ## */
+    /* ## L4 ## */
+    /* ## -- ## */
+
+    {
+        MFF_TCP_SRC, "tcp_src", NULL,
+        MF_FIELD_SIZES(be16),
+        MFM_FULLY, 0,
+        MFS_DECIMAL,
+        MFP_TCP,
+        true,
+        OXM_OF_TCP_SRC, "OXM_OF_TCP_SRC",
+    }, {
+        MFF_TCP_DST, "tcp_dst", NULL,
+        MF_FIELD_SIZES(be16),
+        MFM_FULLY, 0,
+        MFS_DECIMAL,
+        MFP_TCP,
+        true,
+        OXM_OF_TCP_DST, "OXM_OF_TCP_DST",
+    },
+
+    {
+        MFF_UDP_SRC, "udp_src", NULL,
+        MF_FIELD_SIZES(be16),
+        MFM_FULLY, 0,
+        MFS_DECIMAL,
+        MFP_UDP,
+        true,
+        OXM_OF_UDP_SRC, "OXM_OF_UDP_SRC",
+    }, {
+        MFF_UDP_DST, "udp_dst", NULL,
+        MF_FIELD_SIZES(be16),
+        MFM_FULLY, 0,
+        MFS_DECIMAL,
+        MFP_UDP,
+        true,
+        OXM_OF_UDP_DST, "OXM_OF_UDP_DST",
+    },
+
+    {
+        MFF_SCTP_SRC, "sctp_src", NULL,
+        MF_FIELD_SIZES(be16),
+        MFM_FULLY, 0,
+        MFS_DECIMAL,
+        MFP_UDP,
+        true,
+        OXM_OF_SCTP_SRC, "OXM_OF_SCTP_SRC",
+    }, {
+        MFF_SCTP_DST, "sctp_dst", NULL,
+        MF_FIELD_SIZES(be16),
+        MFM_FULLY, 0,
+        MFS_DECIMAL,
+        MFP_UDP,
+        true,
+        OXM_OF_SCTP_DST, "OXM_OF_SCTP_DST",
+    },
+
+    {
+        MFF_ICMPV4_TYPE, "icmpv4_type", NULL,
+        MF_FIELD_SIZES(u8),
+        MFM_NONE, 0,
+        MFS_DECIMAL,
+        MFP_ICMPV4,
+        false,
+        OXM_OF_ICMPV4_TYPE, "OXM_OF_ICMPV4_TYPE",
+    }, {
+        MFF_ICMPV4_CODE, "icmpv4_code", NULL,
+        MF_FIELD_SIZES(u8),
+        MFM_NONE, 0,
+        MFS_DECIMAL,
+        MFP_ICMPV4,
+        false,
+        OXM_OF_ICMPV4_CODE, "OXM_OF_ICMPV4_CODE",
+    },
+
+    {
+        MFF_ICMPV6_TYPE, "icmpv6_type", NULL,
+        MF_FIELD_SIZES(u8),
+        MFM_NONE, 0,
+        MFS_DECIMAL,
+        MFP_ICMPV6,
+        false,
+        OXM_OF_ICMPV6_TYPE, "OXM_OF_ICMPV6_TYPE",
+    }, {
+        MFF_ICMPV6_CODE, "icmpv6_code", NULL,
+        MF_FIELD_SIZES(u8),
+        MFM_NONE, 0,
+        MFS_DECIMAL,
+        MFP_ICMPV6,
+        false,
+        OXM_OF_ICMPV6_CODE, "OXM_OF_ICMPV6_CODE",
+    },
+
+    /* ## ---- ## */
+    /* ## L"5" ## */
+    /* ## ---- ## */
+
+    {
+        MFF_ND_TARGET, "ipv6_nd_target", NULL,
+        MF_FIELD_SIZES(ipv6),
+        MFM_NONE, FWW_ND_TARGET,
+        MFS_IPV6,
+        MFP_ND,
+        false,
+        OXM_OF_IPV6_ND_TARGET, "OXM_OF_IPV6_ND_TARGET",
+    }, {
+        MFF_ND_SLL, "ipv6_nd_sll", NULL,
+        MF_FIELD_SIZES(mac),
+        MFM_NONE, FWW_ARP_SHA,
+        MFS_ETHERNET,
+        MFP_ND_SOLICIT,
+        false,
+        OXM_OF_IPV6_ND_SLL, "OXM_OF_IPV6_ND_SLL",
+    }, {
+        MFF_ND_TLL, "ipv6_nd_tll", NULL,
+        MF_FIELD_SIZES(mac),
+        MFM_NONE, FWW_ARP_THA,
+        MFS_ETHERNET,
+        MFP_ND_ADVERT,
+        false,
+        OXM_OF_IPV6_ND_TLL, "OXM_OF_IPV6_ND_TLL",
+    }
+};
+
 struct nxm_field {
     struct hmap_node hmap_node;
     uint32_t nxm_header;
@@ -597,6 +943,12 @@ mf_is_all_wild(const struct mf_field *mf, const struct 
flow_wildcards *wc)
         return !wc->tp_dst_mask;
 
     case MFF_N_IDS:
+    case MFF_IN_PHY_PORT:
+    case MFF_METADATA:
+    case MFF_MPLS_LABEL:
+    case MFF_MPLS_TC:
+    case MFF_SCTP_SRC:
+    case MFF_SCTP_DST:
     default:
         NOT_REACHED();
     }
@@ -724,6 +1076,12 @@ mf_get_mask(const struct mf_field *mf, const struct 
flow_wildcards *wc,
         break;
 
     case MFF_N_IDS:
+    case MFF_IN_PHY_PORT:
+    case MFF_METADATA:
+    case MFF_MPLS_LABEL:
+    case MFF_MPLS_TC:
+    case MFF_SCTP_SRC:
+    case MFF_SCTP_DST:
     default:
         NOT_REACHED();
     }
@@ -814,6 +1172,10 @@ mf_are_prereqs_ok(const struct mf_field *mf, const struct 
flow *flow)
         return (is_icmpv6(flow)
                 && flow->tp_dst == htons(0)
                 && (flow->tp_src == htons(ND_NEIGHBOR_ADVERT)));
+
+    case MFP_IN_PORT:
+    case MFP_MPLS_ANY:
+        NOT_REACHED();
     }
 
     NOT_REACHED();
@@ -909,6 +1271,12 @@ mf_is_value_valid(const struct mf_field *mf, const union 
mf_value *value)
         return !(value->be32 & ~htonl(IPV6_LABEL_MASK));
 
     case MFF_N_IDS:
+    case MFF_IN_PHY_PORT:
+    case MFF_METADATA:
+    case MFF_MPLS_LABEL:
+    case MFF_MPLS_TC:
+    case MFF_SCTP_SRC:
+    case MFF_SCTP_DST:
     default:
         NOT_REACHED();
     }
@@ -1076,6 +1444,12 @@ mf_get_value(const struct mf_field *mf, const struct 
flow *flow,
         break;
 
     case MFF_N_IDS:
+    case MFF_IN_PHY_PORT:
+    case MFF_METADATA:
+    case MFF_MPLS_LABEL:
+    case MFF_MPLS_TC:
+    case MFF_SCTP_SRC:
+    case MFF_SCTP_DST:
     default:
         NOT_REACHED();
     }
@@ -1246,6 +1620,12 @@ mf_set_value(const struct mf_field *mf,
         break;
 
     case MFF_N_IDS:
+    case MFF_IN_PHY_PORT:
+    case MFF_METADATA:
+    case MFF_MPLS_LABEL:
+    case MFF_MPLS_TC:
+    case MFF_SCTP_SRC:
+    case MFF_SCTP_DST:
     default:
         NOT_REACHED();
     }
@@ -1412,6 +1792,12 @@ mf_set_flow_value(const struct mf_field *mf,
         break;
 
     case MFF_N_IDS:
+    case MFF_IN_PHY_PORT:
+    case MFF_METADATA:
+    case MFF_MPLS_LABEL:
+    case MFF_MPLS_TC:
+    case MFF_SCTP_SRC:
+    case MFF_SCTP_DST:
     default:
         NOT_REACHED();
     }
@@ -1594,6 +1980,12 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule 
*rule)
         break;
 
     case MFF_N_IDS:
+    case MFF_IN_PHY_PORT:
+    case MFF_METADATA:
+    case MFF_MPLS_LABEL:
+    case MFF_MPLS_TC:
+    case MFF_SCTP_SRC:
+    case MFF_SCTP_DST:
     default:
         NOT_REACHED();
     }
@@ -1730,6 +2122,12 @@ mf_set(const struct mf_field *mf,
         break;
 
     case MFF_N_IDS:
+    case MFF_IN_PHY_PORT:
+    case MFF_METADATA:
+    case MFF_MPLS_LABEL:
+    case MFF_MPLS_TC:
+    case MFF_SCTP_SRC:
+    case MFF_SCTP_DST:
     default:
         NOT_REACHED();
     }
@@ -1886,6 +2284,12 @@ mf_random_value(const struct mf_field *mf, union 
mf_value *value)
         break;
 
     case MFF_N_IDS:
+    case MFF_IN_PHY_PORT:
+    case MFF_METADATA:
+    case MFF_MPLS_LABEL:
+    case MFF_MPLS_TC:
+    case MFF_SCTP_SRC:
+    case MFF_SCTP_DST:
     default:
         NOT_REACHED();
     }
diff --git a/lib/meta-flow.h b/lib/meta-flow.h
index 91d52c7..e268d14 100644
--- a/lib/meta-flow.h
+++ b/lib/meta-flow.h
@@ -33,6 +33,8 @@ enum mf_field_id {
     /* Metadata. */
     MFF_TUN_ID,                 /* be64 */
     MFF_IN_PORT,                /* be16 */
+    MFF_IN_PHY_PORT,            /* be32 */
+    MFF_METADATA,               /* be64 */
 
 #if FLOW_N_REGS > 0
     MFF_REG0,                   /* be32 */
@@ -71,6 +73,10 @@ enum mf_field_id {
     MFF_VLAN_VID,               /* be16 */
     MFF_VLAN_PCP,               /* u8 */
 
+    /* L2.5 */
+    MFF_MPLS_LABEL,            /* be64 */
+    MFF_MPLS_TC,                /* be64 */
+
     /* L3. */
     MFF_IPV4_SRC,               /* be32 */
     MFF_IPV4_DST,               /* be32 */
@@ -98,6 +104,9 @@ enum mf_field_id {
     MFF_UDP_SRC,                /* be16 (used for IPv4 or IPv6) */
     MFF_UDP_DST,                /* be16 (used for IPv4 or IPv6) */
 
+    MFF_SCTP_SRC,               /* be16 (used for IPv4 or IPv6) */
+    MFF_SCTP_DST,               /* be16 (used for IPv4 or IPv6) */
+
     MFF_ICMPV4_TYPE,            /* u8 */
     MFF_ICMPV4_CODE,            /* u8 */
 
@@ -120,12 +129,19 @@ enum mf_field_id {
 enum mf_prereqs {
     MFP_NONE,
 
+    /* Metadata requirements. */
+    MFP_IN_PORT,
+
     /* L2 requirements. */
+    MFP_VID,
     MFP_ARP,
     MFP_IPV4,
     MFP_IPV6,
     MFP_IP_ANY,
 
+    /* L2.5 requirements. */
+    MFP_MPLS_ANY,
+
     /* L2+L3 requirements. */
     MFP_TCP,                    /* On IPv4 or IPv6. */
     MFP_UDP,                    /* On IPv4 or IPv6. */
-- 
1.7.9.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to