also, implement text <-> binary convertions for field values.  this will
be used for later ofproto api refinement.  (and probably stringify stuff)

Signed-off-by: YAMAMOTO Takashi <[email protected]>
---
 ryu/ofproto/ofproto_v1_2.py | 130 +++++++++++----------------------
 ryu/ofproto/ofproto_v1_3.py | 144 ++++++++++++------------------------
 ryu/ofproto/oxm_fields.py   | 173 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 261 insertions(+), 186 deletions(-)
 create mode 100644 ryu/ofproto/oxm_fields.py

diff --git a/ryu/ofproto/ofproto_v1_2.py b/ryu/ofproto/ofproto_v1_2.py
index d1ad9c2..16cf205 100644
--- a/ryu/ofproto/ofproto_v1_2.py
+++ b/ryu/ofproto/ofproto_v1_2.py
@@ -14,6 +14,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from ryu.ofproto import oxm_fields
+
 from struct import calcsize
 
 # struct ofp_header
@@ -164,44 +166,6 @@ OFPXMC_NXM_1 = 0x0001  # Backward compatibility with NXM
 OFPXMC_OPENFLOW_BASIC = 0x8000  # Basic class for OpenFlow
 OFPXMC_EXPERIMENTER = 0xFFFF  # Experimenter class
 
-# enmu oxm_ofb_match_fields
-OFPXMT_OFB_IN_PORT = 0  # Switch input port.
-OFPXMT_OFB_IN_PHY_PORT = 1  # Switch physical input port.
-OFPXMT_OFB_METADATA = 2  # Metadata passed between tables.
-OFPXMT_OFB_ETH_DST = 3  # Ethernet destination address.
-OFPXMT_OFB_ETH_SRC = 4  # Ethernet source address.
-OFPXMT_OFB_ETH_TYPE = 5  # Ethernet frame type.
-OFPXMT_OFB_VLAN_VID = 6  # VLAN id.
-OFPXMT_OFB_VLAN_PCP = 7  # VLAN priority.
-OFPXMT_OFB_IP_DSCP = 8  # IP DSCP (6 bits in ToS field).
-OFPXMT_OFB_IP_ECN = 9  # IP ECN (2 bits in ToS field).
-OFPXMT_OFB_IP_PROTO = 10  # IP protocol.
-OFPXMT_OFB_IPV4_SRC = 11  # IPv4 source address.
-OFPXMT_OFB_IPV4_DST = 12  # IPv4 destination address.
-OFPXMT_OFB_TCP_SRC = 13  # TCP source port.
-OFPXMT_OFB_TCP_DST = 14  # TCP destination port.
-OFPXMT_OFB_UDP_SRC = 15  # UDP source port.
-OFPXMT_OFB_UDP_DST = 16  # UDP destination port.
-OFPXMT_OFB_SCTP_SRC = 17  # SCTP source port.
-OFPXMT_OFB_SCTP_DST = 18  # SCTP destination port.
-OFPXMT_OFB_ICMPV4_TYPE = 19  # ICMP type.
-OFPXMT_OFB_ICMPV4_CODE = 20  # ICMP code.
-OFPXMT_OFB_ARP_OP = 21  # ARP opcode.
-OFPXMT_OFB_ARP_SPA = 22  # ARP source IPv4 address.
-OFPXMT_OFB_ARP_TPA = 23  # ARP target IPv4 address.
-OFPXMT_OFB_ARP_SHA = 24  # ARP source hardware address.
-OFPXMT_OFB_ARP_THA = 25  # ARP target hardware address.
-OFPXMT_OFB_IPV6_SRC = 26  # IPv6 source address.
-OFPXMT_OFB_IPV6_DST = 27  # IPv6 destination address.
-OFPXMT_OFB_IPV6_FLABEL = 28  # IPv6 Flow Label
-OFPXMT_OFB_ICMPV6_TYPE = 29  # ICMPv6 type.
-OFPXMT_OFB_ICMPV6_CODE = 30  # ICMPv6 code.
-OFPXMT_OFB_IPV6_ND_TARGET = 31  # Target address for ND.
-OFPXMT_OFB_IPV6_ND_SLL = 32  # Source link-layer for ND.
-OFPXMT_OFB_IPV6_ND_TLL = 33  # Target link-layer for ND.
-OFPXMT_OFB_MPLS_LABEL = 34  # MPLS label.
-OFPXMT_OFB_MPLS_TC = 35  # MPLS TC.
-
 # enum ofp_vlan_id
 OFPVID_PRESENT = 0x1000  # bit that indicate that a VLAN id is set.
 OFPVID_NONE = 0x0000  # No VLAN id was set.
