Signed-off-by: Isaku Yamahata <[email protected]>
---
 ryu/app/rest_tunnel.py |  230 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 230 insertions(+), 0 deletions(-)
 create mode 100644 ryu/app/rest_tunnel.py

diff --git a/ryu/app/rest_tunnel.py b/ryu/app/rest_tunnel.py
new file mode 100644
index 0000000..bf5ed5b
--- /dev/null
+++ b/ryu/app/rest_tunnel.py
@@ -0,0 +1,230 @@
+# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
+# Copyright (C) 2012 Isaku Yamahata <yamahata at valinux co jp>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, version 3 of the License
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import httplib
+import json
+import logging
+
+import ryu.exception as ryu_exc
+from ryu.app.wsapi import wsapi
+from ryu.app.wsapi import WSPathStaticString
+from ryu.app.wspath import DPID
+from ryu.app.wspath import DPID_FMT
+from ryu.app.wspath import NETWORK_ID
+from ryu.app.wspath import PORT_NO
+from ryu.app.wspath import WSPathInt
+from ryu.app.wspath import WSPathNetwork
+from ryu.app.wspath import WSPathPort
+from ryu.app.wspath import WSPathSwitch
+
+
+LOG = logging.getLogger(__name__)
+
+# REST API for tunneling
+#
+# register GRE tunnel key of this network
+# Fail if the key is already registered
+# POST /v1.0/tunnels/gre/networks/{network-id}/key/{tunnel_key}
+#
+# register GRE tunnel key of this network
+# Success as nop even if the same key is already registered
+# PUT /v1.0/tunnels/gre/networks/{network-id}/key/{tunnel_key}
+#
+# return allocated GRE tunnel key of this network
+# GET /v1.0/tunnels/gre/networks/{network-id}/key
+#
+# get the ports of dpid that are used for tunneling
+# GET /v1.0/tunnels/gre/switches/{dpid}/ports
+#
+# get the dpid of the other end of tunnel
+# GET /v1.0/tunnels/gre/switches/{dpid}/ports/{port-id}/
+#
+# register the dpid of the other end of tunnel
+# Fail if the dpid is already registered
+# POST /v1.0/tunnels/gre/switches/{dpid}/ports/{port-id}/{remote_dpip}
+#
+# register the dpid of the other end of tunnel
+# Success as nop even if the dpid is already registered
+# PUT /v1.0/tunnels/gre/switches/{dpid}/ports/{port-id}/{remote_dpip}
+
+
+REMOTE_DPID = '{remote-dpid}'
+TUNNEL_KEY = '{tunnel-key}'
+
+
+class WSPathTunnelKey(WSPathInt):
+    """ Match a tunnel key value = 32 bit unsigned value """
+    _name = TUNNEL_KEY
+    _base = 16
+    _max_value = 0xffffffff
+
+
+class GRETunnelController(object):
+    def __init__(self, *_args, **kwargs):
+        super(GRETunnelController, self).__init__()
+        self.nw = kwargs['network']
+        self.tunnels = kwargs['tunnels']
+
+        self.ws = wsapi()
+        self.api = self.ws.get_version('1.0')
+        self._register()
+
+    @staticmethod
+    def _get_param_network_id(data):
+        return data[NETWORK_ID]
+
+    @staticmethod
+    def _get_param_tunnel_key(data):
+        return (data[NETWORK_ID], data[TUNNEL_KEY])
+
+    @staticmethod
+    def _get_param_dpid(data):
+        return data[DPID]
+
+    @staticmethod
+    def _get_param_port(data):
+        return (data[DPID], data[PORT_NO])
+
+    @staticmethod
+    def _get_param_remote_dpid(data):
+        return (data[DPID], data[PORT_NO], data[REMOTE_DPID])
+
+    def get_key_handler(self, request, data):
+        network_id = self._get_param_network_id(data)
+        try:
+            tunnel_key = self.tunnels.get_key(network_id)
+        except ryu_exc.TunnelKeyNotFound:
+            request.setResponseCode(httplib.NOT_FOUND)
+            return 'no key found for network %s' % network_id
+
+        request.setHeader('Content-Type', 'application/json')
+        return json.dumps(tunnel_key)
+
+    def delete_key_handler(self, request, data):
+        network_id = self._get_param_network_id(data)
+        try:
+            self.tunnels.delete_key(network_id)
+        except (ryu_exc.NetworkNotFound, ryu_exc.TunnelKeyNotFound):
+            request.setResponseCode(httplib.NOT_FOUND)
+            return 'no key found for network %s' % network_id
+        return ''
+
+    def create_key_handler(self, request, data):
+        network_id, tunnel_key = self._get_param_tunnel_key(data)
+        try:
+            self.tunnels.register_key(network_id, tunnel_key)
+        except (ryu_exc.NetworkAlreadyExist,
+                ryu_exc.TunnelKeyAlreadyExist) as e:
+            request.setResponseCode(httplib.CONFLICT)
+            return str(e)
+        return ''
+
+    def update_key_handler(self, request, data):
+        network_id, tunnel_key = self._get_param_tunnel_key(data)
+        try:
+            self.tunnels.update_key(network_id, tunnel_key)
+        except (ryu_exc.NetworkAlreadyExist,
+                ryu_exc.TunnelKeyAlreadyExist) as e:
+            request.setResponseCode(httplib.CONFLICT)
+            return str(e)
+        return ''
+
+    def list_tunnel_ports_handler(self, request, data):
+        dpid = self._get_param_dpid(data)
+        ports = self.tunnels.list_ports(dpid)
+
+        request.setHeader('Content-Type', 'application/json')
+        return json.dumps(ports)
+
+    def delete_port_handler(self, request, data):
+        dpid, port_no = self._get_param_port(data)
+        try:
+            self.tunnels.delete_port(dpid, port_no)
+        except ryu_exc.PortNotFound as e:
+            request.setResponseCode(httplib.NOT_FOUND)
+            return str(e)
+        return ''
+
+    def get_remote_dpid_handler(self, request, data):
+        dpid, port_no = self._get_param_port(data)
+        try:
+            remote_dpid = self.tunnels.get_remote_dpid(dpid, port_no)
+        except ryu_exc.PortNotFound as e:
+            request.setResponseCode(httplib.NOT_FOUND)
+            return str(e)
+
+        request.setHeader('Content-Type', 'application/json')
+        return json.dumps(DPID_FMT % remote_dpid)
+
+    def create_remote_dpid_handler(self, request, data):
+        dpid, port_no, remote_dpid = self._get_param_remote_dpid(data)
+        try:
+            self.tunnels.register_port(dpid, port_no, remote_dpid)
+        except ryu_exc.PortAlreadyExist as e:
+            request.setResponseCode(httplib.CONFLICT)
+            return str(e)
+        return ''
+
+    def update_remote_dpid_handler(self, request, data):
+        dpid, port_no, remote_dpid = self._get_param_remote_dpid(data)
+        try:
+            self.tunnels.update_port(dpid, port_no, remote_dpid)
+        except ryu_exc.RemoteDPIDAlreadyExist as e:
+            request.setResponseCode(httplib.CONFLICT)
+            return str(e)
+        return ''
+
+    def _register(self):
+        path_gre = (WSPathStaticString('tunnels'), WSPathStaticString('gre'))
+
+        path_key = path_gre + (WSPathStaticString('networks'),
+                               WSPathNetwork(), WSPathStaticString('key'))
+        self.api.register_request(self.get_key_handler, 'GET',
+                                  path_key,
+                                  'get the tunnel key of a network')
+        self.api.register_request(self.delete_key_handler, 'DELETE',
+                                  path_key,
+                                  'delete the tunnel key of a network')
+
+        path_tunnel_key = path_key + (WSPathTunnelKey(), )
+        self.api.register_request(self.create_key_handler, 'POST',
+                                  path_tunnel_key,
+                                  'create the tunnel key of a network')
+        self.api.register_request(self.update_key_handler, 'PUT',
+                                  path_tunnel_key,
+                                  'update the tunnel key of a network')
+
+        path_switches = path_gre + (WSPathStaticString('switches'),
+                                    WSPathSwitch(DPID))
+        path_ports = path_switches + (WSPathStaticString('ports'), )
+        self.api.register_request(self.list_tunnel_ports_handler, 'GET',
+                                  path_ports,
+                                  'get the list of ports used for tunnel')
+
+        path_port = path_ports + (WSPathPort(), )
+        self.api.register_request(self.delete_port_handler, 'DELETE',
+                                  path_port,
+                                  'delete the tunnel port')
+        self.api.register_request(self.get_remote_dpid_handler, 'GET',
+                                  path_port,
+                                  'get the remote dpid')
+
+        path_remote_dpid = path_port + (WSPathSwitch(REMOTE_DPID), )
+        self.api.register_request(self.create_remote_dpid_handler, 'POST',
+                                  path_remote_dpid,
+                                  'register remote dpid')
+        self.api.register_request(self.update_remote_dpid_handler, 'PUT',
+                                  path_remote_dpid,
+                                  'update remote dpid')
-- 
1.7.1.1


------------------------------------------------------------------------------
Better than sec? Nothing is better than sec when it comes to
monitoring Big Data applications. Try Boundary one-second 
resolution app monitoring today. Free.
http://p.sf.net/sfu/Boundary-dev2dev
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to