this patch implements the match conditions using IPv6.

NOTE: OpenFlow1.0 does not support IPv6.

e.g. using ofctl_rest)

curl -X POST -d '{"dpid": 1,
                  "match": {"eth_type": 34525,
                            "ipv6_src": "fe08:2001::/64",
                            "ipv6_dst": "ff02::1"},
                  "actions": [{"type": "OUTPUT",
                               "port": 2}]}' 
http://localhost:8080/stats/flowentry/add

Signed-off-by: Yuichi Ito <[email protected]>
---
 ryu/lib/ofctl_v1_2.py |   51 +++++++++++++++++++++++++++++++++++++++++++------
 ryu/lib/ofctl_v1_3.py |   48 ++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 89 insertions(+), 10 deletions(-)

diff --git a/ryu/lib/ofctl_v1_2.py b/ryu/lib/ofctl_v1_2.py
index c0da95a..6eb2981 100644
--- a/ryu/lib/ofctl_v1_2.py
+++ b/ryu/lib/ofctl_v1_2.py
@@ -16,6 +16,7 @@
 import struct
 import socket
 import logging
+import netaddr

 from ryu.ofproto import inet
 from ryu.ofproto import ofproto_v1_2
@@ -90,7 +91,9 @@ def to_match(dp, attrs):
                'tcp_src': int,
                'tcp_dst': int,
                'udp_src': int,
-               'udp_dst': int}
+               'udp_dst': int,
+               'ipv6_src': to_match_ipv6,
+               'ipv6_dst': to_match_ipv6}

     match_append = {'in_port': match.set_in_port,
                     'dl_src': match.set_dl_src,
@@ -112,14 +115,17 @@ def to_match(dp, attrs):
                     'tcp_src': to_match_tpsrc,
                     'tcp_dst': to_match_tpdst,
                     'udp_src': to_match_tpsrc,
-                    'udp_dst': to_match_tpdst}
+                    'udp_dst': to_match_tpdst,
+                    'ipv6_src': match.set_ipv6_src_masked,
+                    'ipv6_dst': match.set_ipv6_dst_masked}

     for key, value in attrs.items():
         if key in convert:
             value = convert[key](value)
         if key in match_append:
             if key == 'nw_src' or key == 'nw_dst' or \
-                    key == 'ipv4_src' or key == 'ipv4_dst':
+                    key == 'ipv4_src' or key == 'ipv4_dst' or \
+                    key == 'ipv6_src' or key == 'ipv6_dst':
                 # IP address
                 ip = value[0]
                 mask = value[1]
@@ -128,7 +134,7 @@ def to_match(dp, attrs):
                     key == 'tcp_src' or key == 'tcp_dst' or \
                     key == 'udp_src' or key == 'udp_dst':
                 # tp_src/dst
-                match = match_append[key](value, match, attrs)
+                match_append[key](value, match, attrs)
             else:
                 # others
                 match_append[key](value)
@@ -172,6 +178,11 @@ def to_match_ip(value):
     return ipv4, netmask


+def to_match_ipv6(value):
+    ip = netaddr.IPNetwork(value)
+    return ip.ip.words, ip.netmask.words
+
+
 def match_to_str(ofmatch):
     keys = {ofproto_v1_2.OXM_OF_IN_PORT: 'in_port',
             ofproto_v1_2.OXM_OF_ETH_SRC: 'dl_src',
@@ -186,7 +197,11 @@ def match_to_str(ofmatch):
             ofproto_v1_2.OXM_OF_TCP_SRC: 'tp_src',
             ofproto_v1_2.OXM_OF_TCP_DST: 'tp_dst',
             ofproto_v1_2.OXM_OF_UDP_SRC: 'tp_src',
-            ofproto_v1_2.OXM_OF_UDP_DST: 'tp_dst'}
+            ofproto_v1_2.OXM_OF_UDP_DST: 'tp_dst',
+            ofproto_v1_2.OXM_OF_IPV6_SRC: 'ipv6_src',
+            ofproto_v1_2.OXM_OF_IPV6_DST: 'ipv6_dst',
+            ofproto_v1_2.OXM_OF_IPV6_SRC_W: 'ipv6_src',
+            ofproto_v1_2.OXM_OF_IPV6_DST_W: 'ipv6_dst'}

     match = {}
     for match_field in ofmatch.fields:
@@ -195,6 +210,8 @@ def match_to_str(ofmatch):
             value = mac.haddr_to_str(match_field.value)
         elif key == 'nw_src' or key == 'nw_dst':
             value = match_ip_to_str(match_field.value, match_field.mask)
+        elif key == 'ipv6_src' or key == 'ipv6_dst':
+            value = match_ipv6_to_str(match_field.value, match_field.mask)
         else:
             value = match_field.value
         match.setdefault(key, value)
@@ -214,6 +231,29 @@ def match_ip_to_str(value, mask):
     return ip + netmask


+def match_ipv6_to_str(value, mask):
+    ip_list = []
+    for word in value:
+        ip_list.append('%04x' % word)
+    ip = netaddr.IPNetwork(':'.join(ip_list))
+
+    netmask = 128
+    if mask is not None:
+        mask_list = []
+        for word in mask:
+            mask_list.append('%04x' % word)
+        mask_v = netaddr.IPNetwork(':'.join(mask_list))
+        netmask = len(mask_v.ip.bits().replace(':', '').rstrip('0'))
+
+    if netmask == 128:
+        ip_str = str(ip.ip)
+    else:
+        ip.prefixlen = netmask
+        ip_str = str(ip)
+
+    return ip_str
+
+
 def send_stats_request(dp, stats, waiters, msgs):
     dp.set_xid(stats)
     waiters_per_dp = waiters.setdefault(dp.id, {})
