This patch introduces APIs to register/unregister switch address after
Ryu (ofp_handler) starting.

Signed-off-by: IWASE Yusuke <iwase.yusu...@gmail.com>
---
 ryu/controller/controller.py  | 14 ++++++++-
 ryu/controller/ofp_api.py     | 73 +++++++++++++++++++++++++++++++++++++++++++
 ryu/controller/ofp_event.py   |  3 ++
 ryu/controller/ofp_handler.py |  6 ++--
 4 files changed, 93 insertions(+), 3 deletions(-)
 create mode 100644 ryu/controller/ofp_api.py

diff --git a/ryu/controller/controller.py b/ryu/controller/controller.py
index 84e0e05..2de14a7 100644
--- a/ryu/controller/controller.py
+++ b/ryu/controller/controller.py
@@ -66,7 +66,7 @@ CONF.register_cli_opts([
     cfg.StrOpt('ca-certs', default=None, help='CA certificates'),
     cfg.ListOpt('ofp-switch-address-list', item_type=str, default=[],
                 help='list of IP address and port pairs (default empty). '
-                     'e.g., "127.0.0.1:6653,127.0.0.1:6633"'),
+                     'e.g., "127.0.0.1:6653,[::1]:6653"'),
     cfg.IntOpt('ofp-switch-connect-interval',
                default=DEFAULT_OFP_SW_CON_INTERVAL,
                help='interval in seconds to connect to switches '
@@ -133,6 +133,12 @@ class OpenFlowController(object):
             self.ofp_tcp_listen_port = CONF.ofp_tcp_listen_port
             self.ofp_ssl_listen_port = CONF.ofp_ssl_listen_port
 
+        # Example:
+        # self._clients = {
+        #     ('127.0.0.1', 6653): <instance of StreamClient>,
+        # }
+        self._clients = {}
+
     # entry point
     def __call__(self):
         # LOG.debug('call')
@@ -147,6 +153,12 @@ class OpenFlowController(object):
         interval = interval or CONF.ofp_switch_connect_interval
         client = hub.StreamClient(addr)
         hub.spawn(client.connect_loop, datapath_connection_factory, interval)
+        self._clients[addr] = client
+
+    def stop_client_loop(self, addr):
+        client = self._clients.get(addr, None)
+        if client is not None:
+            client.stop()
 
     def server_loop(self, ofp_tcp_listen_port, ofp_ssl_listen_port):
         if CONF.ctl_privkey is not None and CONF.ctl_cert is not None:
diff --git a/ryu/controller/ofp_api.py b/ryu/controller/ofp_api.py
new file mode 100644
index 0000000..088f140
--- /dev/null
+++ b/ryu/controller/ofp_api.py
@@ -0,0 +1,73 @@
+# Copyright (C) 2017 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+OpenFlow related APIs of ryu.controller module.
+"""
+
+import netaddr
+
+from ryu.base import app_manager
+from ryu.lib import hub
+from . import ofp_event
+
+
+_TMP_ADDRESSES = {}
+
+
+def register_switch_address(addr, interval=None):
+    """
+    Registers a new address to initiate connection to switch.
+
+    Registers a new IP address and port pair of switch to let
+    ryu.controller.controller.OpenFlowController to try to initiate
+    connection to switch.
+
+    :param addr: A tuple of (host, port) pair of switch.
+    :param interval: Interval in seconds to try to connect to switch
+    """
+    assert len(addr) == 2
+    assert netaddr.valid_ipv4(addr[0]) or netaddr.valid_ipv6(addr[0])
+    ofp_handler = app_manager.lookup_service_brick(ofp_event.NAME)
+    _TMP_ADDRESSES[addr] = interval
+
+    def _retry_loop():
+        # Delays registration if ofp_handler is not started yet
+        while True:
+            if ofp_handler.controller is not None:
+                for a, i in _TMP_ADDRESSES.items():
+                    ofp_handler.controller.spawn_client_loop(a, i)
+                    hub.sleep(1)
+                break
+            hub.sleep(1)
+
+    hub.spawn(_retry_loop)
+
+
+def unregister_switch_address(addr):
+    """
+    Unregister the given switch address.
+
+    Unregisters the given switch address to let
+    ryu.controller.controller.OpenFlowController stop trying to initiate
+    connection to switch.
+
+    :param addr: A tuple of (host, port) pair of switch.
+    """
+    ofp_handler = app_manager.lookup_service_brick(ofp_event.NAME)
+    # Do nothing if ofp_handler is not started yet
+    if ofp_handler.controller is None:
+        return
+    ofp_handler.controller.stop_client_loop(addr)
diff --git a/ryu/controller/ofp_event.py b/ryu/controller/ofp_event.py
index 6eb8e5f..7640b41 100644
--- a/ryu/controller/ofp_event.py
+++ b/ryu/controller/ofp_event.py
@@ -26,6 +26,9 @@ from ryu import ofproto
 from . import event
 
 
+NAME = 'ofp_event'
+
+
 class EventOFPMsgBase(event.EventBase):
     """
     The base class of OpenFlow event class.
diff --git a/ryu/controller/ofp_handler.py b/ryu/controller/ofp_handler.py
index 7b4bfd1..4f439c2 100644
--- a/ryu/controller/ofp_handler.py
+++ b/ryu/controller/ofp_handler.py
@@ -51,11 +51,13 @@ from ryu.ofproto import ofproto_parser
 class OFPHandler(ryu.base.app_manager.RyuApp):
     def __init__(self, *args, **kwargs):
         super(OFPHandler, self).__init__(*args, **kwargs)
-        self.name = 'ofp_event'
+        self.name = ofp_event.NAME
+        self.controller = None
 
     def start(self):
         super(OFPHandler, self).start()
-        return hub.spawn(OpenFlowController())
+        self.controller = OpenFlowController()
+        return hub.spawn(self.controller)
 
     def _hello_failed(self, datapath, error_desc):
         self.logger.error(error_desc)
-- 
2.7.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to