def get_flow_data(self, req, **_kwargs): """Get switch data """ # TODO: merge with get_flow_stats if req.GET: lst = {} if req.GET.get("list") == "switches": lst = {t[0]: t[0] for t in self.api.get_switches()} if req.GET.get("switchdesc"): dpid = int(req.GET["switchdesc"]) lst = self.api.get_switch_desc(dpid) if req.GET.get("portdesc"): dpid = int(req.GET["portdesc"]) lst = self.api.get_port_desc(dpid) if req.GET.get("portstat"): dpid = int(req.GET["portstat"]) lst = self.api.get_port_stat(dpid) if req.GET.get("flowsumm"): dpid = int(req.GET["flowsumm"]) lst = self.api.get_flow_summary(dpid) if req.GET.get("tablestat"): dpid = int(req.GET["tablestat"]) lst = self.api.get_table_stat(dpid) res = Response(content_type="application/json") res.json = lst return res return Response(status=400) # bad request
def req_handler_sfc_add(self, req, **kwargs): sfc = ServiceFunctionChain.from_json(req.body, self.app.ip_to_dp) if self.app.find_service(sfc.hook): return Response(status=409) self.app.add_service_hook(sfc) self.app.services[sfc.label] = sfc return Response(status=200)
def mod_flow(self, req, table, **kwargs): """ simulate flow mod event """ msg = json.loads(req.body) if table == "vlan": self._mod_flow_vlan(msg) elif table == "termmac": self._mod_flow_termmac(msg) elif table == "mpls1": self._mod_flow_mpls1(msg) elif table == "unicast": self._mod_flow_unicast(msg) elif table == "acl": self._mod_flow_acl(msg) else: _LOG.error("bad flow mod %s %s", table, msg) return Response(status=404) return Response(status=200)
def _access_switch(self, req, switchid, vlan_id, func, waiters): try: rest = req.json if req.body else {} except ValueError: QoSController._LOGGER.debug('invalid syntax %s', req.body) return Response(status=400) try: dps = self._OFS_LIST.get_ofs(switchid) vid = QoSController._conv_toint_vlanid(vlan_id) except ValueError as message: return Response(status=400, body=str(message)) msgs = [] for f_ofs in dps.values(): function = getattr(f_ofs, func) try: if waiters is not None: msg = function(rest, vid, waiters) else: msg = function(rest, vid) except ValueError as message: return Response(status=400, body=str(message)) msgs.append(msg) body = json.dumps(msgs) return Response(content_type='application/json', body=body)
def __wrapper(self, req, **kwargs): try: try: body = req.json if req.body else {} except ValueError: raise ValueError('Invalid syntax %s', req.body) kwargs.update(body) for key, converter in keywords.items(): value = kwargs.get(key, None) if value is None: raise ValueError('%s not specified' % key) kwargs[key] = converter(value) except ValueError as e: return Response(content_type='application/json', body={"error": str(e)}, status=400) try: return method(self, **kwargs) except Exception as e: status = 500 body = { "error": str(e), "status": status, } return Response(content_type='application/json', body=json.dumps(body), status=status)
def mod_group(self, req, name, **kwargs): """ simulare group mod event """ msg = json.loads(req.body) if name == "l2_interface": self._mod_group_l2_interface(msg) elif name == "l3_unicast": self._mod_group_l3_unicast(msg) elif name == "mpls_interface": self._mod_group_mpls_interface(msg) elif name == "mpls_l2_vpn": pass elif name == "mpls_l3_vpn": self._mod_group_l3_vpn(msg) elif name == "mpls_tun1": self._mod_group_mpls_tun1(msg) elif name == "mpls_tun2": pass elif name == "mpls_swap": self._mod_group_mpls_swap(msg) else: _LOG.error("bad group mod %s %s", name, msg) return Response(status=404) return Response(status=200)
def _set_rule(self, req, switchid, vlan_id=VLANID_NONE): try: rule = req.json if req.body else {} except ValueError: FirewallController._LOGGER.debug('invalid syntax %s', req.body) return Response(status=400) try: dps = self._OFS_LIST.get_ofs(switchid) vid = FirewallController._conv_toint_vlanid(vlan_id) except ValueError as message: return Response(status=400, body=str(message)) msgs = [] rule = rule["rules"] for f_ofs in dps.values(): for rule1 in rule: try: # f_ofs is <ryu.app.rest_firewall.Firewall object at 0x7fb5be59ca90> msg = f_ofs.set_rule(rule1, self.waiters, vid) msgs.append(msg) except ValueError as message: return Response(status=400, body=str(message)) # print msgs body = json.dumps(msgs) return Response(content_type='application/json', body=body)
def put_param(self, req, **kwargs): response = {} simple_switch = self.simple_switch_app obj = kwargs["obj"] try: new_value = req.json if req.body else {} except ValueError: raise Response(status=400) print("PUT obj: {} new_value: {}".format(obj, new_value)) # if key not in globals().keys():# or new_value[key] not in globals().keys(): # return Response(status=404) for key in new_value: if obj not in dir(self.simple_switch_app): return Response(status=404) try: # obj = str_to_class(key) obj = getattr(self.simple_switch_app, key) print("PUT obj: {} old_value: {} new_value: {}".format( key, obj, new_value[key])) setattr(self.simple_switch_app, key, new_value[key]) response[key] = new_value[key] except Exception as e: return Response(status=500) body = json.dumps(response) return Response(content_type='application/json', body=body, charset='UTF-8')
def ruleNonList(self, req, **kwargs): print("REST request for /task3/rule/{ruleid} '{}'".format( kwargs["ruleid"])) if req.method == "GET": # Get a single rule if "ruleid" in kwargs: ruleid = int(kwargs["ruleid"]) if ruleid >= 0 and ruleid < len(self.data["rules"]): return json.dumps(self.data["rules"][ruleid]) + "\n" else: print("Uh-oh %d" % (len(self.data["rules"]), )) return Response(status=404, body="Not found") else: return Response(status=404, body="Not found") elif req.method == "DELETE": # Delete a single rule if "ruleid" in kwargs: ruleid = int(kwargs["ruleid"]) if ruleid >= 0 and ruleid < len(self.data["rules"]): del self.data["rules"][ruleid] return "\n" else: return Response(status=404, body="Not found") else: return Response(status=404, body="Not found")
def wrapper(self, req, *args, **kwargs): # Parse request json body try: if req.body: # We use ast.literal_eval() to parse request json body # instead of json.loads(). # Because we need to parse binary format body # in send_experimenter(). body = ast.literal_eval(req.body.decode('utf-8')) else: body = {} except SyntaxError: LOG.exception('Invalid syntax: %s', req.body) return Response(status=400) # Get datapath_id from request parameters dpid = body.get('dpid', None) if not dpid: try: dpid = kwargs.pop('dpid') except KeyError: LOG.exception('Cannot get dpid from request parameters') return Response(status=400) # Get datapath instance from DPSet try: dp = self.dpset.get(int(str(dpid), 0)) except ValueError: LOG.exception('Invalid dpid: %s', dpid) return Response(status=400) if dp is None: LOG.error('No such Datapath: %s', dpid) return Response(status=404) # Get lib/ofctl_* module try: ofctl = supported_ofctl.get(dp.ofproto.OFP_VERSION) except KeyError: LOG.exception('Unsupported OF version: version=%s', dp.ofproto.OFP_VERSION) return Response(status=501) # Invoke StatsController method try: method(self, req, dp, ofctl, body, *args, **kwargs) return Response(status=200) except ValueError: LOG.exception('Invalid syntax: %s', req.body) return Response(status=400) except AttributeError: LOG.exception('Unsupported OF request in this version: %s', dp.ofproto.OFP_VERSION) return Response(status=501) except CommandNotFoundError as e: LOG.exception(e.message) return Response(status=404) except PortNotFoundError as e: LOG.exception(e.message) return Response(status=404)
def port(self, req, **kwargs): simple_switch = self.simple_switch_app if simple_switch.ev2 is not None: return Response(content_type='application/json', body=json.dumps(simple_switch.ev2.msg.to_jsondict(), ensure_ascii=True, indent=3, sort_keys=True)) else: return Response(status=503)
def get_meter_form(self, req, **_kwargs): """Connect with meter form """ if req.POST: res = Response() res.body = self.api.process_meter_message(req.json) return res return Response(status=400) # bad request
def get_flow_stats(self, req, **_kwargs): """Get stats """ if req.GET['status'] and req.GET['dpid']: res = Response(content_type="application/json") res.json = self.api.get_stats(req.GET['status'], req.GET['dpid']) return res return Response(status=404) # Resource does not exist
def post_group_form(self, req, **_kwargs): """Connect with group form """ if req.POST: res = Response() s = self.api.process_group_message(req.json) res.text = s if PYTHON3 else unicode(s, "utf-8") return res return Response(status=400) # bad request
def get_logs(self, req, **_kwargs): """Get log mesages """ if req.GET: logs = self.api.read_logs() res = Response(content_type="application/json") res.json = logs return res return Response(status=400) # bad request
def post_flow_delete(self, req, **_kwargs): """Receive flows delete request """ if req.POST: res = Response() s = self.api.delete_flow_list(req.json) res.text = s if PYTHON3 else unicode(s, "utf-8") return res return Response(status=400) # bad request
def post_reset_flow_monitor(self, req, **_kwargs): """Reset flows monitoring data """ if req.POST: res = Response() s = self.api.rest_flow_monitoring(req.json) res.text = s if PYTHON3 else unicode(s, "utf-8") return res return Response(status=400) # bad request
def get_flow_stats(self, req): """Get stats """ if 'status' in req.GET and 'dpid' in req.GET: res = Response(content_type="application/json") res.json = self.ctrl_api.get_stats(req.GET['status'], req.GET['dpid']) return res return Response(status=404) # Resource does not exist
def req_handler_lldp_period(self, req, **kwargs): if req.method == "GET": return Response( content_type="application/json", body=json.dumps({"period": self.app.monitor.period}, indent=2), ) else: data = json.loads(req.body) self.app.monitor.period = data["period"] return Response(status=200)
def configure_links(self, req, **kwargs): try: json_in = req.json if req.body else {} except ValueError: raise Response(status=400) try: config_list = json_in['connected'] except Exception as e: return Response(status=500) self.red_off(None) simple_switch = self.simple_switch_app link_list = get_link(simple_switch) queue = [] original_links = [(link.src.dpid, link.dst.dpid) for link in link_list] down_links = [] for link in link_list: src = link.src.dpid dst = link.dst.dpid if ([src, dst] not in config_list) and ([dst, src] not in config_list): parser = get_switch(simple_switch, src)[0].dp.ofproto_parser ofproto = get_switch(simple_switch, src)[0].dp.ofproto mod1 = parser.OFPPortMod( datapath=get_switch(simple_switch, src)[0].dp, port_no=link.src.port_no, hw_addr=link.src.hw_addr, config=(ofproto.OFPPC_NO_RECV | ofproto.OFPPC_NO_FWD), mask=(ofproto.OFPPC_NO_FWD | ofproto.OFPPC_NO_RECV)) queue.append([mod1, get_switch(simple_switch, src)[0].dp]) mod2 = parser.OFPPortMod( datapath=get_switch(simple_switch, dst)[0].dp, port_no=link.dst.port_no, hw_addr=link.dst.hw_addr, config=(ofproto.OFPPC_NO_RECV | ofproto.OFPPC_NO_FWD), mask=(ofproto.OFPPC_NO_FWD | ofproto.OFPPC_NO_RECV)) queue.append([mod2, get_switch(simple_switch, dst)[0].dp]) down_links.append((src, dst)) original_links = set(original_links) down_links = set(down_links) up_links = original_links - down_links for link in up_links: requests.get("http://192.168.4." + str(link[0]) + ":1142/red_light_on") requests.get("http://192.168.4." + str(link[1]) + ":1142/red_light_on") # We use a message queue to avoid changing the length # of link_list in our loop by turning off links. for message in queue: message[1].send_msg(message[0])
def list_mac_table(self, req, **kwargs): simple_switch = self.simple_switch_app dpid = dpid_lib.str_to_dpid(kwargs['dpid']) if dpid not in simple_switch.mac_to_port: return Response(status=404) mac_table = simple_switch.mac_to_port.get(dpid, {}) body = json.dumps(mac_table) return Response(content_type='application/json', body=body)
def delete_flow_rules(self, req, **kwargs): simple_switch = self.simple_switch_app dpid = dpid_lib.str_to_dpid(kwargs['dpid']) if dpid not in simple_switch.switches: return Response(status=404) try: simple_switch.delete_flow(dpid) return Response(status=200) except Exception as e: print e return Response(status=500)
def get_port_statistic(self, req, **kwargs): ufd = self.ufd_app try: body = ufd.get_port_statistic() except Exception as e: return Response(status=http_client.INTERNAL_SERVER_ERROR) if bool(body): return Response(status=http_client.OK, body=body)
def auth_user(self, req, mac, identity, **_kwargs): # TODO Remove flow after being unauthenticated # TODO Investigate the use of diffie-hellman if identity != 'AUTH-NOT': log('%s (%s) authenticated successfuly' % (identity, mac)) ip = IEDS[identity]['ip'] port = IEDS[identity]['port'] log('Installing MMS flows (%s <-> controller)' % identity) add_mms_flow(self.s1, mac, ip) add_mms_flow(self.s2, mac, ip, port) log('Controller connecting to %s (MMS)' % identity) with Mms(ip) as ied: # TODO create second read for the sub publish_goose_to = ied.read() # TODO fix messages log('%s wants to subscribe to GOOSE %s frames' % (identity, publish_goose_to)) log('ABAC: %s can subscribe GOOSE %s frames?' % (identity, publish_goose_to)) if publish_goose_to in self.authenticated: action = 'subscribe' else: action = 'publish' publish_goose = { 'ied': identity, 'action': action, 'address': {'mac': publish_goose_to}, 'protocol': 'GOOSE'} if self.abac.is_allowed(**publish_goose): self.authenticated[mac] = { 'address': mac, 'identity': identity} if publish_goose_to in self.authenticated: log('%s permited to subscribe GOOSE %s frames' % (identity, publish_goose_to)) log('Installing flows requested by %s' % identity) add_goose_flow( self.s2, self.authenticated[publish_goose_to]['address'], publish_goose_to, 2, IEDS[identity]['port']) else: self.authenticated[publish_goose_to] = { 'address': mac, 'identity': identity} log('%s (%s) authorized to subscribe %s GOOSE frames' % (identity, mac, publish_goose_to)) body = json.dumps( "{'AUTH-OK':" + str(self.authenticated[mac]) + '}') return Response(content_type='application/json', body=body) else: log("{'NOT-OK':" + str(self.authenticated[mac]) + '}') return Response(status=400)
def drop_others(self, req, **kwargs): simple_switch = self.simple_switch_app try: values = req.json if req.body else {} except ValueError: raise Response(status=400) try: simple_switch.drop_others_packets(values) return Response(status=200) except Exception as e: return Response(status=500)
def auth_user(self, req, mac, identity, **_kwargs): # TODO Investigate the use of diffie-hellman log('%s (%s) authenticated successfuly' % (identity, mac)) ip = IEDS[identity]['ip'] port = IEDS[identity]['port'] log('Installing MMS flows (%s <-> controller)' % identity) add_mms_flow(self.s1, mac, ip) add_mms_flow(self.s2, mac, ip, port) log('Controller connecting to %s (MMS)' % identity) with Mms(ip) as ied: # TODO create second read for the sub publish_goose_to = ied.read() # TODO fix messages if publish_goose_to in self.authenticated: action = 'subscribe' else: action = 'publish' log('%s wants to %s GOOSE %s frames' % (identity, action, publish_goose_to)) log('ABAC: can %s %s GOOSE %s frames?' % (identity, action, publish_goose_to)) publish_goose = Inquiry(action={ 'type': action, 'dest': publish_goose_to }, resource='GOOSE', subject=identity) if guard.is_allowed(publish_goose): self.authenticated[mac] = {'address': mac, 'identity': identity} if publish_goose_to in self.authenticated: log('%s permited to subscribe GOOSE %s frames' % (identity, publish_goose_to)) log('Installing flows requested by %s' % identity) add_goose_flow(self.s2, self.authenticated[publish_goose_to]['address'], publish_goose_to, 2, IEDS[identity]['port']) else: self.authenticated[publish_goose_to] = { 'address': mac, 'identity': identity } log('%s (%s) authorized to subscribe %s GOOSE frames' % (identity, mac, publish_goose_to)) body = json.dumps("{'AUTH-OK':" + str(self.authenticated[mac]) + '}') return Response(content_type='application/json', body=body) else: # TODO Fix hostapd to send Failure to supp if NOT-OK log("{'NOT-OK': 'Access not granted'}") return Response(status=400)
def deauth_user(self, req, mac, **_kwargs): if mac in self.authenticated: unauthenticated = self.authenticated[mac] identity = unauthenticated['identity'] del self.authenticated[mac] log('%s (%s) deauthenticated successfuly' % (identity, mac)) log('Removing flows requested by %s' % identity) # TODO Remove flow after being unauthenticated body = json.dumps("{'AUTH-NOT':" + str(unauthenticated) + '}') return Response(content_type='application/json', body=body) log("{'NOT-OK': 'MAC not found'}") return Response(status=400)
def _get_path(self, req): try: rest = req.json if req.body else {} except ValueError: return Response(status=400) try: src_ip = rest[REST_SRCIP] dst_ip = rest[REST_DSTIP] return self._cal_path(src_ip, dst_ip) except ValueError: return Response(status=400)
def get_param(self, req, **kwargs): obj = kwargs["obj"] # if obj not in globals().keys(): # or new_value[key] not in globals().keys(): # return Response(status=404) if obj not in dir(self.simple_switch_app ): # or new_value[key] not in globals().keys(): return Response(status=404) # body = json.dumps({obj: str_to_class(obj)}) body = json.dumps({obj: getattr(self.simple_switch_app, obj)}) return Response(content_type='application/json', body=body, charset='UTF-8')
def set_tables(self, req, **kwargs): simple_switch = self.simple_switch_app try: json_in = json.loads(req.body) if req.body else {} except ValueError: raise Response(status=400) try: table_entries = json_in['table_entries'] except Exception as e: return Response(status=500) self.simple_switch_app.forwarding_tables = table_entries