@@ -263,7 +303,6 @@ def get_flow_stats(dp, waiters):
         for stats in msg.body:
             actions = actions_to_str(stats.instructions)
             match = match_to_str(stats.match)
-
             s = {'priority': stats.priority,
                  'cookie': stats.cookie,
                  'idle_timeout': stats.idle_timeout,
diff --git a/ryu/lib/ofctl_v1_3.py b/ryu/lib/ofctl_v1_3.py
index 4516a56..7d2c9fb 100644
--- a/ryu/lib/ofctl_v1_3.py
+++ b/ryu/lib/ofctl_v1_3.py
@@ -16,6 +16,7 @@
 import struct
 import socket
 import logging
+import netaddr

 from ryu.ofproto import inet
 from ryu.ofproto import ofproto_v1_3
@@ -223,7 +224,9 @@ def to_match(dp, attrs):
                'tcp_src': int,
                'tcp_dst': int,
                'udp_src': int,
-               'udp_dst': int}
+               'udp_dst': int,
+               'ipv6_src': to_match_ipv6,
+               'ipv6_dst': to_match_ipv6}

     match_append = {'in_port': match.set_in_port,
                     'dl_src': match.set_dl_src,
@@ -247,14 +250,17 @@ def to_match(dp, attrs):
                     'tcp_src': to_match_tpsrc,
                     'tcp_dst': to_match_tpdst,
                     'udp_src': to_match_tpsrc,
-                    'udp_dst': to_match_tpdst}
+                    'udp_dst': to_match_tpdst,
+                    'ipv6_src': match.set_ipv6_src_masked,
+                    'ipv6_dst': match.set_ipv6_dst_masked}

     for key, value in attrs.items():
         if key in convert:
             value = convert[key](value)
         if key in match_append:
             if key == 'nw_src' or key == 'nw_dst' or \
-                    key == 'ipv4_src' or key == 'ipv4_dst':
+                    key == 'ipv4_src' or key == 'ipv4_dst' or \
+                    key == 'ipv6_src' or key == 'ipv6_dst':
                 # IP address
                 ip = value[0]
                 mask = value[1]
@@ -312,6 +318,11 @@ def to_match_ip(value):
     return ipv4, netmask


+def to_match_ipv6(value):
+    ip = netaddr.IPNetwork(value)
+    return ip.ip.words, ip.netmask.words
+
+
 def to_match_metadata(value):
     if '/' in value:
         metadata = value.split('/')
@@ -336,7 +347,11 @@ def match_to_str(ofmatch):
             ofproto_v1_3.OXM_OF_UDP_SRC: 'tp_src',
             ofproto_v1_3.OXM_OF_UDP_DST: 'tp_dst',
             ofproto_v1_3.OXM_OF_METADATA: 'metadata',
-            ofproto_v1_3.OXM_OF_METADATA_W: 'metadata'}
+            ofproto_v1_3.OXM_OF_METADATA_W: 'metadata',
+            ofproto_v1_3.OXM_OF_IPV6_SRC: 'ipv6_src',
+            ofproto_v1_3.OXM_OF_IPV6_DST: 'ipv6_dst',
+            ofproto_v1_3.OXM_OF_IPV6_SRC_W: 'ipv6_src',
+            ofproto_v1_3.OXM_OF_IPV6_DST_W: 'ipv6_dst'}

     match = {}
     for match_field in ofmatch.fields:
@@ -345,6 +360,8 @@ def match_to_str(ofmatch):
             value = mac.haddr_to_str(match_field.value)
         elif key == 'nw_src' or key == 'nw_dst':
             value = match_ip_to_str(match_field.value, match_field.mask)
+        elif key == 'ipv6_src' or key == 'ipv6_dst':
+            value = match_ipv6_to_str(match_field.value, match_field.mask)
         elif key == 'metadata':
             value = ('%d/%d' % (match_field.value, match_field.mask)
                      if match_field.mask else '%d' % match_field.value)
@@ -367,6 +384,29 @@ def match_ip_to_str(value, mask):
     return ip + netmask


+def match_ipv6_to_str(value, mask):
+    ip_list = []
+    for word in value:
+        ip_list.append('%04x' % word)
+    ip = netaddr.IPNetwork(':'.join(ip_list))
+
+    netmask = 128
+    if mask is not None:
+        mask_list = []
+        for word in mask:
+            mask_list.append('%04x' % word)
+        mask_v = netaddr.IPNetwork(':'.join(mask_list))
+        netmask = len(mask_v.ip.bits().replace(':', '').rstrip('0'))
+
+    if netmask == 128:
+        ip_str = str(ip.ip)
+    else:
+        ip.prefixlen = netmask
+        ip_str = str(ip)
+
+    return ip_str
+
+
 def send_stats_request(dp, stats, waiters, msgs):
     dp.set_xid(stats)
     waiters_per_dp = waiters.setdefault(dp.id, {})
-- 
1.7.10.4


------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to