OFPMatch is slightly different from NXMatch so I implemented it
slightly differently.

I've not implemented all matches. I'll do if the code looks ok.

-
>From 414ef21dfa1afd7e8538b0c657e697bcf25235e5 Mon Sep 17 00:00:00 2001
From: FUJITA Tomonori <[email protected]>
Date: Tue, 19 Jun 2012 22:15:35 +0900
Subject: [PATCH] of1.2: add ofp_match support

Signed-off-by: FUJITA Tomonori <[email protected]>
---
 ryu/ofproto/ofproto_v1_2_parser.py |  164 ++++++++++++++++++++++++++++++++++++
 1 files changed, 164 insertions(+), 0 deletions(-)

diff --git a/ryu/ofproto/ofproto_v1_2_parser.py 
b/ryu/ofproto/ofproto_v1_2_parser.py
index 9b234d4..b01bfb4 100644
--- a/ryu/ofproto/ofproto_v1_2_parser.py
+++ b/ryu/ofproto/ofproto_v1_2_parser.py
@@ -17,6 +17,7 @@
 import collections
 import struct
 
+from ryu.lib import mac
 from ofproto_parser import MsgBase, msg_pack_into, msg_str_attr
 from . import ofproto_parser
 from . import ofproto_v1_2
@@ -835,3 +836,166 @@ class OFPRoleReply(MsgBase):
             ofproto_v1_2.OFP_HEADER_SIZE)
 
         return msg
+
+
+FWW_IN_PORT = 1 << 0
+FWW_DL_TYPE = 1 << 4
+FWW_NW_PROTO = 1 << 5
+# No corresponding OFPFW_* bits
+FWW_NW_DSCP = 1 << 1
+FWW_NW_ECN = 1 << 2
+FWW_ARP_SHA = 1 << 3
+FWW_ARP_THA = 1 << 6
+FWW_NW_TTL = 1 << 8
+FWW_ALL = (1 << 9) - 1
+
+
+class Flow(object):
+    def __init__(self):
+        self.in_port = 0
+        self.dl_dst = mac.DONTCARE
+
+
+class FlowWildcards(object):
+    def __init__(self):
+        self.dl_dst_mask = 0
+        self.wildcards = FWW_ALL
+
+
+class OFPMatch(object):
+    def __init__(self):
+        super(OFPMatch, self).__init__()
+        self.wc = FlowWildcards()
+        self.flow = Flow()
+        self.fields = []
+
+    def serialize(self, buf, offset):
+        if not self.wc.wildcards & FWW_IN_PORT:
+            self.fields.append(OFPMatchField.make(ofproto_v1_2.OXM_OF_IN_PORT))
+
+        if self.flow.dl_dst != mac.DONTCARE:
+            if self.wc.dl_dst_mask:
+                header = ofproto_v1_2.OXM_OF_ETH_DST_W
+            else:
+                header = ofproto_v1_2.OXM_OF_ETH_DST
+            self.fields.append(OFPMatchField.make(header))
+
+        field_offset = offset + 4
+        for f in self.fields:
+            f.serialize(buf, field_offset, self)
+            field_offset += f.length
+
+        length = field_offset - offset
+        msg_pack_into('!HH', buf, offset, ofproto_v1_2.OFPMT_OXM, length)
+
+        pad_len = 8 - (length % 8)
+        ofproto_parser.msg_pack_into("%dx" % pad_len, buf, field_offset)
+
+    @classmethod
+    def parser(cls, buf, offset):
+        match = OFPMatch()
+        type_, length = struct.unpack_from('!HH', buf, offset)
+
+        # ofp_match adjustment
+        offset += 4
+        length -= 4
+        while length > 0:
+            field = OFPMatchField.parser(buf, offset)
+            offset += field.length
+            length -= field.length
+            match.fields.append(field)
+
+        return match
+
+    def set_in_port(self, port):
+        self.wc.wildcards &= ~FWW_IN_PORT
+        self.flow.in_port = port
+
+    def set_dl_dst(self, dl_dst):
+        self.flow.dl_dst = dl_dst
+
+    def set_dl_dst_masked(self, dl_dst, mask):
+        self.wc.dl_dst_mask = mask
+        # bit-wise and of the corresponding elements of dl_dst and mask
+        self.flow.dl_dst = mac.haddr_bitand(dl_dst, mask)
+
+
+class OFPMatchField(object):
+    _FIELDS_HEADERS = {}
+
+    @staticmethod
+    def register_field_header(headers):
+        def _register_field_header(cls):
+            for header in headers:
+                OFPMatchField._FIELDS_HEADERS[header] = cls
+            return cls
+        return _register_field_header
+
+    def __init__(self, header, pack_str):
+        self.header = header
+        self.pack_str = pack_str
+        self.n_bytes = struct.calcsize(pack_str)
+        self.length = 0
+
+    @staticmethod
+    def make(header):
+        cls_ = OFPMatchField._FIELDS_HEADERS.get(header)
+        return cls_(header)
+
+    @classmethod
+    def parser(cls, buf, offset):
+        (header,) = struct.unpack_from('!I', buf, offset)
+        # TODO: handle unknown field
+        cls_ = OFPMatchField._FIELDS_HEADERS.get(header)
+        field = cls_.parser(header, buf, offset)
+        field.length = (header & 0xff) + 4
+        return field
+
+    def _put_header(self, buf, offset):
+        ofproto_parser.msg_pack_into('!I', buf, offset, self.header)
+        self.length += 4
+
+    def _put(self, buf, offset, value):
+        ofproto_parser.msg_pack_into(self.pack_str, buf, offset, value)
+        self.length += self.n_bytes
+
+    def put_w(self, buf, offset, value, mask):
+        self._put_header(buf, offset)
+        self._put(buf, offset + self.length, value)
+        self._put(buf, offset + self.length, mask)
+
+    def put(self, buf, offset, value):
+        self._put_header(buf, offset)
+        self._put(buf, offset + self.length, value)
+
+
[email protected]_field_header([ofproto_v1_2.OXM_OF_IN_PORT])
+class MTInPort(OFPMatchField):
+    def __init__(self, header):
+        super(MTInPort, self).__init__(header, '!I')
+
+    def serialize(self, buf, offset, match):
+        self.put(buf, offset, match.flow.in_port)
+
+    @classmethod
+    def parser(cls, header, buf, offset):
+        # set in_port
+        return MTInPort(header)
+
+
[email protected]_field_header([ofproto_v1_2.OXM_OF_ETH_DST,
+                                    ofproto_v1_2.OXM_OF_ETH_DST_W])
+class MTEthDst(OFPMatchField):
+    def __init__(self, header):
+        super(MTEthDst, self).__init__(header, '!6s')
+
+    def serialize(self, buf, offset, match):
+        if match.wc.dl_dst_mask:
+            self.put_w(buf, offset, match.flow.dl_dst,
+                              match.wc.dl_dst_mask)
+        else:
+            self.put(buf, offset, match.flow.dl_dst)
+
+    @classmethod
+    def parser(cls, header, buf, offset):
+        return MTEthDst(header)
-- 
1.7.4.4


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to