@@ -816,56 +780,46 @@ def oxm_tlv_header_extract_length(header):
         length = header & 0xff
     return length
 
-
-OXM_OF_IN_PORT = oxm_tlv_header(OFPXMT_OFB_IN_PORT, 4)
-OXM_OF_IN_PHY_PORT = oxm_tlv_header(OFPXMT_OFB_IN_PHY_PORT, 4)
-OXM_OF_METADATA = oxm_tlv_header(OFPXMT_OFB_METADATA, 8)
-OXM_OF_METADATA_W = oxm_tlv_header_w(OFPXMT_OFB_METADATA, 8)
-OXM_OF_ETH_DST = oxm_tlv_header(OFPXMT_OFB_ETH_DST, 6)
-OXM_OF_ETH_DST_W = oxm_tlv_header_w(OFPXMT_OFB_ETH_DST, 6)
-OXM_OF_ETH_SRC = oxm_tlv_header(OFPXMT_OFB_ETH_SRC, 6)
-OXM_OF_ETH_SRC_W = oxm_tlv_header_w(OFPXMT_OFB_ETH_SRC, 6)
-OXM_OF_ETH_TYPE = oxm_tlv_header(OFPXMT_OFB_ETH_TYPE, 2)
-OXM_OF_VLAN_VID = oxm_tlv_header(OFPXMT_OFB_VLAN_VID, 2)
-OXM_OF_VLAN_VID_W = oxm_tlv_header_w(OFPXMT_OFB_VLAN_VID, 2)
-OXM_OF_VLAN_PCP = oxm_tlv_header(OFPXMT_OFB_VLAN_PCP, 1)
-OXM_OF_IP_DSCP = oxm_tlv_header(OFPXMT_OFB_IP_DSCP, 1)
-OXM_OF_IP_ECN = oxm_tlv_header(OFPXMT_OFB_IP_ECN, 1)
-OXM_OF_IP_PROTO = oxm_tlv_header(OFPXMT_OFB_IP_PROTO, 1)
-OXM_OF_IPV4_SRC = oxm_tlv_header(OFPXMT_OFB_IPV4_SRC, 4)
-OXM_OF_IPV4_SRC_W = oxm_tlv_header_w(OFPXMT_OFB_IPV4_SRC, 4)
-OXM_OF_IPV4_DST = oxm_tlv_header(OFPXMT_OFB_IPV4_DST, 4)
-OXM_OF_IPV4_DST_W = oxm_tlv_header_w(OFPXMT_OFB_IPV4_DST, 4)
-OXM_OF_TCP_SRC = oxm_tlv_header(OFPXMT_OFB_TCP_SRC, 2)
-OXM_OF_TCP_DST = oxm_tlv_header(OFPXMT_OFB_TCP_DST, 2)
-OXM_OF_UDP_SRC = oxm_tlv_header(OFPXMT_OFB_UDP_SRC, 2)
-OXM_OF_UDP_DST = oxm_tlv_header(OFPXMT_OFB_UDP_DST, 2)
-OXM_OF_SCTP_SRC = oxm_tlv_header(OFPXMT_OFB_SCTP_SRC, 2)
-OXM_OF_SCTP_DST = oxm_tlv_header(OFPXMT_OFB_SCTP_DST, 2)
-OXM_OF_ICMPV4_TYPE = oxm_tlv_header(OFPXMT_OFB_ICMPV4_TYPE, 1)
-OXM_OF_ICMPV4_CODE = oxm_tlv_header(OFPXMT_OFB_ICMPV4_CODE, 1)
-OXM_OF_ARP_OP = oxm_tlv_header(OFPXMT_OFB_ARP_OP, 2)
-OXM_OF_ARP_SPA = oxm_tlv_header(OFPXMT_OFB_ARP_SPA, 4)
-OXM_OF_ARP_SPA_W = oxm_tlv_header_w(OFPXMT_OFB_ARP_SPA, 4)
-OXM_OF_ARP_TPA = oxm_tlv_header(OFPXMT_OFB_ARP_TPA, 4)
-OXM_OF_ARP_TPA_W = oxm_tlv_header_w(OFPXMT_OFB_ARP_TPA, 4)
-OXM_OF_ARP_SHA = oxm_tlv_header(OFPXMT_OFB_ARP_SHA, 6)
-OXM_OF_ARP_SHA_W = oxm_tlv_header_w(OFPXMT_OFB_ARP_SHA, 6)
-OXM_OF_ARP_THA = oxm_tlv_header(OFPXMT_OFB_ARP_THA, 6)
-OXM_OF_ARP_THA_W = oxm_tlv_header_w(OFPXMT_OFB_ARP_THA, 6)
-OXM_OF_IPV6_SRC = oxm_tlv_header(OFPXMT_OFB_IPV6_SRC, 16)
-OXM_OF_IPV6_SRC_W = oxm_tlv_header_w(OFPXMT_OFB_IPV6_SRC, 16)
-OXM_OF_IPV6_DST = oxm_tlv_header(OFPXMT_OFB_IPV6_DST, 16)
-OXM_OF_IPV6_DST_W = oxm_tlv_header_w(OFPXMT_OFB_IPV6_DST, 16)
-OXM_OF_IPV6_FLABEL = oxm_tlv_header(OFPXMT_OFB_IPV6_FLABEL, 4)
-OXM_OF_IPV6_FLABEL_W = oxm_tlv_header_w(OFPXMT_OFB_IPV6_FLABEL, 4)
-OXM_OF_ICMPV6_TYPE = oxm_tlv_header(OFPXMT_OFB_ICMPV6_TYPE, 1)
-OXM_OF_ICMPV6_CODE = oxm_tlv_header(OFPXMT_OFB_ICMPV6_CODE, 1)
-OXM_OF_IPV6_ND_TARGET = oxm_tlv_header(OFPXMT_OFB_IPV6_ND_TARGET, 16)
-OXM_OF_IPV6_ND_SLL = oxm_tlv_header(OFPXMT_OFB_IPV6_ND_SLL, 6)
-OXM_OF_IPV6_ND_TLL = oxm_tlv_header(OFPXMT_OFB_IPV6_ND_TLL, 6)
-OXM_OF_MPLS_LABEL = oxm_tlv_header(OFPXMT_OFB_MPLS_LABEL, 4)
-OXM_OF_MPLS_TC = oxm_tlv_header(OFPXMT_OFB_MPLS_TC, 1)
+oxm_types = [
+    oxm_fields.OpenFlowBasic('in_port', 0, oxm_fields.Int4),
+    oxm_fields.OpenFlowBasic('in_phy_port', 1, oxm_fields.Int4),
+    oxm_fields.OpenFlowBasic('metadata', 2, oxm_fields.Int8),
+    oxm_fields.OpenFlowBasic('eth_dst', 3, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('eth_src', 4, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('eth_type', 5, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('vlan_vid', 6, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('vlan_pcp', 7, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('ip_dscp', 8, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('ip_ecn', 9, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('ip_proto', 10, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('ipv4_src', 11, oxm_fields.IPv4Addr),
+    oxm_fields.OpenFlowBasic('ipv4_dst', 12, oxm_fields.IPv4Addr),
+    oxm_fields.OpenFlowBasic('tcp_src', 13, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('tcp_dst', 14, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('udp_src', 15, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('udp_dst', 16, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('sctp_src', 17, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('sctp_dst', 18, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('icmpv4_type', 19, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('icmpv4_code', 20, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('arp_op', 21, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('arp_spa', 22, oxm_fields.IPv4Addr),
+    oxm_fields.OpenFlowBasic('arp_tpa', 23, oxm_fields.IPv4Addr),
+    oxm_fields.OpenFlowBasic('arp_sha', 24, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('arp_tha', 25, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('ipv6_src', 26, oxm_fields.IPv6Addr),
+    oxm_fields.OpenFlowBasic('ipv6_dst', 27, oxm_fields.IPv6Addr),
+    oxm_fields.OpenFlowBasic('ipv6_flabel', 28, oxm_fields.Int4),
+    oxm_fields.OpenFlowBasic('icmpv6_type', 29, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('icmpv6_code', 30, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('ipv6_nd_target', 31, oxm_fields.IPv6Addr),
+    oxm_fields.OpenFlowBasic('ipv6_nd_sll', 32, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('ipv6_nd_tll', 33, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('mpls_label', 34, oxm_fields.Int4),
+    oxm_fields.OpenFlowBasic('mpls_tc', 35, oxm_fields.Int1),
+]
+
+oxm_fields.generate(__name__)
 
 
 # define constants
diff --git a/ryu/ofproto/ofproto_v1_3.py b/ryu/ofproto/ofproto_v1_3.py
index 9190737..bba98ba 100644
--- a/ryu/ofproto/ofproto_v1_3.py
+++ b/ryu/ofproto/ofproto_v1_3.py
@@ -14,6 +14,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from ryu.ofproto import oxm_fields
+
 from struct import calcsize
 
 # struct ofp_header
@@ -169,48 +171,6 @@ OFPXMC_NXM_1 = 0x0001  # Backward compatibility with NXM
 OFPXMC_OPENFLOW_BASIC = 0x8000  # Basic class for OpenFlow
 OFPXMC_EXPERIMENTER = 0xFFFF  # Experimenter class
 
-# enmu oxm_ofb_match_fields
-OFPXMT_OFB_IN_PORT = 0  # Switch input port.
-OFPXMT_OFB_IN_PHY_PORT = 1  # Switch physical input port.
-OFPXMT_OFB_METADATA = 2  # Metadata passed between tables.
-OFPXMT_OFB_ETH_DST = 3  # Ethernet destination address.
-OFPXMT_OFB_ETH_SRC = 4  # Ethernet source address.
-OFPXMT_OFB_ETH_TYPE = 5  # Ethernet frame type.
-OFPXMT_OFB_VLAN_VID = 6  # VLAN id.
-OFPXMT_OFB_VLAN_PCP = 7  # VLAN priority.
-OFPXMT_OFB_IP_DSCP = 8  # IP DSCP (6 bits in ToS field).
-OFPXMT_OFB_IP_ECN = 9  # IP ECN (2 bits in ToS field).
-OFPXMT_OFB_IP_PROTO = 10  # IP protocol.
-OFPXMT_OFB_IPV4_SRC = 11  # IPv4 source address.
-OFPXMT_OFB_IPV4_DST = 12  # IPv4 destination address.
-OFPXMT_OFB_TCP_SRC = 13  # TCP source port.
-OFPXMT_OFB_TCP_DST = 14  # TCP destination port.
-OFPXMT_OFB_UDP_SRC = 15  # UDP source port.
-OFPXMT_OFB_UDP_DST = 16  # UDP destination port.
-OFPXMT_OFB_SCTP_SRC = 17  # SCTP source port.
-OFPXMT_OFB_SCTP_DST = 18  # SCTP destination port.
-OFPXMT_OFB_ICMPV4_TYPE = 19  # ICMP type.
-OFPXMT_OFB_ICMPV4_CODE = 20  # ICMP code.
-OFPXMT_OFB_ARP_OP = 21  # ARP opcode.
-OFPXMT_OFB_ARP_SPA = 22  # ARP source IPv4 address.
-OFPXMT_OFB_ARP_TPA = 23  # ARP target IPv4 address.
-OFPXMT_OFB_ARP_SHA = 24  # ARP source hardware address.
-OFPXMT_OFB_ARP_THA = 25  # ARP target hardware address.
-OFPXMT_OFB_IPV6_SRC = 26  # IPv6 source address.
-OFPXMT_OFB_IPV6_DST = 27  # IPv6 destination address.
-OFPXMT_OFB_IPV6_FLABEL = 28  # IPv6 Flow Label
-OFPXMT_OFB_ICMPV6_TYPE = 29  # ICMPv6 type.
-OFPXMT_OFB_ICMPV6_CODE = 30  # ICMPv6 code.
-OFPXMT_OFB_IPV6_ND_TARGET = 31  # Target address for ND.
-OFPXMT_OFB_IPV6_ND_SLL = 32  # Source link-layer for ND.
-OFPXMT_OFB_IPV6_ND_TLL = 33  # Target link-layer for ND.
-OFPXMT_OFB_MPLS_LABEL = 34  # MPLS label.
-OFPXMT_OFB_MPLS_TC = 35  # MPLS TC.
-OFPXMT_OFB_MPLS_BOS = 36  # MPLS BoS bit.
-OFPXMT_OFB_PBB_ISID = 37  # PBB I-SID.
-OFPXMT_OFB_TUNNEL_ID = 38  # Logical Port Metadata.
-OFPXMT_OFB_IPV6_EXTHDR = 39  # IPv6 Extension Header pseudo-field
-
 # enum ofp_vlan_id
 OFPVID_PRESENT = 0x1000  # bit that indicate that a VLAN id is set.
 OFPVID_NONE = 0x0000  # No VLAN id was set.
@@ -1057,63 +1017,51 @@ def oxm_tlv_header_extract_length(header):
         length = header & 0xff
     return length
 
+oxm_types = [
+    oxm_fields.OpenFlowBasic('in_port', 0, oxm_fields.Int4),
+    oxm_fields.OpenFlowBasic('in_phy_port', 1, oxm_fields.Int4),
+    oxm_fields.OpenFlowBasic('metadata', 2, oxm_fields.Int8),
+    oxm_fields.OpenFlowBasic('eth_dst', 3, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('eth_src', 4, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('eth_type', 5, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('vlan_vid', 6, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('vlan_pcp', 7, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('ip_dscp', 8, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('ip_ecn', 9, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('ip_proto', 10, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('ipv4_src', 11, oxm_fields.IPv4Addr),
+    oxm_fields.OpenFlowBasic('ipv4_dst', 12, oxm_fields.IPv4Addr),
+    oxm_fields.OpenFlowBasic('tcp_src', 13, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('tcp_dst', 14, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('udp_src', 15, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('udp_dst', 16, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('sctp_src', 17, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('sctp_dst', 18, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('icmpv4_type', 19, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('icmpv4_code', 20, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('arp_op', 21, oxm_fields.Int2),
+    oxm_fields.OpenFlowBasic('arp_spa', 22, oxm_fields.IPv4Addr),
+    oxm_fields.OpenFlowBasic('arp_tpa', 23, oxm_fields.IPv4Addr),
+    oxm_fields.OpenFlowBasic('arp_sha', 24, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('arp_tha', 25, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('ipv6_src', 26, oxm_fields.IPv6Addr),
+    oxm_fields.OpenFlowBasic('ipv6_dst', 27, oxm_fields.IPv6Addr),
+    oxm_fields.OpenFlowBasic('ipv6_flabel', 28, oxm_fields.Int4),
+    oxm_fields.OpenFlowBasic('icmpv6_type', 29, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('icmpv6_code', 30, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('ipv6_nd_target', 31, oxm_fields.IPv6Addr),
+    oxm_fields.OpenFlowBasic('ipv6_nd_sll', 32, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('ipv6_nd_tll', 33, oxm_fields.MacAddr),
+    oxm_fields.OpenFlowBasic('mpls_label', 34, oxm_fields.Int4),
+    oxm_fields.OpenFlowBasic('mpls_tc', 35, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('mpls_bos', 36, oxm_fields.Int1),
+    oxm_fields.OpenFlowBasic('pbb_isid', 37, oxm_fields.Int3),
+    oxm_fields.OpenFlowBasic('tunnel_id', 38, oxm_fields.Int8),
+    oxm_fields.OpenFlowBasic('ipv6_exthdr', 39, oxm_fields.Int2),
+]
+
+oxm_fields.generate(__name__)
 
-OXM_OF_IN_PORT = oxm_tlv_header(OFPXMT_OFB_IN_PORT, 4)
-OXM_OF_IN_PHY_PORT = oxm_tlv_header(OFPXMT_OFB_IN_PHY_PORT, 4)
-OXM_OF_METADATA = oxm_tlv_header(OFPXMT_OFB_METADATA, 8)
-OXM_OF_METADATA_W = oxm_tlv_header_w(OFPXMT_OFB_METADATA, 8)
-OXM_OF_ETH_DST = oxm_tlv_header(OFPXMT_OFB_ETH_DST, 6)
-OXM_OF_ETH_DST_W = oxm_tlv_header_w(OFPXMT_OFB_ETH_DST, 6)
-OXM_OF_ETH_SRC = oxm_tlv_header(OFPXMT_OFB_ETH_SRC, 6)
-OXM_OF_ETH_SRC_W = oxm_tlv_header_w(OFPXMT_OFB_ETH_SRC, 6)
-OXM_OF_ETH_TYPE = oxm_tlv_header(OFPXMT_OFB_ETH_TYPE, 2)
-OXM_OF_VLAN_VID = oxm_tlv_header(OFPXMT_OFB_VLAN_VID, 2)
-OXM_OF_VLAN_VID_W = oxm_tlv_header_w(OFPXMT_OFB_VLAN_VID, 2)
-OXM_OF_VLAN_PCP = oxm_tlv_header(OFPXMT_OFB_VLAN_PCP, 1)
-OXM_OF_IP_DSCP = oxm_tlv_header(OFPXMT_OFB_IP_DSCP, 1)
-OXM_OF_IP_ECN = oxm_tlv_header(OFPXMT_OFB_IP_ECN, 1)
-OXM_OF_IP_PROTO = oxm_tlv_header(OFPXMT_OFB_IP_PROTO, 1)
-OXM_OF_IPV4_SRC = oxm_tlv_header(OFPXMT_OFB_IPV4_SRC, 4)
-OXM_OF_IPV4_SRC_W = oxm_tlv_header_w(OFPXMT_OFB_IPV4_SRC, 4)
-OXM_OF_IPV4_DST = oxm_tlv_header(OFPXMT_OFB_IPV4_DST, 4)
-OXM_OF_IPV4_DST_W = oxm_tlv_header_w(OFPXMT_OFB_IPV4_DST, 4)
-OXM_OF_TCP_SRC = oxm_tlv_header(OFPXMT_OFB_TCP_SRC, 2)
-OXM_OF_TCP_DST = oxm_tlv_header(OFPXMT_OFB_TCP_DST, 2)
-OXM_OF_UDP_SRC = oxm_tlv_header(OFPXMT_OFB_UDP_SRC, 2)
-OXM_OF_UDP_DST = oxm_tlv_header(OFPXMT_OFB_UDP_DST, 2)
-OXM_OF_SCTP_SRC = oxm_tlv_header(OFPXMT_OFB_SCTP_SRC, 2)
-OXM_OF_SCTP_DST = oxm_tlv_header(OFPXMT_OFB_SCTP_DST, 2)
-OXM_OF_ICMPV4_TYPE = oxm_tlv_header(OFPXMT_OFB_ICMPV4_TYPE, 1)
-OXM_OF_ICMPV4_CODE = oxm_tlv_header(OFPXMT_OFB_ICMPV4_CODE, 1)
-OXM_OF_ARP_OP = oxm_tlv_header(OFPXMT_OFB_ARP_OP, 2)
-OXM_OF_ARP_SPA = oxm_tlv_header(OFPXMT_OFB_ARP_SPA, 4)
-OXM_OF_ARP_SPA_W = oxm_tlv_header_w(OFPXMT_OFB_ARP_SPA, 4)
-OXM_OF_ARP_TPA = oxm_tlv_header(OFPXMT_OFB_ARP_TPA, 4)
-OXM_OF_ARP_TPA_W = oxm_tlv_header_w(OFPXMT_OFB_ARP_TPA, 4)
-OXM_OF_ARP_SHA = oxm_tlv_header(OFPXMT_OFB_ARP_SHA, 6)
-OXM_OF_ARP_SHA_W = oxm_tlv_header_w(OFPXMT_OFB_ARP_SHA, 6)
-OXM_OF_ARP_THA = oxm_tlv_header(OFPXMT_OFB_ARP_THA, 6)
-OXM_OF_ARP_THA_W = oxm_tlv_header_w(OFPXMT_OFB_ARP_THA, 6)
-OXM_OF_IPV6_SRC = oxm_tlv_header(OFPXMT_OFB_IPV6_SRC, 16)
-OXM_OF_IPV6_SRC_W = oxm_tlv_header_w(OFPXMT_OFB_IPV6_SRC, 16)
-OXM_OF_IPV6_DST = oxm_tlv_header(OFPXMT_OFB_IPV6_DST, 16)
-OXM_OF_IPV6_DST_W = oxm_tlv_header_w(OFPXMT_OFB_IPV6_DST, 16)
-OXM_OF_IPV6_FLABEL = oxm_tlv_header(OFPXMT_OFB_IPV6_FLABEL, 4)
-OXM_OF_IPV6_FLABEL_W = oxm_tlv_header_w(OFPXMT_OFB_IPV6_FLABEL, 4)
-OXM_OF_ICMPV6_TYPE = oxm_tlv_header(OFPXMT_OFB_ICMPV6_TYPE, 1)
-OXM_OF_ICMPV6_CODE = oxm_tlv_header(OFPXMT_OFB_ICMPV6_CODE, 1)
-OXM_OF_IPV6_ND_TARGET = oxm_tlv_header(OFPXMT_OFB_IPV6_ND_TARGET, 16)
-OXM_OF_IPV6_ND_SLL = oxm_tlv_header(OFPXMT_OFB_IPV6_ND_SLL, 6)
-OXM_OF_IPV6_ND_TLL = oxm_tlv_header(OFPXMT_OFB_IPV6_ND_TLL, 6)
-OXM_OF_MPLS_LABEL = oxm_tlv_header(OFPXMT_OFB_MPLS_LABEL, 4)
-OXM_OF_MPLS_TC = oxm_tlv_header(OFPXMT_OFB_MPLS_TC, 1)
-OXM_OF_MPLS_BOS = oxm_tlv_header(OFPXMT_OFB_MPLS_BOS, 1)
-OXM_OF_PBB_ISID = oxm_tlv_header(OFPXMT_OFB_PBB_ISID, 3)
-OXM_OF_PBB_ISID_W = oxm_tlv_header_w(OFPXMT_OFB_PBB_ISID, 3)
-OXM_OF_TUNNEL_ID = oxm_tlv_header(OFPXMT_OFB_TUNNEL_ID, 8)
-OXM_OF_TUNNEL_ID_W = oxm_tlv_header_w(OFPXMT_OFB_TUNNEL_ID, 8)
-OXM_OF_IPV6_EXTHDR = oxm_tlv_header(OFPXMT_OFB_IPV6_EXTHDR, 2)
-OXM_OF_IPV6_EXTHDR_W = oxm_tlv_header_w(OFPXMT_OFB_IPV6_EXTHDR, 2)
 
 # define constants
 OFP_VERSION = 0x04
diff --git a/ryu/ofproto/oxm_fields.py b/ryu/ofproto/oxm_fields.py
new file mode 100644
index 0000000..f317da0
--- /dev/null
+++ b/ryu/ofproto/oxm_fields.py
@@ -0,0 +1,173 @@
+# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
+# Copyright (C) 2013 YAMAMOTO Takashi <yamamoto at valinux co jp>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# there are two representations of value and mask this module deal with.
+#
+# "user"
+#   (value, mask) or value.  the latter means no mask.
+#   value and mask are strings.
+#
+# "internal"
+#   value and mask are on-wire bytes.
+#   mask is None if no mask.
+
+import itertools
+
+from ryu.lib import addrconv
+
+
+class TypeDescr(object):
+    pass
+
+
+class IntDescr(TypeDescr):
+    def __init__(self, size):
+        self.size = size
+
+    def to_user(self, bin):
+        i = 0
+        for x in xrange(self.size):
+            c = bin[:1]
+            i = i * 256 + ord(c)
+            bin = bin[1:]
+        return i
+
+    def from_user(self, i):
+        bin = ''
+        for x in xrange(self.size):
+            bin = chr(i & 255) + bin
+            i /= 256
+        return bin
+
+Int1 = IntDescr(1)
+Int2 = IntDescr(2)
+Int3 = IntDescr(3)
+Int4 = IntDescr(4)
+Int8 = IntDescr(8)
+
+
+class MacAddr(TypeDescr):
+    size = 6
+    to_user = addrconv.mac.bin_to_text
+    from_user = addrconv.mac.text_to_bin
+
+
+class IPv4Addr(TypeDescr):
+    size = 4
+    to_user = addrconv.ipv4.bin_to_text
+    from_user = addrconv.ipv4.text_to_bin
+
+
+class IPv6Addr(TypeDescr):
+    size = 16
+    to_user = addrconv.ipv6.bin_to_text
+    from_user = addrconv.ipv6.text_to_bin
+
+
+class UnknownType(TypeDescr):
+    import base64
+
+    to_user = staticmethod(base64.b64encode)
+    from_user = staticmethod(base64.b64decode)
+
+
+OFPXMC_OPENFLOW_BASIC = 0x8000
+
+
+class OpenFlowBasic(object):
+    _class = OFPXMC_OPENFLOW_BASIC
+
+    def __init__(self, name, num, type_):
+        self.name = name
+        self.num = num | (self._class << 7)
+        self.type = type_
+
+
+def generate(modname):
+    import sys
+    import string
+    import functools
+
+    mod = sys.modules[modname]
+
+    def add_attr(k, v):
+        setattr(mod, k, v)
+
+    for i in mod.oxm_types:
+        uk = string.upper(i.name)
+        oxm_class = i.num >> 7
+        if oxm_class != OFPXMC_OPENFLOW_BASIC:
+            continue
+        ofpxmt = i.num & 0x3f
+        td = i.type
+        add_attr('OFPXMT_OFB_' + uk, ofpxmt)
+        add_attr('OXM_OF_' + uk, mod.oxm_tlv_header(ofpxmt, td.size))
+        add_attr('OXM_OF_' + uk + '_W', mod.oxm_tlv_header_w(ofpxmt, td.size))
+
+    name_to_field = dict((f.name, f) for f in mod.oxm_types)
+    num_to_field = dict((f.num, f) for f in mod.oxm_types)
+    add_attr('oxm_from_user', functools.partial(from_user, name_to_field))
+    add_attr('oxm_to_user', functools.partial(to_user, num_to_field))
+    add_attr('oxm_normalize_user', functools.partial(normalize_user, mod))
+
+
+def from_user(name_to_field, name, user_value):
+    try:
+        f = name_to_field[name]
+        t = f.type
+        num = f.num
+    except KeyError:
+        t = UnknownType
+        if name.startswith('field_'):
+            num = int(name.split('_')[1])
+        else:
+            raise KeyError('unknown match field ' + name)
+    if isinstance(user_value, tuple):
+        (value, mask) = user_value
+    else:
+        value = user_value
+        mask = None
+    value = t.from_user(value)
+    if not mask is None:
+        mask = t.from_user(mask)
+    return num, value, mask
+
+
+def to_user(num_to_field, n, v, m):
+    try:
+        f = num_to_field[n]
+        t = f.type
+        name = f.name
+    except KeyError:
+        t = UnknownType
+        name = 'field_%d' % n
+    value = t.to_user(v)
+    if m is None:
+        user_value = value
+    else:
+        user_value = (value, t.to_user(m))
+    return name, user_value
+
+
+def normalize_user(mod, k, uv):
+    (n, v, m) = mod.oxm_from_user(k, uv)
+    # apply mask
+    if not m is None:
+        v = ''.join(chr(ord(x) & ord(y)) for (x, y)
+            in itertools.izip(v, m))
+    (k2, uv2) = mod.oxm_to_user(n, v, m)
+    assert k2 == k
+    return (k2, uv2)
-- 
1.8.1.5


------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to