backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / app / simple_switch_rest_13.py
1 # Copyright (C) 2016 Nippon Telegraph and Telephone Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 import json
17
18 from ryu.app import simple_switch_13
19 from ryu.controller import ofp_event
20 from ryu.controller.handler import CONFIG_DISPATCHER
21 from ryu.controller.handler import set_ev_cls
22 from ryu.app.wsgi import ControllerBase
23 from ryu.app.wsgi import Response
24 from ryu.app.wsgi import route
25 from ryu.app.wsgi import WSGIApplication
26 from ryu.lib import dpid as dpid_lib
27
28 simple_switch_instance_name = 'simple_switch_api_app'
29 url = '/simpleswitch/mactable/{dpid}'
30
31
32 class SimpleSwitchRest13(simple_switch_13.SimpleSwitch13):
33
34     _CONTEXTS = {'wsgi': WSGIApplication}
35
36     def __init__(self, *args, **kwargs):
37         super(SimpleSwitchRest13, self).__init__(*args, **kwargs)
38         self.switches = {}
39         wsgi = kwargs['wsgi']
40         wsgi.register(SimpleSwitchController,
41                       {simple_switch_instance_name: self})
42
43     @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
44     def switch_features_handler(self, ev):
45         super(SimpleSwitchRest13, self).switch_features_handler(ev)
46         datapath = ev.msg.datapath
47         self.switches[datapath.id] = datapath
48         self.mac_to_port.setdefault(datapath.id, {})
49
50     def set_mac_to_port(self, dpid, entry):
51         mac_table = self.mac_to_port.setdefault(dpid, {})
52         datapath = self.switches.get(dpid)
53
54         entry_port = entry['port']
55         entry_mac = entry['mac']
56
57         if datapath is not None:
58             parser = datapath.ofproto_parser
59             if entry_port not in mac_table.values():
60
61                 for mac, port in mac_table.items():
62
63                     # from known device to new device
64                     actions = [parser.OFPActionOutput(entry_port)]
65                     match = parser.OFPMatch(in_port=port, eth_dst=entry_mac)
66                     self.add_flow(datapath, 1, match, actions)
67
68                     # from new device to known device
69                     actions = [parser.OFPActionOutput(port)]
70                     match = parser.OFPMatch(in_port=entry_port, eth_dst=mac)
71                     self.add_flow(datapath, 1, match, actions)
72
73                 mac_table.update({entry_mac: entry_port})
74         return mac_table
75
76
77 class SimpleSwitchController(ControllerBase):
78
79     def __init__(self, req, link, data, **config):
80         super(SimpleSwitchController, self).__init__(req, link, data, **config)
81         self.simple_switch_app = data[simple_switch_instance_name]
82
83     @route('simpleswitch', url, methods=['GET'],
84            requirements={'dpid': dpid_lib.DPID_PATTERN})
85     def list_mac_table(self, req, **kwargs):
86
87         simple_switch = self.simple_switch_app
88         dpid = dpid_lib.str_to_dpid(kwargs['dpid'])
89
90         if dpid not in simple_switch.mac_to_port:
91             return Response(status=404)
92
93         mac_table = simple_switch.mac_to_port.get(dpid, {})
94         body = json.dumps(mac_table)
95         return Response(content_type='application/json', body=body)
96
97     @route('simpleswitch', url, methods=['PUT'],
98            requirements={'dpid': dpid_lib.DPID_PATTERN})
99     def put_mac_table(self, req, **kwargs):
100
101         simple_switch = self.simple_switch_app
102         dpid = dpid_lib.str_to_dpid(kwargs['dpid'])
103         try:
104             new_entry = req.json if req.body else {}
105         except ValueError:
106             raise Response(status=400)
107
108         if dpid not in simple_switch.mac_to_port:
109             return Response(status=404)
110
111         try:
112             mac_table = simple_switch.set_mac_to_port(dpid, new_entry)
113             body = json.dumps(mac_table)
114             return Response(content_type='application/json', body=body)
115         except Exception as e:
116             return Response(status=500)