def _hosts(self, req, **kwargs): dpid = None if 'dpid' in kwargs: dpid = dpid_lib.str_to_dpid(kwargs['dpid']) hosts = get_host(self.topology_api_app, dpid) body = json.dumps([host.to_dict() for host in hosts]) return Response(content_type='application/json', body=body)
def _host_add_handler(self, ev): # get_host(self, None) outputs the list of hosts object. self.topo_hosts = get_host(self, None) # print '*'*40,"Switch_set",'*'*40 Host_set = [ host.to_dict() for host in self.topo_hosts ] # pprint.pprint(Host_set) Host_set_json = json.dumps(Host_set, indent=4) Hsj_file = open('./Info/Static/Host_json.json','w+') Hsj_file.write(Host_set_json) Hsj_file.close() self.logger.info("******_host_add_handler, Host_set******" )
def find_hosts(self, dst): all_hosts = get_host(self, None) for host in all_hosts: src = host.mac dpid = host.port.dpid in_port = host.port.port_no self.hosts[src] = (dpid, in_port) if src not in self.mac_to_gid: self.mac_to_gid[src] = self.num_groups gid = self.num_groups self.logger.info("mac: %s, gid: %d", src, gid) self.num_groups += 1 return (dst in self.hosts)
def _get_topology(self): _hosts, _switches, _links = None, None, None while True: hosts = get_host(self) switches = get_switch(self) links = get_link(self) # update topo_map when topology change if [str(x) for x in hosts] == _hosts and [ str(x) for x in switches ] == _switches and [str(x) for x in links] == _links: continue _hosts, _switches, _links = [str(x) for x in hosts ], [str(x) for x in switches ], [str(x) for x in links] for switch in switches: self.port_info.setdefault(switch.dp.id, set()) # record all ports for port in switch.ports: self.port_info[switch.dp.id].add(port.port_no) for host in hosts: # take one ipv4 address as host id if host.ipv4: self.link_info[(host.port.dpid, host.ipv4[0])] = host.port.port_no self.topo_map.add_edge(host.ipv4[0], host.port.dpid, hop=1, delay=0, is_host=True) for link in links: # delete ports linked switches self.port_info[link.src.dpid].discard(link.src.port_no) self.port_info[link.dst.dpid].discard(link.dst.port_no) # s1 -> s2: s1.port, s2 -> s1: s2.port self.link_info[(link.src.dpid, link.dst.dpid)] = link.src.port_no self.link_info[(link.dst.dpid, link.src.dpid)] = link.dst.port_no self.topo_map.add_edge(link.src.dpid, link.dst.dpid, hop=1, is_host=False) if CONF.weight == 'hop': self.show_topo_map() hub.sleep(GET_TOPOLOGY_INTERVAL)
def get_hosts_data(self, ev): hosts = get_host(self, ev.host.port.dpid) for host in hosts: ipv4 = host.ipv4[0] if ipv4 not in self._hosts: dpid = ev.host.port.dpid port_no = ev.host.port.port_no self._hosts.update({ipv4: host}) self._links.append((ipv4, dpid)) self._links.append((dpid, ipv4)) self._dpid_to_port[dpid][ipv4] = port_no self._dpid_to_port.setdefault(ipv4, {}) self._dpid_to_port[ipv4][dpid] = port_no self.logger.info('host added: ' + ipv4)
def get_topology(self): ''' This function brings the links of current topology ''' switch_list = self.get_switches() switches = [switch.dp.id for switch in switch_list] #for switch in switch_list: # print("SWITCH IP: "+str(switch.dp.address)) links_list = get_link(self, None) links = [[link.src.dpid, link.dst.dpid, link.src.port_no] for link in links_list] host_list = get_host(self, None) hosts = [host.port.name for host in host_list] return links
def _show_topo(self): SLEEP_TIME = 5 while True: links = get_link(self.topology_api_app, None) hosts = get_host(self.topology_api_app, None) json_str = json.dumps(links, default=lambda obj: obj.__dict__) links2 = (json.loads(json_str, object_hook=Link.to_dict)) print len(links) print "links:" for link in links2: print link print type(link) print type(link.src) print "hosts" for host in hosts: print host hub.sleep(SLEEP_TIME)
def get_topology_data(self, ev): switch_list = get_switch(self.topology_api_app, None) switches=[switch.dp.id for switch in switch_list] self.net.add_nodes_from(switches) #print "**********List of switches" #for switch in switch_list: #self.ls(switch) #print switch #self.nodes[self.no_of_nodes] = switch #self.no_of_nodes += 1 links_list = get_link(self.topology_api_app, None) #print links_list links=[(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list] #print links self.net.add_edges_from(links) links=[(link.dst.dpid,link.src.dpid,{'port':link.dst.port_no}) for link in links_list] #print links self.net.add_edges_from(links) print "**********List of links" print self.net.edges() #for link in links_list: #print link.dst #print link.src #print "Novo link" #self.no_of_links += 1 hosts_list = get_host(self.topology_api_app, None) print "**********List of hosts" print hosts_list #print "@@@@@@@@@@@@@@@@@Printing both arrays@@@@@@@@@@@@@@@" #for node in self.nodes: # print self.nodes[node] #for link in self.links: # print self.links[link] #print self.no_of_nodes #print self.no_of_links #@set_ev_cls(event.EventLinkAdd) #def get_links(self, ev): #print "################Something##############" #print ev.link.src, ev.link.dst
def myfunction(self): self.logger.info("started new thread") hub.sleep(10) switch_list = get_switch(self.topology_api_app, None) self.switches = [switch.dp.id for switch in switch_list] links_list = get_link(self.topology_api_app, None) self.links = [(link.src.dpid, link.dst.dpid, { 'port': link.src.port_no }) for link in links_list] host_list = get_host(self.topology_api_app, None) self.hosts = [(host.mac, host.port.dpid, { 'port': host.port.port_no }) for host in host_list] self.logger.info("*********Topology Information*************") self.logger.info("Switches %s", self.switches) self.logger.info("Links %s", self.links) self.logger.info("Hosts %s", self.hosts)
def get_links(self, ev): """ This function gives the number of links connected to a switch. For all the switches connected to the controller. """ #print "Printing ip address: {}".format(ev.switch.dp.address) switch_list = get_switch(self, None) switches = [switch.dp.id for switch in switch_list] links_list = get_link(self, None) links = [(link.src.dpid, link.dst.dpid, { 'port': link.src.port_no }) for link in links_list] host_list = [] for i in switches: host_list.append(get_host(self, i)) #Number of links between switches. self.num_links = len(links)
def refresh_topology_data(self): switch_list = get_switch(self, None) switches = [switch.dp.id for switch in switch_list] self.net.add_nodes_from(switches) links_list = get_link(self, None) for link in links_list: self.net.add_edge(link.src.dpid, link.dst.dpid, {'port': link.src.port_no}) try: hosts = [host.mac for host in get_host(self)] for (src, dst, data) in self.net.edges(data=True): try: if dst in hosts: self.net.add_edge(src, dst, {'port': data['port']}) except: self.logger.debug("error %s ", src) return except: self.logger.debug("error")
def get_topology_data(self, ev): print "\n-----------get_topology_data" switch_list = get_switch(self.topology_api_app, None) switches = [switch.dp.id for switch in switch_list] print "-----------List of switches" for switch in switch_list: print switch host_list = get_host(self.topology_api_app, None) print "-----------List of hosts" for host in host_list: print host print "-----------List of links" link_list = get_link(self.topology_api_app, None) for link in link_list: print link print switch_list, host_list, link_list
def _find_host_dpid(self, mac): dpid = None dp_host_port = None for sw_id in self.LSwitches: hosts = get_host(self, sw_id) target_host = [host for host in hosts if host.mac == mac.lower()] if len(target_host) > 0: # assert that Ryu report this host on only one dp and port assert dpid is None assert dp_host_port is None assert len(target_host) == 1 target_host = target_host[0] dpid = sw_id dp_host_port = target_host.port.port_no return dpid, dp_host_port
def _topo_local_sync(self, interval): while self.is_active: self.net = nx.DiGraph() switch_list = get_switch(self.topology_api_app, None) switches = [switch.dp.id for switch in switch_list] self.net.add_nodes_from(switches) links_list = get_link(self.topology_api_app, None) links = [(link.src.dpid, link.dst.dpid, {'port': link.src.port_no}) for link in links_list] self.net.add_edges_from(links) links = [(link.dst.dpid, link.src.dpid, {'port': link.dst.port_no}) for link in links_list] self.net.add_edges_from(links) hosts_list = get_host(self.topology_api_app, None) for host in hosts_list: self.net.add_node(host.mac) self.net.add_edge(host.port.dpid, host.mac, port=host.port.port_no, weight=0) self.net.add_edge(host.mac, host.port.dpid, weight=0) self.printG() print '' hub.sleep(interval)
def forward_path(self, req, **kwargs): # XXX: match flow enties instead src = kwargs['src'] dst = kwargs['dst'] hosts = get_host(self.response_app) # XXX: hard code => static mac address of gateway (NAT) ## find the first matching obj in the list src_host = next((x for x in hosts if x.ipv4[0] == src), None) dst_host = next((x for x in hosts if x.ipv4[0] == dst), None) if src_host is None: return Response(content_type='text/plain', body="Can not found the SRC") if dst_host is None: # return Response(content_type='text/plain', body="Wrong Dst") dst_mac = "00:00:00:ff:00:00" else: dst_mac = dst_host.mac print self.response_app.mac_to_port ## create path from src to dst # find the first dpid connecting to the host path = [] next_dpid = src_host.port.dpid while True: path.append(next_dpid) # hop all dp on the path out_port = self.response_app.mac_to_port[next_dpid][dst_mac] next_dpid = self.response_app.swPort_to_dpid[next_dpid].get( out_port) if next_dpid is None: break # print "check swPort_to_dpid ------" # print self.response_app.swPort_to_dpid body = json.dumps(path) return Response(content_type='application/json', body=body)
def get_topology(self): # add switches switch_list = get_switch(self.topology_api_app, None) switches = [switch.dp.id for switch in switch_list] self.mac_network.add_nodes_from(switches) self.ip_network.add_nodes_from(switches) # add switch links links_list = get_link(self.topology_api_app, None) links = [(link.src.dpid, link.dst.dpid) for link in links_list] self.mac_network.add_edges_from(links) self.ip_network.add_edges_from(links) # add link to port for link in links_list: self.link_to_port[(link.src.dpid, link.dst.dpid)] = link.src.port_no # add hosts hosts_list = get_host(self.topology_api_app, None) hosts = [host.mac for host in hosts_list] self.mac_network.add_nodes_from(hosts) self.hosts_mac = hosts # add host links host_links = [(host.port.dpid, host.mac) for host in hosts_list] self.mac_network.add_edges_from(host_links) host_links = [(host.mac, host.port.dpid) for host in hosts_list] self.mac_network.add_edges_from(host_links) # add switch to host port for host in hosts_list: self.link_to_port[(host.port.dpid, host.mac)] = host.port.port_no self.host_to_switch[host.mac] = host.port.dpid if self.show_or_not and False: print '**********************************topology*****************************************' self.show_varible()
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return if eth.ethertype == ether_types.ETH_TYPE_IPV6: # ignore ipv6 router solicitation message return host_list = get_host(self.topology_api_app, None) arp_pkt = pkt.get_protocol(arp.arp) if eth.ethertype == ether_types.ETH_TYPE_ARP: self.logger.info(" ARP: %s -> %s", arp_pkt.src_ip, arp_pkt.dst_ip) # record source ip to mac address in arp cache self.arp_table[arp_pkt.src_ip] = arp_pkt.src_mac if arp_pkt.opcode == ARP_REQUEST: if arp_pkt.dst_ip in self.arp_table: # build a packet for sending arp reply to src_ip e = ethernet.ethernet(dst=arp_pkt.src_mac, src=self.arp_table[arp_pkt.dst_ip], ethertype=ether_types.ETH_TYPE_ARP) a = arp.arp(hwtype=1, proto=0x800, hlen=6, plen=4, opcode=2, src_mac=self.arp_table[arp_pkt.dst_ip], src_ip=arp_pkt.dst_ip, dst_mac=arp_pkt.src_mac, dst_ip=arp_pkt.src_ip) arp_reply = packet.Packet() arp_reply.add_protocol(e) arp_reply.add_protocol(a) arp_reply.serialize() """ TODO: send self-built ARP reply directly to source """ else: # build a packet for sending arp request to dst_ip arp_request = pkt for host in host_list: if arp_pkt.src_ip not in host.ipv4: actions = [ parser.OFPActionOutput(host.port.port_no) ] data = arp_request.data datapath = self.switch_map[host.port.dpid] out = parser.OFPPacketOut( datapath=datapath, buffer_id=msg.datapath.ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out) if arp_pkt.opcode == ARP_REPLY: # build a packet for sending arp reply to src_ip arp_reply = pkt for host in host_list: if arp_pkt.dst_ip in host.ipv4: actions = [parser.OFPActionOutput(host.port.port_no)] data = arp_reply.data datapath = self.switch_map[host.port.dpid] out = parser.OFPPacketOut( datapath=datapath, buffer_id=msg.datapath.ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out)
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return arp_pkt = pkt.get_protocol(arp.arp) if eth.ethertype == ether_types.ETH_TYPE_ARP: self.logger.info(" ARP: %s -> %s", arp_pkt.src_ip, arp_pkt.dst_ip) """ TODO: flood ARP packets """ return dst = eth.dst src = eth.src dpid = datapath.id self.logger.info("packet in dpid %s src %s dst %s in_port %s", dpid, src, dst, in_port) # get topology self.get_topology() src_switch = None src_port = in_port dst_switch = None dst_port = None host_list = get_host(self.topology_api_app, None) for host in host_list: if host.mac == src: src_switch = host.port.dpid if host.mac == dst: dst_switch = host.port.dpid dst_port = host.port.port_no if dst_switch == None: self.logger.info("Destination switch not found on host %s", dst) return if src_switch == dst_switch: # If source edge switch is equal to destination edge switch, # there is not need to perform BFS """ TODO: install flow rule """ else: bfs_shortest_path = self.bfs_shortest_path(src_switch, src_port, dst_switch, dst_port) if len(bfs_shortest_path) == 0: self.logger.info("Cannot find path!!!") else: pre_node = None for node in reversed(bfs_shortest_path): if node[0] == dst_switch: actions = [parser.OFPActionOutput(dst_port)] match = parser.OFPMatch(in_port=node[2], eth_src=src, eth_dst=dst, eth_type=0x0800) elif node[0] == src_switch: actions = [parser.OFPActionOutput(pre_node[1])] match = parser.OFPMatch(in_port=src_port, eth_src=src, eth_dst=dst, eth_type=0x0800) else: actions = [parser.OFPActionOutput(pre_node[1])] match = parser.OFPMatch(in_port=node[2], eth_src=src, eth_dst=dst, eth_type=0x0800) if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(self.switch_map[node[0]], 1, match, actions, msg.buffer_id) else: self.add_flow(self.switch_map[node[0]], 1, match, actions) pre_node = node
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] out_port = NotImplemented pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) dst = eth.dst src = eth.src is_path_found = False path_id = 0 # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port hosts = [host.mac for host in get_host(self)] if src not in self.net and is_path_found is False and src in hosts: try: weight = abs(self.monitor.port_upload[(dpid, in_port)][-1]) except: weight = 0 self.net.add_node(src) self.net.add_edge(dpid, src, {'port': in_port}, weight=weight) self.net.add_edge(src, dpid, weight=weight) # ignore lldp packet if eth.ethertype == ether_types.ETH_TYPE_LLDP: return # ignore ipv6 packet if eth.ethertype == ether_types.ETH_TYPE_IPV6: return if len(self.all_saved_paths) > 0: for path_obj in self.all_saved_paths: path_src = path_obj[0] path_dst = path_obj[1] path_dpids = path_obj[2] path_id = path_obj[3] if src == path_src and dst == path_dst: # if the switch not in the path if dpid not in path_dpids: return next_dpid = path_dpids[path_dpids.index(dpid) + 1] out_port = self.net[dpid][next_dpid]['port'] path_id = path_id is_is_path_found = True if dst in self.net and is_path_found is False: self.refresh_topology_data() if nx.has_path(self.net, src, dst): new_path = nx.dijkstra_path(self.net, src, dst) path_id = int( random.uniform(self.MIN_PATH_ID, self.MAX_PATH_ID)) self.all_saved_paths.append((src, dst, new_path, path_id)) self.logger.info("Add path Id : %s path : %s", path_id, new_path) if dpid not in new_path: return next_dpid = new_path[new_path.index(dpid) + 1] out_port = self.net[dpid][next_dpid]['port'] else: out_port = ofproto.OFPP_FLOOD elif is_path_found is False: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=dst) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, actions, msg.buffer_id, path_id) return else: self.add_flow(datapath, 1, match, actions, path_id=path_id) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def get_hosts(self): return get_host(self, None)
def _hosts(self): dpid = None hosts = get_host(self.topology_api_app, dpid) body = json.dumps([host.to_dict() for host in hosts]) print('---------body-------') print(body)
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) #self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port self.flag = self.flag + 1 #print self.flag if self.flag == 400: host_list = get_host(self, None) hosts = [host.mac for host in host_list] switch_list = get_switch(self, None) switches = [switch.dp.id for switch in switch_list] links_list = get_link(self, None) link_port = {(link.src.dpid, link.dst.dpid):link.src.port_no for link in links_list} links = [(link.src.dpid, link.dst.dpid) for link in links_list] print('hosts: ',hosts ) print('swiches: ', switches) print('link_port: ', link_port) print('switch_links: ', links) #print self.flag output = subprocess.Popen(["/home/mininet/mininet/util/m","h2","iperf","-c","10.0.0.1"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = str(output.communicate(input="mininet")) cost = string[len(string)-22:len(string)-8] self.bw[("s1","s2")] = {"link_cost":cost} output = subprocess.Popen(["/home/mininet/mininet/util/m","h3","iperf","-c","10.0.0.1"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = str(output.communicate(input="mininet")) cost = string[len(string)-22:len(string)-8] self.bw[("s1","s3")] = {"link_cost":cost} output = subprocess.Popen(["/home/mininet/mininet/util/m","h4","iperf","-c","10.0.0.1"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = str(output.communicate(input="mininet")) cost = string[len(string)-22:len(string)-8] self.bw[("s1","s4")] = {"link_cost":cost} output = subprocess.Popen(["/home/mininet/mininet/util/m","h5","iperf","-c","10.0.0.1"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = str(output.communicate(input="mininet")) cost = string[len(string)-22:len(string)-8] self.bw[("s1","s5")] = {"link_cost":cost} output = subprocess.Popen(["/home/mininet/mininet/util/m","h6","iperf","-c","10.0.0.1"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = str(output.communicate(input="mininet")) cost = string[len(string)-22:len(string)-8] self.bw[("s1","s6")] = {"link_cost":cost} print self.bw
def _topo_local_sync(self, interval): while self.is_active: switch_list = get_switch(self.topology_api_app, None) switches = [switch.dp.id for switch in switch_list] strTopoMessage = '' #print '++++++++++++++++++++++++++++++++++++++++++++++++++++++++' if len(switches) > 0: for sw in switches: tmpStr = str(sw) + '#' strTopoMessage = strTopoMessage + tmpStr #print sw #print '++++++++++++++++++++++++++++++++++++++++++++++++++++++++' strTopoMessage = strTopoMessage.rstrip('#') if strTopoMessage is not '': strTopoMessage = strTopoMessage + '$' links_list = get_link(self.topology_api_app, None) #print '++++++++++++++++++++++++++++++++++++++++++++++++++++++++' tmpStr = '' if len(links_list) > 0: for link in links_list: linkStr = str(link.src.dpid) + ',' + str( link.dst.dpid) + ',' + str( link.src.port_no) + ',' + str( link.dst.port_no) + ',' + str(0) + ')' tmpStr = tmpStr + linkStr #links = [(link.src.dpid, link.dst.dpid, link.src.port_no) for link in links_list] #links = [(link.dst.dpid, link.src.dpid, link.dst.port_no) for link in links_list] tmpStr = tmpStr.rstrip(')') tmpStr = tmpStr + '$' strTopoMessage = strTopoMessage + tmpStr #print tmpStr #print '++++++++++++++++++++++++++++++++++++++++++++++++++++++++' tmpStr = '' hosts_list = get_host(self.topology_api_app, None) for host in hosts_list: #print host #print '' #print host.port.hw_addr for host_i in hosts_list: if host != host_i: if abs(host.port.dpid) == abs( host_i.port.dpid ) and host.port.port_no == host_i.port.port_no: host_i.port.dpid = -abs(host_i.port.dpid) #hosts_list.remove(host_i) if host.port.dpid > 0: host.port.dpid = -abs(host.port.dpid) for host in hosts_list: #print host.port.dpid #print host.mac #print ' || port' + str(host.port.port_no) if host.port.dpid > 0: #print 'tesult host' #print host hostStr = str(host.port.dpid) + ',' + str( host.mac) + ',' + str(host.port.port_no) + '#' tmpStr = tmpStr + hostStr tmpStr = tmpStr.rstrip('#') strTopoMessage = strTopoMessage + tmpStr # self.net.add_node(host.mac) # self.net.add_edge(host.port.dpid, host.mac, port=host.port.port_no, weight=0) # self.net.add_edge(host.mac, host.port.dpid, weight=0) #self.printG() #This is Controller1 #get possiable interLinks massage try: f_rt_switch = open("/home/openlab/openlab/ryu/interLinks.log", "r+") interLinksStr = str(f_rt_switch.read()) f_rt_switch.truncate() finally: f_rt_switch.close() if strTopoMessage is not '': strTopoMessage = strTopoMessage + '$' + interLinksStr strTopoMessage = '1@' + strTopoMessage #self.printG() try: f_rf_switch = open("/home/openlab/openlab/ryu/topoMessage.log", "w+") f_rf_switch.write(str(strTopoMessage)) finally: f_rf_switch.close() #self.printG() hub.sleep(interval)
def _monitor(self): hub.sleep(200) # Wait for the topology discovery host_list = get_host(self, None) switch_list = get_switch(self, None) link_list = get_link(self, None).keys() # Add missing backward links link_pairs = set([(link.src.dpid, link.dst.dpid) for link in link_list]) missing_links = [ Link(link.dst, link.src) for link in link_list if not (link.dst.dpid, link.src.dpid) in link_pairs ] link_list.extend(missing_links) H, S = (len(host_list), len(switch_list)) # The number of nodes, the number of flows and the number of links respectively # +2*H is for the links connecting switches and hosts (bidrectional) N, H2, L = (H + S, H * (H - 1), len(link_list) + 2 * H) # Gather Flow Table Rules self.port_dst_to_rule = {} self.R, self.t = (0, None) for dp in self.datapaths.values(): self._request_stats(dp) hub.sleep(5) # self.port_to_link[switch_id][port_no] gives the corresponding link id # of the port of the switch self.port_to_link = {} # self.port_to_host[switch_id][port_no] gives the corresponding host of # the port of the switch self.port_to_host = {} # switch_to_links[switch_id] provides the id list of the links # connected to the switch switch_to_links = {} # switch_to_rules[switch_id] provides the id list of the rules # in the switch switch_to_rules = {} # Populate the dictionaries for link_id, link in enumerate(link_list): self.port_to_link.setdefault(link.src.dpid, {}) self.port_to_link[link.src.dpid][link.src.port_no] = link_id, link switch_to_links.setdefault(link.src.dpid, []) switch_to_links[link.src.dpid].append(link_id) switch_to_links.setdefault(link.dst.dpid, []) switch_to_links[link.dst.dpid].append(link_id) # Add hosts with the links for host_id, host in enumerate(host_list): rlink_id = len(link_list) + host_id # (Host -> Switch) tlink_id = rlink_id + H # (Switch -> Host) switch_to_links[host.port.dpid].extend([rlink_id, tlink_id]) self.port_to_host.setdefault(host.port.dpid, {}) self.port_to_host[host.port.dpid][ host.port.port_no] = rlink_id, tlink_id, host for switch_id in self.port_dst_to_rule: switch_to_rules[switch_id] = [ rule_id for rule_id, port_no in self.port_dst_to_rule[switch_id].values() ] # Create the routing matricess A = np.zeros((L, H2)) B = np.zeros((self.R, H2)) flow_id = 0 for src_id, src in enumerate(host_list): for dst_id, dst in enumerate(host_list): if src_id != dst_id: # Outgoing link id of src host (Host -> Switch) link_id = len(link_list) + src_id A[link_id, flow_id] = 1 # The first switch on the path switch_id = src.port.dpid # The corresponding rule and out port rule_id, port_no = self.port_dst_to_rule[switch_id][ src.port.port_no, dst.mac] B[rule_id, flow_id] = 1 # Populate through the switches on the path while port_no in self.port_to_link[switch_id]: # Next Link link_id, link = self.port_to_link[switch_id][port_no] A[link_id, flow_id] = 1 # Next Switch switch_id = link.dst.dpid rule_id, port_no = self.port_dst_to_rule[switch_id][ link.dst.port_no, dst.mac] B[rule_id, flow_id] = 1 # Incoming link id of the dst host (Switch -> Host) link_id = len(link_list) + H + dst_id A[link_id, flow_id] = 1 flow_id += 1 im = InferenceModule(A, links=switch_to_links) im2 = InferenceModule(B, links=switch_to_rules) # Start monitoring T = 1000 # The number of time steps self.trace = np.zeros((T, L)) # Time Step x Link ID self.trace2 = np.zeros((T, self.R)) # Time Step x Link ID for self.t in range(T): self.logger.info('Time Step: ' + str(self.t)) for dp in self.datapaths.values(): # Complete measurement self._request_stats(dp) # See SimpleMonitor13._request_stats hub.sleep(1) # Save with open( 'trace_' + datetime.now().strftime('%Y-%m-%d_%H:%M:%S') + '.pkl', 'w') as trace_file: pickle.dump( { 'im': im, 'im2': im2, 'A': A, 'B': B, 'trace': self.trace, 'trace2': self.trace2, 'port_dst_to_rule': self.port_dst_to_rule, 'switch_links': [(link.src.dpid, link.dst.dpid) for link in link_list], 'host_links': [(host.mac, host.port.dpid) for host in host_list], 'switch_to_links': switch_to_links, 'switch_to_rules': switch_to_rules, 'H': H, 'S': S, 'N': N, 'H2': H2, 'L': L, 'R': self.R, 'T': T }, trace_file)
def _packet_in_handler(self, ev): if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] out_port = NotImplemented pkt = packet.Packet(msg.data) ip_pkt = pkt.get_protocol(ipv4.ipv4) eth = pkt.get_protocols(ethernet.ethernet)[0] group_id = 0 path_id = 0 is_path_found = False dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port hosts = [host.mac for host in get_host(self)] if src not in self.net and is_path_found is False and src in hosts: self.net.add_node(src) self.net.add_edge(dpid, src, {'port': in_port}) self.net.add_edge(src, dpid) # ignore lldp packet if eth.ethertype == ether_types.ETH_TYPE_LLDP: return # ignore ipv6 packet if eth.ethertype == ether_types.ETH_TYPE_IPV6: return for multipath_obj in self.all_saved_paths: multipath_obj_src = multipath_obj[0] multipath_obj_dst = multipath_obj[1] multipath_obj_paths = multipath_obj[2] multipath_obj_dpids = multipath_obj[3] multipath_obj_id = multipath_obj[4] if multipath_obj_src == src and multipath_obj_dst == dst: if (self.is_dpid_in_paths(dpid, multipath_obj_paths)) and (dpid not in list(multipath_obj_dpids)): next_dpids_outports = self.get_next_dpids_outports(dpid, multipath_obj_paths) multipath_obj_dpids.append(dpid) outswitch = next_dpids_outports[0] out_port = outswitch[1] path_id = group_id = multipath_obj_id self.group_ids.append(group_id) self.add_group(datapath, next_dpids_outports, group_id) is_path_found = True break else: return if dst in self.net and is_path_found is False: self.refresh_topology_data() if nx.has_path(self.net, src, dst): new_paths = list(nx.all_shortest_new_paths(self.net, src, dst)) if not self.is_dpid_in_new_paths(dpid, new_paths): return dpids = [dpid] path_id = group_id = int(random.uniform(self.MIN_PATH_ID, self.MAX_PATH_ID)) while group_id in self.group_ids: path_id = group_id = int(random.uniform(self.MIN_PATH_ID, self.MAX_PATH_ID)) self.all_saved_paths.append([src, dst, new_paths, dpids, path_id]) for new_path in new_paths: self.logger.info("Add path Id : %s path : %s", path_id, new_path) next_dpids_outports = self.get_next_dpids_outports(dpid, new_paths) outswitch_outport = next_dpids_outports[0] out_port = outswitch_outport[1] self.group_ids.append(group_id) self.add_group(datapath, next_dpids_outports, group_id) else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] elif is_path_found is False: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] if out_port != ofproto.OFPP_FLOOD: group_action = [parser.OFPActionGroup(group_id=group_id)] match = parser.OFPMatch(eth_type=eth.ethertype,eth_dst=dst) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, group_action, msg.buffer_id, path_id=path_id) return else: self.add_flow(datapath, 1, match, group_action, path_id=path_id) actions = [parser.OFPActionOutput(out_port)] data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def get_topology(self, ev): self.create_map(get_switch(self.topology_api_app)) # print get_host(self.topology_api_app) # print type(get_host(self.topology_api_app)) self.create_link_port(get_link(self.topology_api_app), get_host(self.topology_api_app))
def get_qos_topology(self, req, **kwargs): qos_control = self.qos_control_spp hosts = get_host(qos_control, None) body = json.dumps([host.to_dict() for host in hosts]) return Response(content_type='application/json', body=body)
def perform_qos(self): print("Reserving Bandwidth") switch_list = get_switch(self, None) host_list = get_host(self, None) if len(host_list) == 0: print("Topology has not any Hosts") return "Topology has not any Hosts", None, 501 #Source Information for host in host_list: print(host.ipv4[0]) if host.ipv4[0] == self.ip_src: switch_src = host.port.hw_addr #MAC of conected Switch port_src_no = host.port.port_no #PORT Number of connected Host on Switch port_src_name = host.port.name #PORT Name of connected Host on Switch port_src_name = re.findall('''(?<=')\s*[^']+?\s*(?=')''', str(port_src_name)) #Destination Information for host in host_list: if host.ipv4[0] == self.ip_dst: switch_dst = host.port.hw_addr port_dst_no = host.port.port_no port_dst_name = host.port.name port_dst_name = re.findall('''(?<=')\s*[^']+?\s*(?=')''', str(port_dst_name)) print("SRC - NOME DA PORTA DO SWITCH QUE O HOST SRC TA CONECTADO: " + str(port_src_name[0])) print("SRC - NUMERO DA PORTA QUE O SRC TA CONECTADO: " + str(port_src_no)) print("SRC - MAC DO PORTA DO SWITCH QUE O HOST TA CONECTADO: " + str(switch_src)) print("DST - NOME DA PORTA DO SWITCH QUE O HOST DST TA CONECTADO: " + str(port_dst_name[0])) print("DST - NUMERO DA PORTA QUE O DST TA CONECTADO: " + str(port_dst_no)) print("DST - MAC DO PORTA DO SWITCH QUE O HOST DST TA CONECTADO: " + str(switch_dst)) #PROCURE O DPID QUE O HOST ESTA CONECTADO find = False sw_list = requests.get('http://10.0.0.100:8080/stats/switches') sw_list = sw_list.json() for switch in sw_list: rest_link = 'http://10.0.0.100:8080/stats/portdesc/' rest_link = rest_link + str(switch) port_desc = requests.get(rest_link) port_desc = port_desc.json() port_desc = str(port_desc).replace("'", '"') port_desc = json.loads(str(port_desc)) find_dpid = "" for key, value in port_desc.items(): for i in range(len(value)): hw_addr = value[i]['hw_addr'] hw_addr = str(hw_addr) if hw_addr == switch_src: find = True find_dpid = str(key) break if find == True: break if find == True: break #SRC - NOME DA PORTA DO SWITCH QUE O HOST SRC TA CONECTADO: vnet0 #SRC - NUMERO DA PORTA QUE O SRC TA CONECTADO: 2 #SRC - MAC DO PORTA DO SWITCH QUE O HOST TA CONECTADO: a6:c0:32:2b:89:b1 #DST - NOME DA PORTA DO SWITCH QUE O HOST DST TA CONECTADO: enp2s4 #DST - NUMERO DA PORTA QUE O DST TA CONECTADO: 2 #DST - MAC DO PORTA DO SWITCH QUE O HOST DST TA CONECTADO: 00:e0:7d:db:18:d4 self.walk_on_flows(find_dpid, "08:00:27:2c:5c:ff", "08:00:27:0d:2e:eb", switch_src, switch_dst) #[ob.__dict__ for ob in self.PATH])) for path in self.PATH: print("HOST-A VINDO DE: " + str(path.dpid) + " INGRESS: " + str(path.ingress) + " EGRESS: " + str(path.egress)) #By considering path list, make OVS QoS command to each Ingress and Egress port self.apply_rules_on_switches(self.PATH, self.required_bandwidth) return "QoS Path Created", self.PATH, 201
def dpi_init(self, req, **kwargs): # get post data post_data = req.text.split(",") try: hw_addr = post_data[0] ip_addr = post_data[1] dpi_port = post_data[2] except: return "DPI_POST_ERROR" if self.response_app.dpi_info['mac']: return "DPI_ALREADY_EXIST" else: # set dpi_info self.response_app.dpi_info['mac'] = hw_addr self.response_app.dpi_info['ip'] = ip_addr self.response_app.dpi_info['port'] = dpi_port # check whether the dpi is in network for host in get_host(self.response_app): host_dict = host.to_dict() if host_dict['mac'] == hw_addr: self.response_app.dpi_info['dpid'] = host_dict['port'][ 'dpid'] self.response_app.dpi_info['port_no'] = host_dict['port'][ 'port_no'] self.response_app.dpi_info['name'] = host_dict['port'][ 'name'] break else: print "DPI server not found??!" return "DPI_INIT_FAIL" # XXX: remove all datapaths' table. It's better to remove datapath which dpi server attached to. for dp in self.response_app.datapaths.values(): ofproto = dp.ofproto parser = dp.ofproto_parser match = parser.OFPMatch() # remove all flows self.response_app.del_flows(dp, match) # add table miss actions = [ parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] inst = [ parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) ] self.response_app.add_flow(dp, 0, match, actions) ### Create dpi tree when the dpi server connects to the Ryu controller # XXX: only for tree topology. It's better to resolve cyclic topology too. # XXX: not consider switch leave and enter situation # create the topology tree only with links data links = get_link(self.response_app, None) links = [link.to_dict() for link in links] links_r = [] for x in links: a = int(x['src']['dpid']) b = int(x['dst']['dpid']) t = () if a < b: t = (a, b) else: t = (b, a) if t in links_r: continue else: links_r.append(t) # print links_r rdpid = int(self.response_app.dpi_info['dpid']) tree = {rdpid: {'parent': None, 'child': []}} # tn_check is a list matains the dpid in the tree already tn_check = [rdpid] # try to create the tree while len(links_r) > 0: for x in links_r: p = None if x[0] in tn_check: p = x[0] c = x[1] if p is not None and x[1] in tn_check: c = x[0] p = x[1] if p is not None: tn_check.append(c) tree[p]['child'].append(c) tree[c] = {'parent': None, 'child': []} # init child node tree[c]['parent'] = p # only one parent currently links_r.remove(x) break else: print "Link wrong in dpi tree: " + str(x) break print tree self.response_app.dpi_info['tree'] = tree print self.response_app.dpi_info['tree'] # start dpi monitor # print "dpi monitor thread: start" # self.dpi_thread = hub.spawn(self.response_app._dpi_monitor) # add dpi to query queue # XXX: handle Full exception self.response_app.dpiq.put(self.response_app.dpi_info) return "DPI_INIT_OK"
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) #self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port self.i = self.i + 1 if self.i == 500: host_list = get_host(self, None) hosts = [host.mac for host in host_list] switch_list = get_switch(self, None) switches = [switch.dp.id for switch in switch_list] links_list = get_link(self, None) link_port = {(link.src.dpid, link.dst.dpid): link.src.port_no for link in links_list} links = [(link.src.dpid, link.dst.dpid) for link in links_list] print('hosts: ', hosts) print('switches: ', switches) print('link_port: ', link_port) print('switch_links: ', links) output = subprocess.Popen([ "/home/mininet/mininet/util/m", "h2", "iperf", "-c", "10.0.0.1" ], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = str(output.communicate(input="mininet")) string = string[len(string) - 22:len(string) - 8] self.bw[("S1", "S2")] = string output = subprocess.Popen([ "/home/mininet/mininet/util/m", "h3", "iperf", "-c", "10.0.0.1" ], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = str(output.communicate(input="mininet")) string = string[len(string) - 22:len(string) - 8] self.bw[("S1", "S3")] = string output = subprocess.Popen([ "/home/mininet/mininet/util/m", "h4", "iperf", "-c", "10.0.0.1" ], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = str(output.communicate(input="mininet")) string = string[len(string) - 22:len(string) - 8] self.bw[("S1", "S4")] = string output = subprocess.Popen([ "/home/mininet/mininet/util/m", "h5", "iperf", "-c", "10.0.0.1" ], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = str(output.communicate(input="mininet")) string = string[len(string) - 22:len(string) - 8] self.bw[("S1", "S5")] = string output = subprocess.Popen([ "/home/mininet/mininet/util/m", "h6", "iperf", "-c", "10.0.0.1" ], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = str(output.communicate(input="mininet")) string = string[len(string) - 22:len(string) - 8] self.bw[("S1", "S6")] = string print self.bw if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_src=src) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, actions, msg.buffer_id) return else: self.add_flow(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)