Hello, I have implemented a custom OXM match in OVS that works fine over OpenFlow13 when used in a rule installed via ovs-ofctl add-flow. The match definition in OVS looks as following
# Maps a name prefix into an (experimenter ID, class) pair, so: # # - Standard OXM classes are written as (0, <oxm_class>) # # - Experimenter OXM classes are written as (<oxm_vender>, 0xffff) # # If a name matches more than one prefix, the longest one is used. OXM_CLASSES = {"NXM_OF_": (0, 0x0000), "NXM_NX_": (0, 0x0001), "NXOXM_NSH_": (0x005ad650, 0xffff), "OXM_OF_": (0, 0x8000), "OXM_OF_PKT_REG": (0, 0x8001), "ONFOXM_ET_": (0x4f4e4600, 0xffff), "OXM_TRH_": (0x144b0350, 0xffff), <------------------------ Here is my class definition The following is my match field definition /* "trh_nextuid". * * The twenty-four bits h-VNF UID and the eight bits flags fields. * * Type: be32. * Maskable: bitwise. * Formatting: hexadecimal. * Prerequisites: IPv6. * Access: read/write. * NXM: none. * OXM: OXM_TRH_NEXTUID(45) since OF1.2 and v2.8. */ Now I am trying to modify Ryu so that I can utilize it in a controller application with the following line "match = ofp_parser.OFPMatch(trh_nextuid=0x9f8e7dab, eth_type=ETH_TYPE_IPV6)" Here is what I have done so far in Ryu diff --git a/ryu/ofproto/ofproto_common.py b/ryu/ofproto/ofproto_common.py index ffdf1a4..b91fd21 100644 --- a/ryu/ofproto/ofproto_common.py +++ b/ryu/ofproto/ofproto_common.py @@ -33,5 +33,6 @@ # https://rs.opennetworking.org/wiki/display/PUBLIC/ONF+Registry NX_EXPERIMENTER_ID = 0x00002320 # Nicira NX_NSH_EXPERIMENTER_ID = 0x005ad650 # Nicira Ext for Network Service Header BSN_EXPERIMENTER_ID = 0x005c16c7 # Big Switch Networks ONF_EXPERIMENTER_ID = 0x4f4e4600 # OpenFlow Extensions for 1.3.X Pack 1 +TRH_EXPERIMENTER_ID = 0x144b0350 # TRF \ No newline at end of file diff --git a/ryu/ofproto/ofproto_v1_3.py b/ryu/ofproto/ofproto_v1_3.py index d599c1c..018bdad 100644 --- a/ryu/ofproto/ofproto_v1_3.py +++ b/ryu/ofproto/ofproto_v1_3.py @@ -175,10 +175,11 @@ # enum ofp_oxm_class OFPXMC_NXM_0 = 0x0000 # Backward compatibility with NXM OFPXMC_NXM_1 = 0x0001 # Backward compatibility with NXM OFPXMC_OPENFLOW_BASIC = 0x8000 # Basic class for OpenFlow OFPXMC_EXPERIMENTER = 0xFFFF # Experimenter class +OFPXMC_TRH = 0xFFFF # TRF # enum ofp_vlan_id OFPVID_PRESENT = 0x1000 # bit that indicate that a VLAN id is set. OFPVID_NONE = 0x0000 # No VLAN id was set. @@ -1227,10 +1228,12 @@ # EXT-109 TCP flags match field Extension oxm_fields.ONFExperimenter('tcp_flags', 42, type_desc.Int2), # EXT-233 Output match Extension # NOTE(yamamoto): The spec says uint64_t but I assume it's an error. oxm_fields.ONFExperimenter('actset_output', 43, type_desc.Int4), + #TRH + oxm_fields.Trh('trh_nextuid', 45, type_desc.Int4), ] + nicira_ext.oxm_types oxm_fields.generate(__name__) diff --git a/ryu/ofproto/ofproto_v1_3_parser.py b/ryu/ofproto/ofproto_v1_3_parser.py index 0324c82..41977e8 100644 --- a/ryu/ofproto/ofproto_v1_3_parser.py +++ b/ryu/ofproto/ofproto_v1_3_parser.py @@ -693,10 +693,11 @@ self.mpls_tc = 0 self.mpls_bos = 0 self.pbb_isid = 0 self.tunnel_id = 0 self.ipv6_exthdr = 0 + self.trh_nextuid = 0 class FlowWildcards(object): def __init__(self): self.metadata_mask = 0 @@ -713,10 +714,11 @@ self.ipv6_dst_mask = [] self.ipv6_flabel_mask = 0 self.pbb_isid_mask = 0 self.tunnel_id_mask = 0 self.ipv6_exthdr_mask = 0 + self.trh_nextuid_mask = 0 self.wildcards = (1 << 64) - 1 def ft_set(self, shift): self.wildcards &= ~(1 << shift) @@ -783,10 +785,11 @@ (EXT-256 Old version of ONF Extension) tcp_flags Integer 16bit TCP flags (EXT-109 ONF Extension) actset_output Integer 32bit Output port from action set metadata (EXT-233 ONF Extension) + trh_nextuid Integer 32bit TRH Next h-VNF UID ================ =============== ================================== Example:: >>> # compose @@ -1029,10 +1032,11 @@ OXM_OF_MPLS_TC MPLS TC OXM_OF_MPLS_BOS MPLS BoS bit OXM_OF_PBB_ISID PBB I-SID OXM_OF_TUNNEL_ID Logical Port Metadata OXM_OF_IPV6_EXTHDR IPv6 Extension Header pseudo-field + OXM_OF_TRH_NEXTUID TRH Next h-VNF UID ====================== =================================== """ self.fields.append(OFPMatchField.make(header, value, mask)) def _composed_with_old_api(self): @@ -1286,10 +1290,18 @@ else: header = ofproto.OXM_OF_IPV6_EXTHDR self.append_field(header, self._flow.ipv6_exthdr, self._wc.ipv6_exthdr_mask) + if self._wc.ft_test(ofproto.OFPXMT_TRHBB_NEXTUID): + if self._wc.ipv6_flabel_mask == UINT32_MAX: + header = ofproto.OXM_TRH_NEXTUID + else: + header = ofproto.OXM_TRH_NEXTUID_W + self.append_field(header, self._flow.trh_nextuid, + self._wc.trh_nextuid_mask) + field_offset = offset + 4 for f in self.fields: f.serialize(buf, field_offset) field_offset += f.length @@ -2244,21 +2256,29 @@ def __init__(self, header, value, mask=None): super(MTTunnelId, self).__init__(header) self.value = value self.mask = mask - @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_EXTHDR, ofproto.OXM_OF_IPV6_EXTHDR_W]) class MTIPv6ExtHdr(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTIPv6ExtHdr, self).__init__(header) self.value = value self.mask = mask +@OFPMatchField.register_field_header([ofproto.OXM_TRH_NEXTUID, + ofproto.OXM_TRH_NEXTUID_W]) +class MTTrhNextuid(OFPMatchField): + pack_str = '!I' + + def __init__(self, header, value, mask=None): + super(MTTrhNextuid, self).__init__(header) + self.value = value + self.mask = mask @_register_parser @_set_msg_type(ofproto.OFPT_PACKET_IN) class OFPPacketIn(MsgBase): """ diff --git a/ryu/ofproto/oxm_fields.py b/ryu/ofproto/oxm_fields.py index f978f5b..d5015cf 100644 --- a/ryu/ofproto/oxm_fields.py +++ b/ryu/ofproto/oxm_fields.py @@ -82,11 +82,11 @@ OFPXMC_NXM_0 = 0 # Nicira Extended Match (NXM_OF_) OFPXMC_NXM_1 = 1 # Nicira Extended Match (NXM_NX_) OFPXMC_OPENFLOW_BASIC = 0x8000 OFPXMC_PACKET_REGS = 0x8001 OFPXMC_EXPERIMENTER = 0xffff - +OFPXMC_TRH = 0xffff class _OxmClass(object): def __init__(self, name, num, type_): self.name = name self.oxm_field = num @@ -97,24 +97,24 @@ self.type = type_ class OpenFlowBasic(_OxmClass): _class = OFPXMC_OPENFLOW_BASIC - - + class PacketRegs(_OxmClass): _class = OFPXMC_PACKET_REGS - class _Experimenter(_OxmClass): _class = OFPXMC_EXPERIMENTER def __init__(self, name, num, type_): super(_Experimenter, self).__init__(name, num, type_) self.num = (self.experimenter_id, self.oxm_type) self.exp_type = self.oxm_field +class Trh(_OxmClass): + _class = OFPXMC_TRH class ONFExperimenter(_Experimenter): experimenter_id = ofproto_common.ONF_EXPERIMENTER_ID And the following is the error when I try to launch the controller app File "/root/.local/lib/python2.7/site-packages/ryu/ofproto/ofproto_protocol.py", line 22, in <module> from ryu.ofproto import ofproto_v1_3_parser File "/root/.local/lib/python2.7/site-packages/ryu/ofproto/ofproto_v1_3_parser.py", line 2271, in <module> @OFPMatchField.register_field_header([ofproto.OXM_TRH_NEXTUID, AttributeError: 'module' object has no attribute 'OXM_TRH_NEXTUID' For now, I am not interested in the REST API side of things; it would be enough if I can use this match in the FLOW_MOD messages. I'd appreciate if anyone could point me in the right direction. Thanks, Alan
_______________________________________________ Ryu-devel mailing list Ryu-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ryu-devel