v6 address and mask are represented in a list including four int
values like the following:

set_ipv6_src_masked([0xf1234567, 3, 4, 7], [0xffff0000, 0, 0, 0])

Signed-off-by: FUJITA Tomonori <[email protected]>
---
 ryu/ofproto/nx_match.py     |   74 ++++++++++++++++++++++++++++++++++++++++++-
 ryu/ofproto/ofproto_v1_0.py |    5 +++
 2 files changed, 78 insertions(+), 1 deletions(-)

diff --git a/ryu/ofproto/nx_match.py b/ryu/ofproto/nx_match.py
index 799d90d..209d1c2 100644
--- a/ryu/ofproto/nx_match.py
+++ b/ryu/ofproto/nx_match.py
@@ -16,6 +16,7 @@
 # limitations under the License.
 
 import struct
+import itertools
 
 from ryu import exception
 from ryu.lib import mac
@@ -84,6 +85,8 @@ class Flow(object):
         self.tun_id = 0
         self.arp_spa = 0
         self.arp_tpa = 0
+        self.ipv6_src = []
+        self.ipv6_dst = []
         self.ipv6_label = 0
 
 
@@ -99,6 +102,8 @@ class FlowWildcards(object):
         self.arp_spa_mask = 0
         self.arp_tpa_mask = 0
         self.vlan_tci_mask = 0
+        self.ipv6_src_mask = []
+        self.ipv6_dst_mask = []
         self.wildcards = FWW_ALL
 
 
@@ -228,6 +233,20 @@ class ClsRule(object):
         self.wc.wildcards &= ~FWW_IPV6_LABEL
         self.flow.ipv6_label = label
 
+    def set_ipv6_src_masked(self, src, mask):
+        self.wc.ipv6_src_mask = mask
+        self.flow.ipv6_src = [x & y for (x, y) in itertools.izip(src, mask)]
+
+    def set_ipv6_src(self, src):
+        self.flow.ipv6_src = src
+
+    def set_ipv6_dst_masked(self, dst, mask):
+        self.wc.ipv6_dst_mask = mask
+        self.flow.ipv6_dst = [x & y for (x, y) in itertools.izip(dst, mask)]
+
+    def set_ipv6_dst(self, dst):
+        self.flow.ipv6_dst = dst
+
     def flow_format(self):
         # Tunnel ID is only supported by NXM
         if self.wc.tun_id_mask != 0:
@@ -317,6 +336,17 @@ class MFField(object):
         else:
             return self.putw(buf, offset, value, mask)
 
+    def _putv6(self, buf, offset, value):
+        ofproto_parser.msg_pack_into(self.pack_str, buf, offset,
+                                     *value)
+        return self.n_bytes
+
+    def putv6(self, buf, offset, value, mask):
+        _len = self._putv6(buf, offset, value)
+        if len(mask):
+            return _len + self._putv6(buf, offset + _len, mask)
+        return _len
+
 
 @_register_make
 @_set_nxm_headers([ofproto_v1_0.NXM_OF_IN_PORT])
@@ -508,6 +538,34 @@ class MFArpSha(MFField):
 
 
 @_register_make
+@_set_nxm_headers([ofproto_v1_0.NXM_NX_IPV6_SRC,
+                   ofproto_v1_0.NXM_NX_IPV6_SRC_W])
+class MFIPV6Src(MFField):
+    @classmethod
+    def make(cls):
+        return cls('!4I')
+
+    def put(self, buf, offset, rule):
+        return self.putv6(buf, offset,
+                          rule.flow.ipv6_src,
+                          rule.wc.ipv6_src_mask)
+
+
+@_register_make
+@_set_nxm_headers([ofproto_v1_0.NXM_NX_IPV6_DST,
+                   ofproto_v1_0.NXM_NX_IPV6_DST_W])
+class MFIPV6Dst(MFField):
+    @classmethod
+    def make(cls):
+        return cls('!4I')
+
+    def put(self, buf, offset, rule):
+        return self.putv6(buf, offset,
+                          rule.flow.ipv6_dst,
+                          rule.wc.ipv6_dst_mask)
+
+
+@_register_make
 @_set_nxm_headers([ofproto_v1_0.NXM_NX_ARP_THA])
 class MFArpTha(MFField):
     @classmethod
@@ -669,7 +727,7 @@ def serialize_nxm_match(rule, buf, offset):
             header = ofproto_v1_0.NXM_OF_IP_DST_W
         offset += nxm_put(buf, offset, header, rule)
 
-    # XXX: IPv6
+    # IPv6
     if not rule.wc.wildcards & FWW_NW_PROTO and (rule.flow.nw_proto
                                                  == IPPROTO_ICMPV6):
         if rule.wc.tp_src_mask != 0:
@@ -682,6 +740,20 @@ def serialize_nxm_match(rule, buf, offset):
     if not rule.wc.wildcards & FWW_IPV6_LABEL:
         offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_IPV6_LABEL, rule)
 
+    if len(rule.flow.ipv6_src):
+        if len(rule.wc.ipv6_src_mask):
+            header = ofproto_v1_0.NXM_NX_IPV6_SRC_W
+        else:
+            header = ofproto_v1_0.NXM_NX_IPV6_SRC
+        offset += nxm_put(buf, offset, header, rule)
+
+    if len(rule.flow.ipv6_dst):
+        if len(rule.wc.ipv6_dst_mask):
+            header = ofproto_v1_0.NXM_NX_IPV6_DST_W
+        else:
+            header = ofproto_v1_0.NXM_NX_IPV6_DST
+        offset += nxm_put(buf, offset, header, rule)
+
     # ARP
     if rule.flow.arp_spa != 0:
         if rule.wc.arp_spa_mask == UINT32_MAX:
diff --git a/ryu/ofproto/ofproto_v1_0.py b/ryu/ofproto/ofproto_v1_0.py
index 4564843..bc1ce5c 100644
--- a/ryu/ofproto/ofproto_v1_0.py
+++ b/ryu/ofproto/ofproto_v1_0.py
@@ -707,6 +707,11 @@ NXM_NX_TUN_ID_W = nxm_header_w(0x0001, 16, 8)
 NXM_NX_ARP_SHA = nxm_header(0x0001, 17, 6)
 NXM_NX_ARP_THA = nxm_header(0x0001, 18, 6)
 
+NXM_NX_IPV6_SRC = nxm_header(0x0001, 19, 16)
+NXM_NX_IPV6_SRC_W = nxm_header_w(0x0001, 19, 16)
+NXM_NX_IPV6_DST = nxm_header(0x0001, 20, 16)
+NXM_NX_IPV6_DST_W = nxm_header_w(0x0001, 20, 16)
+
 NXM_NX_ICMPV6_TYPE = nxm_header(0x0001, 21, 1)
 NXM_NX_ICMPV6_CODE = nxm_header(0x0001, 22, 1)
 
-- 
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