class fv2d3(): def __init__(self, user = "******", passw="0penfl0w", \ host="flowvisor.openflow.interop.net", port = 9090, jsonport = 8081): self.id = -1 self.cntstr = "https://%s:%s@%s:%d" % (user, passw, host, int(jsonport)) self.serverport = port self.connect() self.initialize() self.registerCallbacks() self.httpd = TCPServer((IP, 8000), FVHTTPHandler) self.startservers() def nextid(self): self.id = self.id + 1 return self.id def getFLLinks(self): url = 'http://45.0.88.7:8080/wm/topology/links/json' request = urllib2.Request(url, None, {'Content-Type':'application/json'}) try: response = urllib2.urlopen(request) resp_text = response.read() except: print "Exception:", e print resp_text # # Get the current state from FV # def initialize(self): self.ls = json.loads(self.fv.getLinks()['valueAsJson']) self.dev = json.loads(self.fv.listDevices()['valueAsJson']) self.slices = json.loads(self.fv.listSlices()['valueAsJson']) self.flowspace = json.loads(self.fv.listFlowSpace()['valueAsJson']) self.setHash() self.compute() def setHash(self): self.dev.sort() self.devices = [] for d in self.dev: self.devices.append(d) self.links = [] for link in self.ls: link["id"] = self.nextid() self.links.append(link) del self.dev del self.ls def compute(self): self.buildSliceInfo() self.buildTopos() def buildSliceInfo(self): self.nodesPerSlice = { slice:[] for slice in self.slices } self.linksPerSlice = {} for fe in self.flowspace: slices = [ actions['sliceName'] for actions in fe['actionsList'] ] for slice in slices: inport = fe['ruleMatch']['inputPort'] dpid = fe['dpid'] if dpid == "all_dpids": break; if (dpid, inport) not in self.linksPerSlice: self.linksPerSlice[(dpid, inport)] = [] self.linksPerSlice[(dpid, inport)].append(slice) if slice in self.nodesPerSlice.keys() and \ dpid not in self.nodesPerSlice[slice]: self.nodesPerSlice[slice].append(dpid) def buildTopos(self): self.sliceTopos = { slice:[] for slice in self.slices} for link in self.links: src = (link['srcDPID'], int(link['srcPort'])) dst = (link['dstDPID'], int(link['dstPort'])) try: for slice in self.linksPerSlice[src]: if slice in self.linksPerSlice[dst] and \ link not in self.sliceTopos[slice]: self.sliceTopos[slice].append(link) except KeyError as inst: continue #print "KeyError on: %s" % inst self.convertTod3() def convertTod3(self): self.topos = {} self.topos['full'] = {} for slice in self.slices: self.topos[slice] = {} self.topos[slice]['nodes'] = [] curr = {} self.id = -1 for dev in self.nodesPerSlice[slice]: curr[dev] = self.nextid() self.topos[slice]['nodes'].append({"id" : curr[dev], "name" : dev }) try: self.topos[slice]['links'] = [ {"source" :curr[link['srcDPID']],\ "target" : curr[link['dstDPID']], \ "value" : 0, "id" : link['id']} \ for link in self.sliceTopos[slice] ] except Exception as inst: print "Error during slice topo build: %s" % inst try: self.topos['full']['nodes'] = [ {"id" : self.devices.index(dev), "name" : dev, \ "index" : self.devices.index(dev) } \ for dev in self.devices ] self.topos['full']['links'] = [ {"source" : self.devices.index(link['srcDPID']), \ "target" : self.devices.index(link['dstDPID']), \ "value" : 0, "id" : link['id'] } \ for link in self.links ] except Exception as inst: print "Error duing full topo build: %s" % inst def contains(self, dpid, port, link): if (link['srcDPID'] == dpid and link['srcPort'] == port or link['dstDPID'] == dpid and link['dstPort'] == port): return True return False def removeLinkDevice(self, device): for link in self.links: if (link['srcDPID'] == device or link['dstDPID'] == device): try: self.links.remove(link) except Exception as inst: print "Error link remove from device: %s" % inst def removeLink(self, dpid, port): for link in self.links: if contains(dpid, port, link): self.links.remove(link) def removeFullLink(self, link): for l in self.links: if l['srcDPID'] == link['srcDPID'] and \ l['srcPort'] == link['srcPort'] and \ l['dstDPID'] == link['dstDPID'] and \ l['dstPort'] == link['dstPort']: self.links.remove(l) return def connect(self): try: FVHTTPHandler.fv = self.getFV self.fv = ServiceProxy(self.cntstr, JSONParamEncoder) except: print "Connection to FlowVisor using %s failed" % self.cntstr sys.exit() def getFV(self): return self def registerCallbacks(self): host = "http://%s:9090" % IP self.fv.registerTopologyEventCallback(host, "deviceConnected", "DEVICE_CONNECTED") self.fv.registerTopologyEventCallback(host, "deviceDisconnected", "DEVICE_DISCONNECTED") self.fv.registerTopologyEventCallback(host, "portAdded", "PORT_ADDED") self.fv.registerTopologyEventCallback(host, "portRemoved", "PORT_REMOVED") self.fv.registerTopologyEventCallback(host, "linkup", "LINK_UP") self.fv.registerTopologyEventCallback(host, "linkdown", "LINK_DOWN") def deviceConnected(self, dev): device = dev['valueAsJson'] print "Device %s came up" % device if device not in self.devices: self.devices.append(device) self.compute() def deviceDisconnected(self, dev): device = dev['valueAsJson'] self.devices.remove(device) print "Device %s went down" % device self.removeLinkDevice(device) self.compute() def portAdded(self, dpid, port): p = port['valueAsJson'] dp = dpid['valueAsJson'] print "Port %s on %s was added" % (p, dp) def portRemoved(self, dpid, port): p = port['valueAsJson'] dp = dpid['valueAsJson'] print "Port %s on %s was removed" % (p, dp) self.removeLink(dp, p) self.buildTopos() def linkup(self, linkad): l_up = json.loads(linkad['valueAsJson']) print "Link up %s" % l_up l_up['id'] = self.nextid() self.links.append(l_up) self.buildTopos() def linkdown(self, linkad): l_down = json.loads(linkad['valueAsJson']) print "link down %s" % l_down try: self.removeFullLink(l_down) self.buildTopos() except Exception as inst: print "Error while removing link: %s" % inst def slice(self,slicename): if slicename in self.topos: return self.topos[slicename] else: return None def startservers(self): server = SimpleJSONRPCServer((IP, self.serverport)) server.register_function(self.deviceConnected) server.register_function(self.deviceDisconnected) server.register_function(self.portAdded) server.register_function(self.portRemoved) server.register_function(self.linkup) server.register_function(self.linkdown) try: self.fvthread = threading.Thread(target=server.serve_forever) print "Start callback server" self.fvthread.start() self.httpd.serve_forever() except KeyboardInterrupt: server.shutdown() self.unregisterFromFV() def unregisterFromFV(self): self.fv.deregisterTopologyEventCallback("deviceConnected", "DEVICE_CONNECTED") self.fv.deregisterTopologyEventCallback("deviceDisconnected", "DEVICE_DISCONNECTED") self.fv.deregisterTopologyEventCallback("portAdded", "PORT_ADDED") self.fv.deregisterTopologyEventCallback("portRemoved", "PORT_REMOVED") self.fv.deregisterTopologyEventCallback("linkup", "LINK_UP") self.fv.deregisterTopologyEventCallback("linkdown", "LINK_DOWN") self.httpd.shutdown() print "Cleanup done!"
class fv2d3(): def __init__(self, user = "******", passw="0penfl0w", \ host="flowvisor.openflow.interop.net", port = 9090, jsonport = 8081): self.id = -1 self.cntstr = "https://%s:%s@%s:%d" % (user, passw, host, int(jsonport)) self.serverport = port self.connect() self.initialize() self.registerCallbacks() self.httpd = TCPServer((IP, 8000), FVHTTPHandler) self.startservers() def nextid(self): self.id = self.id + 1 return self.id def getFLLinks(self): url = 'http://45.0.88.7:8080/wm/topology/links/json' request = urllib2.Request(url, None, {'Content-Type': 'application/json'}) try: response = urllib2.urlopen(request) resp_text = response.read() except: print "Exception:", e print resp_text # # Get the current state from FV # def initialize(self): self.ls = json.loads(self.fv.getLinks()['valueAsJson']) self.dev = json.loads(self.fv.listDevices()['valueAsJson']) self.slices = json.loads(self.fv.listSlices()['valueAsJson']) self.flowspace = json.loads(self.fv.listFlowSpace()['valueAsJson']) self.setHash() self.compute() def setHash(self): self.dev.sort() self.devices = [] for d in self.dev: self.devices.append(d) self.links = [] for link in self.ls: link["id"] = self.nextid() self.links.append(link) del self.dev del self.ls def compute(self): self.buildSliceInfo() self.buildTopos() def buildSliceInfo(self): self.nodesPerSlice = {slice: [] for slice in self.slices} self.linksPerSlice = {} for fe in self.flowspace: slices = [actions['sliceName'] for actions in fe['actionsList']] for slice in slices: inport = fe['ruleMatch']['inputPort'] dpid = fe['dpid'] if dpid == "all_dpids": break if (dpid, inport) not in self.linksPerSlice: self.linksPerSlice[(dpid, inport)] = [] self.linksPerSlice[(dpid, inport)].append(slice) if slice in self.nodesPerSlice.keys() and \ dpid not in self.nodesPerSlice[slice]: self.nodesPerSlice[slice].append(dpid) def buildTopos(self): self.sliceTopos = {slice: [] for slice in self.slices} for link in self.links: src = (link['srcDPID'], int(link['srcPort'])) dst = (link['dstDPID'], int(link['dstPort'])) try: for slice in self.linksPerSlice[src]: if slice in self.linksPerSlice[dst] and \ link not in self.sliceTopos[slice]: self.sliceTopos[slice].append(link) except KeyError as inst: continue #print "KeyError on: %s" % inst self.convertTod3() def convertTod3(self): self.topos = {} self.topos['full'] = {} for slice in self.slices: self.topos[slice] = {} self.topos[slice]['nodes'] = [] curr = {} self.id = -1 for dev in self.nodesPerSlice[slice]: curr[dev] = self.nextid() self.topos[slice]['nodes'].append({ "id": curr[dev], "name": dev }) try: self.topos[slice]['links'] = [ {"source" :curr[link['srcDPID']],\ "target" : curr[link['dstDPID']], \ "value" : 0, "id" : link['id']} \ for link in self.sliceTopos[slice] ] except Exception as inst: print "Error during slice topo build: %s" % inst try: self.topos['full']['nodes'] = [ {"id" : self.devices.index(dev), "name" : dev, \ "index" : self.devices.index(dev) } \ for dev in self.devices ] self.topos['full']['links'] = [ {"source" : self.devices.index(link['srcDPID']), \ "target" : self.devices.index(link['dstDPID']), \ "value" : 0, "id" : link['id'] } \ for link in self.links ] except Exception as inst: print "Error duing full topo build: %s" % inst def contains(self, dpid, port, link): if (link['srcDPID'] == dpid and link['srcPort'] == port or link['dstDPID'] == dpid and link['dstPort'] == port): return True return False def removeLinkDevice(self, device): for link in self.links: if (link['srcDPID'] == device or link['dstDPID'] == device): try: self.links.remove(link) except Exception as inst: print "Error link remove from device: %s" % inst def removeLink(self, dpid, port): for link in self.links: if contains(dpid, port, link): self.links.remove(link) def removeFullLink(self, link): for l in self.links: if l['srcDPID'] == link['srcDPID'] and \ l['srcPort'] == link['srcPort'] and \ l['dstDPID'] == link['dstDPID'] and \ l['dstPort'] == link['dstPort']: self.links.remove(l) return def connect(self): try: FVHTTPHandler.fv = self.getFV self.fv = ServiceProxy(self.cntstr, JSONParamEncoder) except: print "Connection to FlowVisor using %s failed" % self.cntstr sys.exit() def getFV(self): return self def registerCallbacks(self): host = "http://%s:9090" % IP self.fv.registerTopologyEventCallback(host, "deviceConnected", "DEVICE_CONNECTED") self.fv.registerTopologyEventCallback(host, "deviceDisconnected", "DEVICE_DISCONNECTED") self.fv.registerTopologyEventCallback(host, "portAdded", "PORT_ADDED") self.fv.registerTopologyEventCallback(host, "portRemoved", "PORT_REMOVED") self.fv.registerTopologyEventCallback(host, "linkup", "LINK_UP") self.fv.registerTopologyEventCallback(host, "linkdown", "LINK_DOWN") def deviceConnected(self, dev): device = dev['valueAsJson'] print "Device %s came up" % device if device not in self.devices: self.devices.append(device) self.compute() def deviceDisconnected(self, dev): device = dev['valueAsJson'] self.devices.remove(device) print "Device %s went down" % device self.removeLinkDevice(device) self.compute() def portAdded(self, dpid, port): p = port['valueAsJson'] dp = dpid['valueAsJson'] print "Port %s on %s was added" % (p, dp) def portRemoved(self, dpid, port): p = port['valueAsJson'] dp = dpid['valueAsJson'] print "Port %s on %s was removed" % (p, dp) self.removeLink(dp, p) self.buildTopos() def linkup(self, linkad): l_up = json.loads(linkad['valueAsJson']) print "Link up %s" % l_up l_up['id'] = self.nextid() self.links.append(l_up) self.buildTopos() def linkdown(self, linkad): l_down = json.loads(linkad['valueAsJson']) print "link down %s" % l_down try: self.removeFullLink(l_down) self.buildTopos() except Exception as inst: print "Error while removing link: %s" % inst def slice(self, slicename): if slicename in self.topos: return self.topos[slicename] else: return None def startservers(self): server = SimpleJSONRPCServer((IP, self.serverport)) server.register_function(self.deviceConnected) server.register_function(self.deviceDisconnected) server.register_function(self.portAdded) server.register_function(self.portRemoved) server.register_function(self.linkup) server.register_function(self.linkdown) try: self.fvthread = threading.Thread(target=server.serve_forever) print "Start callback server" self.fvthread.start() self.httpd.serve_forever() except KeyboardInterrupt: server.shutdown() self.unregisterFromFV() def unregisterFromFV(self): self.fv.deregisterTopologyEventCallback("deviceConnected", "DEVICE_CONNECTED") self.fv.deregisterTopologyEventCallback("deviceDisconnected", "DEVICE_DISCONNECTED") self.fv.deregisterTopologyEventCallback("portAdded", "PORT_ADDED") self.fv.deregisterTopologyEventCallback("portRemoved", "PORT_REMOVED") self.fv.deregisterTopologyEventCallback("linkup", "LINK_UP") self.fv.deregisterTopologyEventCallback("linkdown", "LINK_DOWN") self.httpd.shutdown() print "Cleanup done!"