This adds IPv6 peering support. IPv6 advertisement support is the next item
in my TODO list.

=
>From f5baa763682caa89c02136b45e35ce99c539fae7 Mon Sep 17 00:00:00 2001
From: FUJITA Tomonori <[email protected]>
Date: Tue, 17 Jun 2014 17:59:31 +0900
Subject: [PATCH] bgp: support IPv6 peering

Signed-off-by: FUJITA Tomonori <[email protected]>
---
 ryu/services/protocols/bgp/base.py                  | 21 +++++++++++++++++----
 ryu/services/protocols/bgp/core.py                  | 10 ++++++----
 .../protocols/bgp/core_managers/peer_manager.py     |  3 ++-
 ryu/services/protocols/bgp/rtconf/neighbors.py      | 15 +++++++++++----
 4 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/ryu/services/protocols/bgp/base.py 
b/ryu/services/protocols/bgp/base.py
index 9eff703..d6989a3 100644
--- a/ryu/services/protocols/bgp/base.py
+++ b/ryu/services/protocols/bgp/base.py
@@ -21,6 +21,7 @@ import socket
 import time
 import traceback
 import weakref
+import netaddr
 
 from ryu.lib import hub
 from ryu.lib.hub import Timeout
@@ -318,16 +319,24 @@ class Activity(object):
 
         For each connection `server_factory` starts a new protocol.
         """
-        server = hub.listen(loc_addr)
+        if ':' in loc_addr[0]:
+            server = hub.listen(loc_addr, family=socket.AF_INET6)
+        else:
+            server = hub.listen(loc_addr)
+
         server_name = self.name + '_server@' + str(loc_addr)
         self._asso_socket_map[server_name] = server
 
         # We now wait for connection requests from client.
         while True:
             sock, client_address = server.accept()
+            client_address, port = client_address[:2]
             LOG.debug('Connect request received from client for port'
-                      ' %s:%s' % client_address)
-            client_name = self.name + '_client@' + str(client_address)
+                      ' %s:%s' % (client_address, port))
+            if 'ffff:' in client_address:
+                client_address = str(netaddr.IPAddress(client_address).ipv4())
+
+            client_name = self.name + '_client@' + client_address
             self._asso_socket_map[client_name] = sock
             self._spawn(client_name, conn_handle, sock)
 
@@ -341,8 +350,12 @@ class Activity(object):
         """
         LOG.debug('Connect TCP called for %s:%s' % (peer_addr[0],
                                                     peer_addr[1]))
+        if netaddr.valid_ipv4(peer_addr[0]):
+            family = socket.AF_INET
+        else:
+            family = socket.AF_INET6
         with Timeout(time_out, socket.error):
-            sock = hub.connect(peer_addr, bind=bind_address)
+            sock = hub.connect(peer_addr, family=family, bind=bind_address)
             if sock:
                 # Connection name for pro-active connection is made up
                 # of local end address + remote end address
diff --git a/ryu/services/protocols/bgp/core.py 
b/ryu/services/protocols/bgp/core.py
index 3a56411..09c058c 100644
--- a/ryu/services/protocols/bgp/core.py
+++ b/ryu/services/protocols/bgp/core.py
@@ -45,7 +45,7 @@ LOG = logging.getLogger('bgpspeaker.core')
 
 # Interface IP address on which to run bgp server. Core service listens on all
 # interfaces of the host on port 179 - standard bgp port.
-CORE_IP = '0.0.0.0'
+CORE_IP = '::'
 
 # Required dictates that Origin attribute be incomplete
 EXPECTED_ORIGIN = BGP_ATTR_ORIGIN_INCOMPLETE
@@ -380,7 +380,7 @@ class CoreService(Factory, Activity):
     def build_protocol(self, socket):
         assert socket
         # Check if its a reactive connection or pro-active connection
-        _, remote_port = socket.getpeername()
+        _, remote_port = socket.getpeername()[:2]
         is_reactive_conn = True
         if remote_port == STD_BGP_SERVER_PORT_NUM:
             is_reactive_conn = False
@@ -399,7 +399,9 @@ class CoreService(Factory, Activity):
         protocol.
         """
         assert socket
-        peer_addr, peer_port = socket.getpeername()
+        peer_addr, peer_port = socket.getpeername()[:2]
+        if 'ffff:' in peer_addr:
+            peer_addr = str(netaddr.IPAddress(peer_addr).ipv4())
         peer = self._peer_manager.get_by_addr(peer_addr)
         bgp_proto = self.build_protocol(socket)
 
@@ -424,7 +426,7 @@ class CoreService(Factory, Activity):
             subcode = BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION
             bgp_proto.send_notification(code, subcode)
         else:
-            bind_ip, bind_port = socket.getsockname()
+            bind_ip, bind_port = socket.getsockname()[0:2]
             peer._host_bind_ip = bind_ip
             peer._host_bind_port = bind_port
             self._spawn_activity(bgp_proto, peer)
diff --git a/ryu/services/protocols/bgp/core_managers/peer_manager.py 
b/ryu/services/protocols/bgp/core_managers/peer_manager.py
index 8fba6b0..1b9dce5 100644
--- a/ryu/services/protocols/bgp/core_managers/peer_manager.py
+++ b/ryu/services/protocols/bgp/core_managers/peer_manager.py
@@ -1,4 +1,5 @@
 import logging
+import netaddr
 
 from ryu.services.protocols.bgp.base import SUPPORTED_GLOBAL_RF
 from ryu.services.protocols.bgp.model import OutgoingRoute
@@ -53,7 +54,7 @@ class PeerManager(object):
         self._core_service.on_peer_removed(peer)
 
     def get_by_addr(self, addr):
-        return self._peers.get(addr)
+        return self._peers.get(str(netaddr.IPAddress(addr)))
 
     def on_peer_down(self, peer):
         """Peer down handler.
diff --git a/ryu/services/protocols/bgp/rtconf/neighbors.py 
b/ryu/services/protocols/bgp/rtconf/neighbors.py
index 8acd62e..8e98105 100644
--- a/ryu/services/protocols/bgp/rtconf/neighbors.py
+++ b/ryu/services/protocols/bgp/rtconf/neighbors.py
@@ -18,6 +18,7 @@
 """
 from abc import abstractmethod
 import logging
+import netaddr
 
 from ryu.lib.packet.bgp import RF_IPv4_UC
 from ryu.lib.packet.bgp import RF_IPv6_UC
@@ -107,20 +108,26 @@ def validate_changes(changes):
     return changes
 
 
+def valid_ip_address(addr):
+    if not netaddr.valid_ipv4(addr) and not netaddr.valid_ipv6(addr):
+        return False
+    return True
+
+
 @validate(name=IP_ADDRESS)
 def validate_ip_address(ip_address):
-    if not is_valid_ipv4(ip_address):
+    if not valid_ip_address(ip_address):
         raise ConfigValueError(desc='Invalid neighbor ip_address: %s' %
                                ip_address)
-    return ip_address
+    return str(netaddr.IPAddress(ip_address))
 
 
 @validate(name=LOCAL_ADDRESS)
 def validate_local_address(ip_address):
-    if not is_valid_ipv4(ip_address):
+    if not valid_ip_address(ip_address):
         raise ConfigValueError(desc='Invalid local ip_address: %s' %
                                ip_address)
-    return ip_address
+    return str(netaddr.IPAddress(ip_address))
 
 
 @validate(name=LOCAL_PORT)
-- 
1.8.5.2 (Apple Git-48)


------------------------------------------------------------------------------
HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration
http://p.sf.net/sfu/hpccsystems
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to