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