def _route(self, req, **kwargs): srcdpid=dpid_lib.str_to_dpid(kwargs['srcdpid']) srcport=port_no_lib.str_to_port_no(kwargs['srcport']) dstdpid=dpid_lib.str_to_dpid(kwargs['dstdpid']) dstport=port_no_lib.str_to_port_no(kwargs['dstport']) links = get_link(self.topology_api_app, None) topology = nx.MultiDiGraph() for link in links: print link topology.add_edge(link.src.dpid, link.dst.dpid, src_port=link.src.port_no, dst_port=link.dst.port_no) try: shortest_path = nx.shortest_path(topology, srcdpid, dstdpid) except (nx.NetworkXError, nx.NetworkXNoPath): body = json.dumps([]) print "Error" return Response(content_type='application/json', body=body) ingressPort = NodePortTuple(srcdpid, srcport) egressPort = NodePortTuple(dstdpid, dstport) route = [] route.append(ingressPort) for i in range(0, len(shortest_path)-1): link = topology[shortest_path[i]][shortest_path[i+1]] index = randrange(len(link)) dstPort = NodePortTuple(shortest_path[i], link[index]['src_port']) srcPort = NodePortTuple(shortest_path[i+1], link[index]['dst_port']) route.append(dstPort) route.append(srcPort) route.append(egressPort) body = json.dumps([hop.to_dict() for hop in route]) return Response(content_type='application/json', body=body)
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) for link in links_list: if (link.src.dpid,link.dst.dpid,link.src.port_no) not in list(self.net.edges_iter(data='port')): self.net.add_edge(link.src.dpid,link.dst.dpid,port=link.src.port_no) if (link.dst.dpid,link.src.dpid,link.dst.port_no) not in list(self.net.edges_iter(data='port')): self.net.add_edge(link.dst.dpid,link.src.dpid,port=link.dst.port_no) print "List of links" print self.net.edges(data=True, keys=True)
def get_topology_data(self): if not self.topo_stable: return self.topo_stable = False print 'get_topoloty_data' self.switch_list = get_switch(self.topology_api_app, None) self.mSwitches = [switch.dp.id for switch in self.switch_list] # switch.dp.id self.mDataPaths = [switch.dp for switch in self.switch_list] print type(self.mDataPaths[0]) self.links_list = get_link(self.topology_api_app, None) self.links = [(1, link.src.dpid, link.dst.dpid, link.src.port_no, link.dst.port_no) for link in self.links_list] self.links.sort() # print 'links : ', self.links print '\n\nlinks:' for lk in self.links: print 'switch ', lk[1], ', port ', lk[3], '--> switch ', lk[2], ', port', lk[4] print 'switches : ', self.mSwitches self.constructing_stp_krustal() # Delete all flows in all datapaths for dpid in self.mSwitches: self.delete_flow(dpid) # Install new flows for block in self.ports_to_block: if block in self.ports_to_enable: continue dpid = block[0] port = block[1] self.block_port(dpid, port) # for enable in self.ports_to_enable: # pass self.start_learning = True
def get_topology_data(self, ev): switch_list = get_switch(self.topology_api_app, None) switches=[switch.dp.id for switch in switch_list] 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] print links print switches
def _links(self, req, **kwargs): dpid = None if 'dpid' in kwargs: dpid = dpid_lib.str_to_dpid(kwargs['dpid']) links = get_link(self.topology_api_app, dpid) body = json.dumps([link.to_dict() for link in links]) return Response(content_type='application/json', body=body)
def get_topology_data(self,ev): switch_list = get_switch(self.topology_api_app, None) switches = [switch.dp.id for switch in switch_list] links_list = get_link(self.topology_api_app, None) links = [(link.src.dpid, link.dst.dpid, {'port':(link.src.hw_addr,link.dst.hw_addr)}) for link in links_list] print len(switches) print "total links",len(links)
def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath in_port = msg.match['in_port'] dpid = datapath.id ports = [int(link.to_dict()['src']['port_no'], 16) for link in get_link(self, dpid)] pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) src = eth.src dst = eth.dst time_now = time.time() if in_port not in ports: self.hosts[src] = {'dpid': dpid, 'time': time_now} if eth.ethertype == 0x0806: # ARP packet arp_p = pkt.get_protocol(arp.arp) if arp_p.src_mac != '00:00:00:00:00:00': self.arp[arp_p.src_mac] = {'dpid': dpid, 'ip': arp_p.src_ip, 'time': time_now} if arp_p.dst_mac != '00:00:00:00:00:00': self.arp[arp_p.dst_mac] = {'dpid': dpid, 'ip': arp_p.dst_ip, 'time': time_now} elif eth.ethertype == 0x0800: # IPv4 packet ip_p = pkt.get_protocol(ipv4.ipv4) if ip_p.proto == 17: udp_p = pkt.get_protocol(udp.udp) if udp_p.dst_port == 67 and udp_p.src_port == 68: # DHCP return self.arp[src] = {'dpid': dpid, 'ip': ip_p.src, 'time': time_now} self.arp[dst] = {'dpid': dpid, 'ip': ip_p.dst, 'time': time_now}
def _switch_enter_handler(self, ev): # get_switch(self, None) outputs the list of switches object. self.topo_switches = get_switch(self, None) # get_link(self, None) outputs the list of links object. self.topo_links = get_link(self, None) """ Now you have saved the links and switches of the topo. But they are object, we need to use to_dict() to trans them """ # print '*'*40,"Switch_set",'*'*40 for switch in self.topo_switches: dp = switch.dp dp_no = dpid_to_str(dp.id) if (Switch_set.has_key(dp_no) == False): ports = switch.ports Switch_set[dp_no] = [port.to_dict() for port in ports] # pprint.pprint(Switch_set) Switch_set_json = json.dumps(Switch_set, indent=4) Ssj_file = open('./Info/Static/Switch_json.json','w+') Ssj_file.write(Switch_set_json) Ssj_file.close() # print '*'*40,"Link_set",'*'*40 Link_set = [ link.to_dict() for link in self.topo_links ] # pprint.pprint(Link_set) Link_set_json = json.dumps(Link_set, indent=4) Lsj_file = open('./Info/Static/Link_json.json','w+') Lsj_file.write(Link_set_json) Lsj_file.close() self.logger.info("******_switch_enter_handler, Switch_set & Link_set******")
def get_topology_data(self, ev): switch_list = get_switch(self.topology_data_app, None) switches = [switch.dp.id for switch in switch_list] self.net.add_nodes_from(switches) with open(OFP_LINK_PORT, 'w') as outp: # src_dpid dst_dpid src_dpid_output_port dst_dpid_input_port links_list = get_link(self.topology_data_app, None) # print links_list # add link from one direction links = [(self._hostname_Check(link.src.dpid), self._hostname_Check(link.dst.dpid), {'out_port': link.src.port_no}) for link in links_list] # print links self.net.add_edges_from(links) for link in links: outp.write("%s %s %s\n" % (self._hostname_Check(link[0]), self._hostname_Check(link[1]), link[2]['out_port'])) # add links from oppsite direction links = [(link.dst.dpid, link.src.dpid, {'out_port': link.dst.port_no}) for link in links_list] # print links self.net.add_edges_from(links) for link in links: outp.write("%s %s %s\n" % (self._hostname_Check(link[0]), self._hostname_Check(link[1]), link[2]['out_port']))
def get_topology_data(self, ev): self.logger.info("get_topology_data()") self._update_switch_dpid_list() switch_list = get_switch(self.topology_data_app, None) switches = [switch.dp.id for switch in switch_list] # print "switches: ", switches self.net.add_nodes_from(switches) # print "~~~~~ FRONT ~~~~~~~" # print "switches:", [self._hostname_Check(s) for s in switches] # print "self.link_port: ", self.link_port # print "self.net.nodes():", self.net.nodes() # print "self.net.edges():", self.net.edges() # print "net nodes: ", self.net.nodes() for node in self.net.nodes(): self.link_port.setdefault(node, {}) # with open(OFP_LINK_PORT, 'w') as outp: # src_dpid dst_dpid src_dpid_output_port dst_dpid_input_port links_list = get_link(self.topology_data_app, None) # print "links_list: ", links_list # add link from one direction links = [(link.src.dpid, link.dst.dpid, {'out_port': link.src.port_no}) for link in links_list] # print "links:", links self.net.add_edges_from(links) for link in links: # self.logger.info("%s %s %s\n" % (self._hostname_Check(link[0]), # self._hostname_Check(link[1]), link[2]['out_port'])) # self.logger.info("%s %s %s\n" % (link[0], link[1], link[2]['out_port'])) # outp.write("%s %s %s\n" % (link[0], link[1], link[2]['out_port'])) self.link_port[link[0]][link[1]] = link[2]['out_port']
def get_topology(self, ev): switch_list = get_switch(self.topology_api_app, None) self.create_port_map(switch_list) self.switches = self.switch_port_table.keys() links = get_link(self.topology_api_app, None) self.create_inter_links(links) self.create_access_ports() self.get_graph(self.link_to_port.keys())
def topology(self): #TODO add the topology collecting periodically self.edgenum=0 start = time.time() print start self.switches = get_switch(self) self.links = get_link(self) self.topo_col_num = self.topo_col_num + 1 end = time.time() print end print 'topology collecting time:' print end-start self.topo_col_period = self.topo_col_period + end-start #n=len(self.switches) #m=len(self.links) ## self.startnum=0 ## self.dpids_to_nums={} ## self.nums_to_dpids={} print 'dpids nums:' for switch in self.switches:#TODO this may has error if self.dpids_to_nums.get(switch.dp.id)==None: self.nums_to_dpids[self.startnum] = switch.dp.id self.dpids_to_nums[switch.dp.id] = self.startnum print str(switch.dp.id)+' '+str(self.startnum) self.startnum = self.startnum + 1 print self.dpids_to_nums self.n=self.startnum print 'edges:' self.linkgraph=[] for i in xrange(self.switch_num): self.linkgraph.append([]) for j in xrange(self.switch_num): self.linkgraph[i].append(0) for link in self.links: self.edgenum=self.edgenum+1 srcnum = self.dpids_to_nums[link.src.dpid] dstnum = self.dpids_to_nums[link.dst.dpid] self.linkgraph[srcnum][dstnum]=1 if self.graph[srcnum][dstnum]==0 and self.graph[dstnum][srcnum]==0: print str(srcnum)+' '+str(dstnum) self.dpid_to_port[(link.src.dpid, link.dst.dpid)] = (link.src.port_no, link.dst.port_no) self.dpid_to_port[(link.dst.dpid, link.src.dpid)]=(link.dst.port_no, link.src.port_no) #print>>devicegraph, str(srcnum)+' '+str(dstnum) self.graph[srcnum][dstnum] = 1 self.graph[dstnum][srcnum] = 1 self.undirected[srcnum][dstnum] = 1 self.m=self.m+1 self.G={} for i in xrange(self.switch_num): self.G[i]={} for j in xrange(self.switch_num): if self.linkgraph[i][j]==1 and self.linkgraph[j][i]==1:#TODO if only one way is ok then regard it as not ok self.G[i][j]=1 print self.G print self.linkgraph print self.graph print self.undirected
def linkDeleteHandler(self, ev): link_list = get_link(self.topology_api_app, None) self.debugfile.write("linkdelete events happened"+"\n") self.debugfile.flush() for link in link_list: self.debugfile.write(str(link)+"\n") self.debugfile.flush() self.debugfile.write("the time is: "+str(time.time())+"\n") self.debugfile.flush()
def get_topology_data(self, ev): switch_list = get_switch(self.my_topology_api_app, None) all_switches = [switch.dp.id for switch in switch_list] # links_list = get_link(self.topology_api_app, None) links_list = get_link(self.my_topology_api_app) links = [(link.src.dpid, link.dst.dpid, {'port': link.src.port_no}) for link in links_list] print ">> switches: ", all_switches print ">> links: ", links
def get_topology(self, ev): switch_list = get_switch(self.topology_api_app, None) self.create_port_map(switch_list) self.switches = self.switch_port_table.keys() links = get_link(self.topology_api_app, None) self.create_interior_links(links) self.create_access_ports() self.get_graph(self.link_to_port.keys()) self.shortest_paths = self.all_k_shortest_paths( self.graph, weight='weight', k=CONF.k_paths)
def _new_link_event(self, ev): LOG.info('TOPO_EVENT: New link detected %s -> %s', ev.link.src.dpid, ev.link.dst.dpid) link_list = get_link(self.topology_api_app, None) links = [(link.src.dpid, link.dst.dpid, {'port':link.src.port_no, 'weight':self.DEF_EDGE_WEIGHT}) for link in link_list] self.net.add_edges_from(links) print '****List of links:' print links
def get_topology(self, ev): print("HELLOOOOOO WORLD") switch_list = copy.copy(get_switch(self, None)) links = copy.copy(get_link(self, None)) edges_list=[] for link in links: src = link.src dst = link.src edges_list.append((src.dpid, dst.dpid, {'port': link.src.port_no})) print(links)
def get_topology_data(self, ev): switch_list = get_switch(self.topology_api_app, None) switches = [switch.dp.id for switch in switch_list] link_list = get_link(self.topology_api_app, None) self.net.add_nodes_from(switches) links=[(link.src.dpid,link.dst.dpid, {'port':link.src.port_no}) for link in links_list] self.ned_add_edges_from(links) self.logger.info('******************************** List of links') self.logger.info(self.net.edges())
def get_topology_data(self, ev): print "Beep!" switch_list = get_switch(self.topology_api_app, None) switches = [switch.dp.id for switch in switch_list] 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] # host_list = get_host(self.topology_api_app, None) # hosts = [host.dp.id for host in host_list] # print i print switches print links
def get_topology_data(self, ev): switch_list = get_switch(self.topology_api_app, None) self.switches=[switch.dp.id for switch in switch_list] print '************Switch List*********************' # print self.switches 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] self.switches_nodes=[switch.dp for switch in switch_list] self.net.add_nodes_from(self.switches) self.net.add_edges_from(self.links)
def get_topology_data(self,ev): time.sleep(0.01) 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) print "**********List of links" print self.net.edges() '''while(self.limit>0):
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) 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)
def get_topology(self, ev): switch_list = get_switch(self.topology_api_app, None) #for val in switch_list: # self.file1.write("switch_list "+str(val)+"\n") self.create_port_map(switch_list) self.switches = self.switch_port_table.keys() links = get_link(self.topology_api_app, dpid=None) #self.file1.write("links "+str(links)+"\n") self.create_interior_links(links) self.create_access_ports() self.get_graph(self.link_to_port.keys())
def get_topology(self, ev): # get switches and store them into self.network switch_list = get_switch(self.topology_api_app, None) switches=[switch.dp.id for switch in switch_list] self.network.add_nodes_from(switches) # get links and store them into self.network 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.network.add_edges_from(links) # reverse link. links=[(link.dst.dpid,link.src.dpid,{'port':link.dst.port_no}) for link in links_list] self.network.add_edges_from(links)
def _get_sws_links(self): sws_list = get_switch(self, None) sws = [switch.dp.id for switch in sws_list] links_list = get_link(self, None) links = [] for link in links_list: links.append({'src': link.src.dpid, 'dst': link.dst.dpid, 'port': link.dst.port_no}) return sws, links
def get_topology(self, ev): switch_list = get_switch(self.topology_api_app, None) self.switches = [switch.dp.id for switch in switch_list] print "--------------------------the num of switches is %d---------------------------------------" %len(self.switches) print self.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] #print links if len(self.switches) == 26: #self.switches = self.switch_port_table.keys() #links = get_link(self.topology_api_app, None) self.create_port_map(switch_list) self.create_interior_links(links_list) self.create_access_ports() #self.get_graph(self.link_to_port.keys()) self.get_graph(self.link_to_port.keys())
def get_topology_data(self): switch_list = get_switch(self.topology_api_app, None) #switches=[switch.dp.id for switch in switch_list] for switch in switch_list: self.datapath_list.setdefault(switch.dp.id) self.datapath_list[switch.dp.id] = switch.dp links_list = get_link(self.topology_api_app, None) #Add ports to out_port_table self.update_system_info(links_list) #print self.out_port_table #print self.link_down_route #Install flows in case of proactive behaviour if PROACTIVE and self.all_switches_up(): self.install_all_flows()
def get_topology_data(self): self.threadLock.acquire() #Delay a second for the LLDP to propagate time.sleep(1) switch_list = get_switch(self, None) GlobalTables.switch_list = [switch.dp.id for switch in switch_list] links_list = get_link(self, None) GlobalTables.sw_links = [(link.src.dpid, link.dst.dpid, {'port': link.src.port_no}) for link in links_list] self.threadLock.release() self.logger.info("sw_links: %s", GlobalTables.sw_links) self.logger.info("hosts: %s", GlobalTables.hosts) self.logger.info("mac_to_port: %s", GlobalTables.mac_to_port)
def datapath_change_handler(self, ev): if ev.enter: print "Datapath entered, id %s" % ev.dp.id switch = api.get_switch(self, ev.dp.id)[0] self.switches.append(switch) ports = switch.ports print "Switch : %s" % switch print "Ports :" for port in ports: print port.to_dict() print "Links :" links = api.get_link(self, ev.dp.id) for link in links: print link.to_dict()
def get_topology_data(self): if not self.topo_stable: return False self.topo_stable = False print 'Geting topology data' self.switch_list = get_switch(self.topology_api_app, None) self.mSwitches = [switch.dp.id for switch in self.switch_list] # switch.dp.id self.mDataPaths = [switch.dp for switch in self.switch_list] # print type(self.mDataPaths[0]) self.links_list = get_link(self.topology_api_app, None) self.links = [(1, link.src.dpid, link.dst.dpid, link.src.port_no, link.dst.port_no) for link in self.links_list] self.links.sort() print '\n\nlinks:' for lk in self.links: print 'switch ', lk[1], ', port ', lk[3], '--> switch ', lk[2], ', port', lk[4] print '\nswitches : ', self.mSwitches return True
def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(array.array('B', msg.data)) eth_pkt = pkt.get_protocol(ethernet.ethernet) arp_pkt = pkt.get_protocol(arp.arp) if arp_pkt: links = get_link(self, None) self.data = [link.to_dict() for link in links] for i in self.data: src = int(i['src']['dpid'], 16) dst = int(i['dst']['dpid'], 16) self.portmap.setdefault(src, {}) self.portmap.setdefault(dst, {}) self.portmap[src][dst] = int(i['src']['port_no']) self.portmap[dst][src] = int(i['dst']['port_no']) try: self.graph[src][dst] except: self.graph.add_weighted_edges_from([(src, dst, self.default_weight)]) # path calculation src = int(arp_pkt.src_ip.split('.')[-1]) dst = int(arp_pkt.dst_ip.split('.')[-1]) cur = datapath.id path = nx.shortest_path(self.graph, source=cur, target=dst) for i in xrange(len(path) - 1): src = path[i] dst = path[i + 1] # forward out_port = self.portmap[src][dst] self._add_dynamic_flow(self.datapaths[src], 1, out_port, 2048, nw_src=arp_pkt.src_ip, nw_dst=arp_pkt.dst_ip, soft_timeout=2) self._add_dynamic_flow(self.datapaths[src], 1, out_port, 2054, arp_spa=arp_pkt.src_ip, arp_tpa=arp_pkt.dst_ip, soft_timeout=2) # backward out_port = self.portmap[dst][src] self._add_dynamic_flow(self.datapaths[dst], 1, out_port, 2048, nw_src=arp_pkt.dst_ip, nw_dst=arp_pkt.src_ip, soft_timeout=2) self._add_dynamic_flow(self.datapaths[dst], 1, out_port, 2054, arp_spa=arp_pkt.dst_ip, arp_tpa=arp_pkt.src_ip, soft_timeout=2) src = path[0] dst = path[1] out_port = self.portmap[src][dst] 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) elif eth_pkt: if eth_pkt.dst.split(':')[1] == '00' and eth_pkt.src.split( ':')[1] == '00': self.logger.info("packet in %s %s %s %s", datapath.id, eth_pkt.src, eth_pkt.dst, in_port) links = get_link(self, None) self.data = [link.to_dict() for link in links] for i in self.data: src = int(i['src']['dpid'], 16) dst = int(i['dst']['dpid'], 16) self.portmap.setdefault(src, {}) self.portmap.setdefault(dst, {}) self.portmap[src][dst] = int(i['src']['port_no']) self.portmap[dst][src] = int(i['dst']['port_no']) try: self.graph[src][dst] except: self.graph.add_weighted_edges_from([ (src, dst, self.default_weight) ]) # path calculation src = int(eth_pkt.src.split(':')[-1], 16) dst = int(eth_pkt.dst.split(':')[-1], 16) cur = datapath.id path = nx.dijkstra_path(self.graph, source=cur, target=dst) for i in xrange(len(path) - 1): src = path[i] dst = path[i + 1] # forward out_port = self.portmap[src][dst] self._add_dynamic_flow(self.datapaths[src], 1, out_port, None, eth_src=eth_pkt.src, eth_dst=eth_pkt.dst, soft_timeout=2) # backward out_port = self.portmap[dst][src] self._add_dynamic_flow(self.datapaths[dst], 1, out_port, None, eth_src=eth_pkt.dst, eth_dst=eth_pkt.src, soft_timeout=2) src = path[0] dst = path[1] out_port = self.portmap[src][dst] 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 _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_src = datapath.id # TOPOLOGY DISCOVERY------------------------------------------ switch_list = get_switch(self.topology_api_app, None) switches = [switch.dp.id for switch in switch_list] if self.GLOBAL_VARIABLE == 0: for s in switches: for switch_port in range(1, NUMBER_OF_SWITCH_PORTS + 1): self.port_occupied.setdefault(s, {}) self.port_occupied[s][switch_port] = 0 self.GLOBAL_VARIABLE = 1 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) links_ = [(link.dst.dpid, link.src.dpid, link.dst.port_no) for link in links_list] for l in links_: self.port_occupied[l[0]][l[2]] = 1 # MAC LEARNING------------------------------------------------- self.mac_to_port.setdefault(dpid_src, {}) self.port_to_mac.setdefault(dpid_src, {}) self.mac_to_port[dpid_src][src] = in_port self.mac_to_dpid[src] = dpid_src self.port_to_mac[dpid_src][in_port] = src # HANDLE ARP PACKETS-------------------------------------------- if eth.ethertype == ether_types.ETH_TYPE_ARP: arp_packet = pkt.get_protocol(arp.arp) arp_dst_ip = arp_packet.dst_ip arp_src_ip = arp_packet.src_ip # self.logger.info("It is an ARP packet") # If it is an ARP request if arp_packet.opcode == 1: # self.logger.info("It is an ARP request") if arp_dst_ip in self.ip_to_mac: # self.logger.info("The address is inside the IP TO MAC table") srcIp = arp_dst_ip dstIp = arp_src_ip srcMac = self.ip_to_mac[arp_dst_ip] dstMac = src outPort = in_port opcode = 2 self.send_arp(datapath, opcode, srcMac, srcIp, dstMac, dstIp, outPort) # self.logger.info("packet in %s %s %s %s", srcMac, srcIp, dstMac, dstIp) else: # self.logger.info("The address is NOT inside the IP TO MAC table") srcIp = arp_src_ip dstIp = arp_dst_ip srcMac = src dstMac = dst # learn the new IP address self.ip_to_mac.setdefault(srcIp, {}) self.ip_to_mac[srcIp] = srcMac # Send and ARP request to all the switches opcode = 1 for id_switch in switches: #if id_switch != dpid_src: datapath_dst = get_datapath(self, id_switch) for po in range(1, len(self.port_occupied[id_switch]) + 1): if self.port_occupied[id_switch][po] == 0: outPort = po if id_switch == dpid_src: if outPort != in_port: self.send_arp(datapath_dst, opcode, srcMac, srcIp, dstMac, dstIp, outPort) else: self.send_arp(datapath_dst, opcode, srcMac, srcIp, dstMac, dstIp, outPort) else: srcIp = arp_src_ip dstIp = arp_dst_ip srcMac = src dstMac = dst if arp_dst_ip in self.ip_to_mac: # learn the new IP address self.ip_to_mac.setdefault(srcIp, {}) self.ip_to_mac[srcIp] = srcMac # Send and ARP reply to the switch opcode = 2 outPort = self.mac_to_port[self.mac_to_dpid[dstMac]][dstMac] datapath_dst = get_datapath(self, self.mac_to_dpid[dstMac]) self.send_arp(datapath_dst, opcode, srcMac, srcIp, dstMac, dstIp, outPort) # HANDLE IP PACKETS----------------------------------------------- ip4_pkt = pkt.get_protocol(ipv4.ipv4) if ip4_pkt: src_ip = ip4_pkt.src dst_ip = ip4_pkt.dst src_MAC = src dst_MAC = dst proto = str(ip4_pkt.proto) sport = "0" dport = "0" if proto == "6": tcp_pkt = pkt.get_protocol(tcp.tcp) sport = str(tcp_pkt.src_port) dport = str(tcp_pkt.dst_port) if proto == "17": udp_pkt = pkt.get_protocol(udp.udp) sport = str(udp_pkt.src_port) dport = str(udp_pkt.dst_port) self.logger.info( "Packet in switch: %s, source IP: %s, destination IP: %s, From the port: %s", dpid_src, src_ip, dst_ip, in_port) # self.logger.info("Packet in switch: %s, source MAC: %s, destination MAC: %s, From the port: %s", dpid_src, src, dst, in_port) datapath_dst = get_datapath(self, self.mac_to_dpid[dst_MAC]) dpid_dst = datapath_dst.id self.logger.info(" --- Destination present on switch: %s", dpid_dst) # Shortest path computation path = nx.shortest_path(self.net, dpid_src, dpid_dst) self.logger.info(" --- Shortest path: %s", path) # Set the flows for different cases if len(path) == 1: In_Port = self.mac_to_port[dpid_src][src] Out_Port = self.mac_to_port[dpid_dst][dst] actions_1 = [datapath.ofproto_parser.OFPActionOutput(Out_Port)] actions_2 = [datapath.ofproto_parser.OFPActionOutput(In_Port)] match_1 = parser.OFPMatch(in_port=In_Port, eth_dst=dst) match_2 = parser.OFPMatch(in_port=Out_Port, eth_dst=src) self.add_flow(datapath, 1, match_1, actions_1) self.add_flow(datapath, 1, match_2, actions_2) actions = [datapath.ofproto_parser.OFPActionOutput(Out_Port)] data = msg.data pkt = packet.Packet(data) eth = pkt.get_protocols(ethernet.ethernet)[0] # self.logger.info(" --- Changing destination mac to %s" % (eth.dst)) pkt.serialize() out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) datapath.send_msg(out) elif len(path) >= 2: datapath_src = get_datapath(self, path[0]) datapath_dst = get_datapath(self, path[len(path) - 1]) dpid_src = datapath_src.id #self.logger.info("dpid_src %s", dpid_src) dpid_dst = datapath_dst.id #self.logger.info("dpid_dst %s", dpid_dst) In_Port_src = self.mac_to_port[dpid_src][src] #self.logger.info("In_Port_src %s", In_Port_src) In_Port_dst = self.mac_to_port[dpid_dst][dst] #self.logger.info("In_Port_dst %s", In_Port_dst) Out_Port_src = self.net[path[0]][path[1]]['port'] #self.logger.info("Out_Port_src %s", Out_Port_src) Out_Port_dst = self.net[path[len(path) - 1]][path[len(path) - 2]]['port'] #self.logger.info("Out_Port_dst %s", Out_Port_dst) actions_1_src = [ datapath.ofproto_parser.OFPActionOutput(Out_Port_src) ] match_1_src = parser.OFPMatch(in_port=In_Port_src, eth_type=0x0800, ipv4_src=src_ip, ipv4_dst=dst_ip) self.add_flow(datapath_src, 1, match_1_src, actions_1_src) actions_2_src = [ datapath.ofproto_parser.OFPActionOutput(In_Port_src) ] match_2_src = parser.OFPMatch(in_port=Out_Port_src, eth_type=0x0800, ipv4_src=dst_ip, ipv4_dst=src_ip) self.add_flow(datapath_src, 1, match_2_src, actions_2_src) self.logger.info("Install the flow on switch %s", path[0]) actions_1_dst = [ datapath.ofproto_parser.OFPActionOutput(Out_Port_dst) ] match_1_dst = parser.OFPMatch(in_port=In_Port_dst, eth_type=0x0800, ipv4_src=dst_ip, ipv4_dst=src_ip) self.add_flow(datapath_dst, 1, match_1_dst, actions_1_dst) actions_2_dst = [ datapath.ofproto_parser.OFPActionOutput(In_Port_dst) ] match_2_dst = parser.OFPMatch(in_port=Out_Port_dst, eth_type=0x0800, ipv4_src=src_ip, ipv4_dst=dst_ip) self.add_flow(datapath_dst, 1, match_2_dst, actions_2_dst) self.logger.info("Install the flow on switch %s", path[len(path) - 1]) if len(path) > 2: for i in range(1, len(path) - 1): self.logger.info("Install the flow on switch %s", path[i]) In_Port_temp = self.net[path[i]][path[i - 1]]['port'] Out_Port_temp = self.net[path[i]][path[i + 1]]['port'] dp = get_datapath(self, path[i]) actions_1 = [ dp.ofproto_parser.OFPActionOutput(Out_Port_temp) ] actions_2 = [ dp.ofproto_parser.OFPActionOutput(In_Port_temp) ] match_1 = parser.OFPMatch(in_port=In_Port_temp, eth_type=0x0800, ipv4_src=src_ip, ipv4_dst=dst_ip) match_2 = parser.OFPMatch(in_port=Out_Port_temp, eth_type=0x0800, ipv4_src=dst_ip, ipv4_dst=src_ip) self.add_flow(dp, 1, match_1, actions_1) self.add_flow(dp, 1, match_2, actions_2) # Send the packet to the original switch path_port = self.net[path[0]][path[1]]['port'] actions = [datapath.ofproto_parser.OFPActionOutput(path_port)] data = msg.data pkt = packet.Packet(data) eth = pkt.get_protocols(ethernet.ethernet)[0] # change the mac address of packet eth.src = self.ip_to_mac[src_ip] eth.dst = self.ip_to_mac[dst_ip] # self.logger.info(" --- Changing destination mac to %s" % (eth.dst)) pkt.serialize() out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) datapath.send_msg(out)
def get_topology_data(self, ev): switch_list = get_switch(self.topology_api_app, None) switches=[switch.dp.id for switch in switch_list] 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]
def get_links(self, ev): links = get_link(self.topology_api_app, None) self.create_interior_links(links) self.create_access_ports() self.logger.info("*********************************************************************************************")
def get_topology_data(self): """Topology Info Handling.""" net_sp = nx.Graph() 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) net_sp.add_nodes_from(switches) for switch in switch_list: print switch.dp.id 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] 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] self.net.add_edges_from(links) group = collection.Group('whole') group.topology = self.net group.switches = switches group.links = links links = [(link.src.dpid, link.dst.dpid) for link in links_list] net_sp.add_edges_from(links) constant.ccc = nx.minimum_spanning_tree(net_sp) data_collection.switch_inner_port = [] for link in links_list: inner_port1 = (link.src.dpid, link.src.port_no) inner_port2 = (link.dst.dpid, link.dst.port_no) if inner_port1 not in data_collection.switch_inner_port: data_collection.switch_inner_port.append(inner_port1) if inner_port2 not in data_collection.switch_inner_port: data_collection.switch_inner_port.append(inner_port2) if data_collection.group_list.get('whole') is not None: # print 'a' g = data_collection.group_list.get('whole') g.switches = group.switches g.topology = group.topology g.links = group.links # print g.switches, g.topology, g.links else: # print 'b' data_collection.group_list.update({'whole': group})
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'] 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_src = datapath.id # TOPOLOGY DISCOVERY------------------------------------------ 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) # print links # MAC LEARNING------------------------------------------------- self.mac_to_port.setdefault(dpid_src, {}) self.mac_to_port.setdefault(src, {}) self.port_to_mac.setdefault(dpid_src, {}) self.mac_to_port[dpid_src][src] = in_port self.mac_to_dpid[src] = dpid_src self.port_to_mac[dpid_src][in_port] = src self.logger.info("Packet in the controller from switch: %s", dpid_src) #print self.mac_to_port # HANDLE ARP PACKETS-------------------------------------------- if eth.ethertype == ether_types.ETH_TYPE_ARP: arp_packet = pkt.get_protocol(arp.arp) arp_dst_ip = arp_packet.dst_ip arp_src_ip = arp_packet.src_ip # self.logger.info("ARP packet from switch: %s source IP: %s destination IP: %s from port: %s", dpid_src, arp_src_ip, arp_dst_ip, in_port) # self.logger.info("ARP packet from switch: %s source MAC: %s destination MAC:%s from port: %s", dpid_src, src, dst, in_port) if arp_dst_ip in self.ip_to_mac: if arp_packet.opcode == 1: # send arp reply (SAME SUBNET) dstIp = arp_src_ip srcIp = arp_dst_ip dstMac = src srcMac = self.ip_to_mac[arp_dst_ip] outPort = in_port opcode = 2 # arp reply packet self.send_arp(datapath, opcode, srcMac, srcIp, dstMac, dstIp, outPort) else: if arp_packet.opcode == 1: # send arp reply (GATEWAY) dstIp = arp_src_ip srcIp = arp_dst_ip dstMac = src srcMac = self.port_to_mac[dpid_src][in_port] outPort = in_port opcode = 2 # arp reply packet self.send_arp(datapath, opcode, srcMac, srcIp, dstMac, dstIp, outPort) # HANDLE IP PACKETS----------------------------------------------- ip4_pkt = pkt.get_protocol(ipv4.ipv4) if ip4_pkt: src_ip = ip4_pkt.src dst_ip = ip4_pkt.dst proto = str(ip4_pkt.proto) sport = "0" dport = "0" if proto == "6": tcp_pkt = pkt.get_protocol(tcp.tcp) sport = str(tcp_pkt.src_port) dport = str(tcp_pkt.dst_port) if proto == "17": udp_pkt = pkt.get_protocol(udp.udp) sport = str(udp_pkt.src_port) dport = str(udp_pkt.dst_port) self.logger.info("Packet from the switch: %s, source IP: %s, destination IP: %s, From the port: %s", dpid_src, src_ip, dst_ip, in_port) ######################################################################################################################## # PACKET CLASSIFICATION FUNCTION: it returns action: "allow" or "deny" # action_rule = self.linear_classification(src_ip, dst_ip, proto, sport, dport) action_rule = "allow" if action_rule == "allow": # IP LOOKUP FUNCTION: it is zero if it didn't find a solution destination_switch_IP = self.binary_trie_search(dst_ip) ######################################################################################################################## if destination_switch_IP != "0": datapath_dst = get_datapath(self,int(self.switch[destination_switch_IP][DPID])) dpid_dst = datapath_dst.id self.logger.info(" --- Destination present on switch: %s", dpid_dst) # Shortest path computation path = nx.shortest_path(self.net,dpid_src,dpid_dst) self.logger.info(" --- Shortest path: %s", path) if len(path) == 1: In_Port = self.mac_to_port[dpid_src][src] Out_Port = self.mac_to_port[dpid_dst][dst] actions_1 = [datapath.ofproto_parser.OFPActionOutput(Out_Port)] actions_2 = [datapath.ofproto_parser.OFPActionOutput(In_Port)] match_1 = parser.OFPMatch(in_port=In_Port, eth_dst=dst) self.add_flow(datapath, 1, match_1, actions_1) actions = [datapath.ofproto_parser.OFPActionOutput(Out_Port)] data = msg.data pkt = packet.Packet(data) eth = pkt.get_protocols(ethernet.ethernet)[0] # self.logger.info(" --- Changing destination mac to %s" % (eth.dst)) pkt.serialize() out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) datapath.send_msg(out) elif len(path) == 2: path_port = self.net[path[0]][path[1]]['port'] actions = [datapath.ofproto_parser.OFPActionOutput(path_port)] data = msg.data pkt = packet.Packet(data) eth = pkt.get_protocols(ethernet.ethernet)[0] eth.src = self.ip_to_mac[src_ip] eth.dst = self.ip_to_mac[dst_ip] # self.logger.info(" --- Changing destination mac to %s" % (eth.dst)) pkt.serialize() out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) datapath.send_msg(out) elif len(path) > 2: # Add flows in the middle of the network path for i in range(1, len(path)-1): In_Port = self.net[path[i]][path[i-1]]['port'] Out_Port = self.net[path[i]][path[i+1]]['port'] dp = get_datapath(self, path[i]) # self.logger.info("Matched OpenFlow Rule = switch: %s, from in port: %s, to out port: %s, source IP: %s, and destination IP: %s", path[i], In_Port, Out_Port, src_ip, dst_ip) actions_1 = [dp.ofproto_parser.OFPActionOutput(Out_Port)] match_1 = parser.OFPMatch(in_port=In_Port, eth_type = 0x0800, ipv4_src=src_ip, ipv4_dst=dst_ip) self.add_flow(dp, 1, match_1, actions_1) path_port = self.net[path[0]][path[1]]['port'] actions = [datapath.ofproto_parser.OFPActionOutput(path_port)] data = msg.data pkt = packet.Packet(data) eth = pkt.get_protocols(ethernet.ethernet)[0] # change the mac address of packet eth.src = self.ip_to_mac[src_ip] eth.dst = self.ip_to_mac[dst_ip] # self.logger.info(" --- Changing destination mac to %s" % (eth.dst)) pkt.serialize() out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) datapath.send_msg(out)
out_port = p[0][2] 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_src=src, eth_dst=dst) 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) @set_ev_cls(event.EventSwitchEnter) def get_topology_data(self, ev): global switches switch_list = get_switch(self.topology_api_app, None) switches=[switch.dp.id for switch in switch_list] self.datapath_list=[switch.dp for switch in switch_list] #print "self.datapath_list=", self.datapath_list print "switches=", switches links_list = get_link(self.topology_api_app, None) mylinks=[(link.src.dpid,link.dst.dpid,link.src.port_no,link.dst.port_no) for link in links_list] for s1,s2,port1,port2 in mylinks: adjacency[s1][s2]=port1 adjacency[s2][s1]=port2 #print s1,s2,port1,port2
def handler_switch_enter(self, ev): self.topo_shape.topo_raw_switches = copy.copy(get_switch(self, None)) self.topo_shape.topo_raw_links = copy.copy(get_link(self, None)) self.topo_shape.print_links("EventSwitchEnter") self.topo_shape.print_switches("EventSwitchEnter")
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch 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] src = eth.src dst = eth.dst dpid = datapath.id self.S = list(set(self.S + [s.dp.id for s in get_switch(self, None)])) self.L = list(set(self.L + [(l.src.dpid, l.dst.dpid, l.src.port_no) for l in get_link(self, None)])) if self.tr_send_time<time.time(): self.trac_send() if self.tr_start_time>0 and time.time()-self.tr_start_time>1: self.tr_result=False self.trac() if dpid in self.fe and len([0 for a in self.fe[dpid] if a[0]==in_port and a[1]==dst])>0: pkt_ipv4=pkt.get_protocol(ipv4.ipv4) if pkt_ipv4 and pkt_ipv4.src=='10.7.10.7': self.tr_result=True self.trac() return 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) if eth.ethertype == ether_types.ETH_TYPE_LLDP: return if src[:2] != '00' and dst[:2] != '00': return self.mac_to_port.setdefault(dpid, {}) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port 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: self.add_flow_path(dpid, src, dst) 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) 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)
def event_switch_enter_handler(self, ev): self.switch = [s.dp.id for s in get_switch(self, None)] self.link = [(l.src.dpid, l.dst.dpid, {'port': l.src.port_no}) for l in get_link(self, None)]
def topology(self): #TODO add the topology collecting periodically self.edgenum = 0 start = time.time() print start self.switches = get_switch(self) self.links = get_link(self) self.topo_col_num = self.topo_col_num + 1 end = time.time() print end print 'topology collecting time:' print end - start self.topo_col_period = self.topo_col_period + end - start #n=len(self.switches) #m=len(self.links) ## self.startnum=0 ## self.dpids_to_nums={} ## self.nums_to_dpids={} print 'dpids nums:' for switch in self.switches: #TODO this may has error if self.dpids_to_nums.get(switch.dp.id) == None: self.nums_to_dpids[self.startnum] = switch.dp.id self.dpids_to_nums[switch.dp.id] = self.startnum print str(switch.dp.id) + ' ' + str(self.startnum) self.startnum = self.startnum + 1 print self.dpids_to_nums self.n = self.startnum print 'edges:' self.linkgraph = [] for i in xrange(self.switch_num): self.linkgraph.append([]) for j in xrange(self.switch_num): self.linkgraph[i].append(0) for link in self.links: self.edgenum = self.edgenum + 1 srcnum = self.dpids_to_nums[link.src.dpid] dstnum = self.dpids_to_nums[link.dst.dpid] self.linkgraph[srcnum][dstnum] = 1 if self.graph[srcnum][dstnum] == 0 and self.graph[dstnum][ srcnum] == 0: print str(srcnum) + ' ' + str(dstnum) self.dpid_to_port[(link.src.dpid, link.dst.dpid)] = (link.src.port_no, link.dst.port_no) self.dpid_to_port[(link.dst.dpid, link.src.dpid)] = (link.dst.port_no, link.src.port_no) #print>>devicegraph, str(srcnum)+' '+str(dstnum) self.graph[srcnum][dstnum] = 1 self.graph[dstnum][srcnum] = 1 self.undirected[srcnum][dstnum] = 1 self.m = self.m + 1 self.G = {} for i in xrange(self.switch_num): self.G[i] = {} for j in xrange(self.switch_num): if self.linkgraph[i][j] == 1 and self.linkgraph[j][ i] == 1: #TODO if only one way is ok then regard it as not ok self.G[i][j] = 1 print self.G print self.linkgraph print self.graph print self.undirected
def get_links(self): return list(get_link(self, None).keys())
def handler_switch_enter(self, ev): for link in copy.copy(get_link(self)): self.link_repository.register_link(link.src.dpid, link.src.port_no, link.dst.dpid, link.dst.port_no)
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)
def getLinkPort(self, srcDpid, dstDpid): links = get_link(self) for link in links: if link.src.dpid == srcDpid and link.dst.dpid == dstDpid: return link.src.port_no
def getLinksByDatapathID(self, dpid): """ Get datapath links by object ID """ #dp = self.getDatapathByID(dpid) #link = get_link(self, dp.id) link = get_link(self, dpid) return link
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'] 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_src = datapath.id # TOPOLOGY DISCOVERY------------------------------------------ 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) # print links # MAC LEARNING------------------------------------------------- self.mac_to_port.setdefault(dpid_src, {}) self.mac_to_port.setdefault(src, {}) self.port_to_mac.setdefault(dpid_src, {}) self.mac_to_port[dpid_src][src] = in_port self.mac_to_dpid[src] = dpid_src self.port_to_mac[dpid_src][in_port] = src self.logger.info("Packet in the controller from switch: %s", dpid_src) #print self.mac_to_port # HANDLE ARP PACKETS-------------------------------------------- if eth.ethertype == ether_types.ETH_TYPE_ARP: arp_packet = pkt.get_protocol(arp.arp) arp_dst_ip = arp_packet.dst_ip arp_src_ip = arp_packet.src_ip # self.logger.info("ARP packet from switch: %s source IP: %s destination IP: %s from port: %s", dpid_src, arp_src_ip, arp_dst_ip, in_port) # self.logger.info("ARP packet from switch: %s source MAC: %s destination MAC:%s from port: %s", dpid_src, src, dst, in_port) if arp_dst_ip in self.ip_to_mac: if arp_packet.opcode == 1: # send arp reply (SAME SUBNET) dstIp = arp_src_ip srcIp = arp_dst_ip dstMac = src srcMac = self.ip_to_mac[arp_dst_ip] outPort = in_port opcode = 2 # arp reply packet self.send_arp(datapath, opcode, srcMac, srcIp, dstMac, dstIp, outPort) else: if arp_packet.opcode == 1: # send arp reply (GATEWAY) dstIp = arp_src_ip srcIp = arp_dst_ip dstMac = src srcMac = self.port_to_mac[dpid_src][in_port] outPort = in_port opcode = 2 # arp reply packet self.send_arp(datapath, opcode, srcMac, srcIp, dstMac, dstIp, outPort) # HANDLE IP PACKETS----------------------------------------------- ip4_pkt = pkt.get_protocol(ipv4.ipv4) if ip4_pkt: src_ip = ip4_pkt.src dst_ip = ip4_pkt.dst proto = str(ip4_pkt.proto) sport = "0" dport = "0" if proto == "6": tcp_pkt = pkt.get_protocol(tcp.tcp) sport = str(tcp_pkt.src_port) dport = str(tcp_pkt.dst_port) if proto == "17": udp_pkt = pkt.get_protocol(udp.udp) sport = str(udp_pkt.src_port) dport = str(udp_pkt.dst_port) self.logger.info("Packet from the switch: %s, source IP: %s, destination IP: %s, From the port: %s", dpid_src, src_ip, dst_ip, in_port) ############################################################################################################################# # PACKET CLASSIFICATION FUNCTION: it returns action: "allow" or "deny" #here we call our tree and function which were defined below of script #class TREE and NODE are out of Class SIMPLEswitch #if here put code of call , the program will be called iteratively action_rule = self.linear_classification(src_ip, dst_ip, proto, sport, dport) #action_rule = "allow" #keep in mind that u need follow the order of calling the function based on your f****n logic and script ############################################## #last issue 30.03.20 how obtain all rule from finding_prefix ############################################## here handle F1 field source ip ################################ #################################################################################################### print "proto of pkt", proto print "sport of pkt", sport print "dport of pkt", dport binn_scr_ip=fromIPtoBinary(src_ip) #here convert all set of SRC_ip into binary version and append them in nod[] vector nod=[] for rule in self.classify: k=fromIPtoBinary_1(self.classify[rule][SRC_IP]) nod.append(k) #here call Tree() which wrote below, in creation tree we put all brahches in list and after handle them in order to create tree f1=Tree() i=0 while i<=len(nod[1]): k=0 tupl=[] while k<len(nod): tupl.append(nod[k][:i]) k+=1 #this checks similar branches and delete the duplicates tupl=list(dict.fromkeys(tupl)) for ke in tupl: #here we assign nodes f1.add_node(str(ke)) i+=1 # here is important part for Set-prunning tree algoritm , we check if node is ancestor of another nodes and assign ancestor's rules to their children for rule in self.classify: for i in self.classify: if self.classify[i][SRC_IP] in self.classify[rule][SRC_IP]: #this is row to assign rule in Tree f1.add_rule(fromIPtoBinary_rule(self.classify[rule][SRC_IP]),0,i,None) #this is commented PrintTree function , just to check the tree decommnet it and run #f1.print_tree(f1.root) #Here we search based on binary version of src_ip best prefix match in the Tree ff=f1.finding_prefix(src_ip,f1.root,0) #this is additional func just to clean duplicates ff=list(dict.fromkeys(ff)) #here we see best prefix match print "\n\n\nBest prefix match for SRC_IP:",ff ################################## Destination of IP address handling ####################################### #Here we create vector nod2[] and append into this all binary version dst_ip nod2=[] for rule in self.classify: k=fromIPtoBinary_1(self.classify[rule][DST_IP]) nod2.append(k) f2=Tree() i=0 while i<=len(nod2[1]): k=0 tupl=[] while k<len(nod2): tupl.append(nod2[k][:i]) k+=1 #this checks similar branches and delete the duplicates tupl=list(dict.fromkeys(tupl)) for ke in tupl: #here we assign nodes f2.add_node(str(ke)) i+=1 for rule in self.classify: for i in self.classify: if self.classify[i][DST_IP] in self.classify[rule][DST_IP]: #this is row to assign rule in Tree f2.add_rule(fromIPtoBinary_rule(self.classify[rule][DST_IP]),0,i,None) ff2=f2.finding_prefix(dst_ip,f2.root,0) #this is additional func just to clean duplicates ff2=list(dict.fromkeys(ff2)) #here we see best prefix match print "\n\n\nBest prefix match for DST_IP:",ff2 #############################################handling protocol of packet filed 3 ###################################################### #Here we conwert proto in binary bin_proto=str(bin(int(proto))[2:]) #Here we convert all proto in rules into binary versions and append them in vector prep[] prep=[] for i in self.classify: prt=str(bin(int(self.classify[i][PROTO]))[2:]) prep.append(prt) #here we "fix" binary version:we align them and made them similiar size it is neccesary to create Tree chunk3=[] for i in prep: chunk3.append(i.ljust(len( max(prep,key=len)),'0')) #Here we create third tree for Proto f3=Tree() i=0 while i<=len(chunk3[1]): k=0 tupl=[] while k<len(chunk3): tupl.append(chunk3[k][:i]) k+=1 tupl=list(dict.fromkeys(tupl)) for ke in tupl: f3.add_node(str(ke)) i+=1 for rule in sorted(self.classify): f3.add_rule(str(bin(int(self.classify[rule][PROTO]))[2:]),0,rule,None) #Here we also have print tree func for proto , it is neccessary to check the correctness of tree #f3.print_tree(f3.root) #Here we find best prefix math for proto in Tree ff3=f3.finding_prefix_one(bin_proto,f3.root,0) print "Best prefix match for PROTO:", ff3 ################################## source port of packet handling filed 4 ##################################################### #here we handle source port of packet , the implementation a little bit different then for SRC,DST #Here we append all source port of rule in all_sport[] vector, we need it for further computation and creation the tree all_sport=[] for i in self.classify: all_sport.append(self.classify[i][SPORT]) #here we clean duplicates all_sport=list(dict.fromkeys(all_sport)) #here we sort and append into data[ ] only non star=="*" source port , bcz "star" source port goes to root of the Tree data=[] for i in all_sport: if i!="*": k=str(bin(int(i))[2:]) data.append(k) #Here also we align all branches, we alligned them with zeros, and it doesnt impact to correctness of Tree same_sport=[] for i in data: same_sport.append(i.ljust(len( max(data,key=len)),'0')) #Here we create tree for source port and assign nodes f4=Tree() i=0 while i<=len(same_sport[1]): k=0 tupl=[] while k<len(same_sport): tupl.append(same_sport[k][:i]) k+=1 tupl=list(dict.fromkeys(tupl)) for ke in tupl: f4.add_node(str(ke)) i+=1 #Here we assign rule regarding of set-prunning algorithm for rule in self.classify: for i in self.classify: if fromIPtoBinary_port(self.classify[i][SPORT]) in fromIPtoBinary_port(self.classify[rule][SPORT]): #assign the rule in the Tree f4.add_rule(fromIPtoBinary_port(self.classify[rule][SPORT]),0,i,None) #Also here we have print tree check (commented), we need print tree func to check the correctness tree at each field #f4.print_tree(f4.root) #we convert source ip in binary and use finding prefix function to find best prefix match bin_sport=fromIPtoBinary_port(sport) fsport=f4.finding_prefix_one(bin_sport,f4.root,0) #here we clean duplicates, it occurs bcz in add_rule function we use iteration and append result into vector iteratively fsport=list(dict.fromkeys(fsport)) print "Best prefix match S_PORT", fsport ########################################## destination port of packet :handling field 5############# handling destination port################################# #handlig for dest port the same as for source port all_dport=[] bin_dport=fromIPtoBinary_port(dport) for i in self.classify: all_dport.append(self.classify[i][DPORT]) all_dport=list(dict.fromkeys(all_dport)) data=[] for i in all_dport: if i!="*": k=str(bin(int(i))[2:]) data.append(k) same_dport=[] for i in data: same_dport.append(i.ljust(len( max(data,key=len)),'0')) f5=Tree() i=0 while i<=len(same_dport[1]): k=0 tupl=[] while k<len(same_dport): tupl.append(same_dport[k][:i]) k+=1 tupl=list(dict.fromkeys(tupl)) for ke in tupl: f5.add_node(str(ke)) # i+=1 for rule in self.classify: for i in self.classify: if fromIPtoBinary_port(self.classify[i][DPORT]) in fromIPtoBinary_port(self.classify[rule][DPORT]): f5.add_rule(fromIPtoBinary_port(self.classify[rule][DPORT]),0,i,None) #f4.print_tree(f4.root) fdport=f5.finding_prefix_one(bin_dport,f5.root,0) fdport=list(dict.fromkeys(fdport)) print "Best prefix match D_PORT:", fdport ############################################################################################################################### #Here we call set_prunning function in order to analyze prefixes and obtain result action and it's rule #here we call Set-prunning function action_rule=self.set_prunning_tree(ff,ff2,ff3,fsport,fdport) action_rule="deny" if action_rule == "allow": # IP LOOKUP FUNCTION: it is zero if it didn't find a solution destination_switch_IP = self.linear_search(dst_ip) if destination_switch_IP != "0": datapath_dst = get_datapath(self,int(self.switch[destination_switch_IP][DPID])) dpid_dst = datapath_dst.id self.logger.info(" --- Destination present on switch: %s", dpid_dst) # Shortest path computation path = nx.shortest_path(self.net,dpid_src,dpid_dst) self.logger.info(" --- Shortest path: %s", path) if len(path) == 1: In_Port = self.mac_to_port[dpid_src][src] Out_Port = self.mac_to_port[dpid_dst][dst] actions_1 = [datapath.ofproto_parser.OFPActionOutput(Out_Port)] actions_2 = [datapath.ofproto_parser.OFPActionOutput(In_Port)] match_1 = parser.OFPMatch(in_port=In_Port, eth_dst=dst) self.add_flow(datapath, 1, match_1, actions_1) actions = [datapath.ofproto_parser.OFPActionOutput(Out_Port)] data = msg.data pkt = packet.Packet(data) eth = pkt.get_protocols(ethernet.ethernet)[0] # self.logger.info(" --- Changing destination mac to %s" % (eth.dst)) pkt.serialize() out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) datapath.send_msg(out) elif len(path) == 2: path_port = self.net[path[0]][path[1]]['port'] actions = [datapath.ofproto_parser.OFPActionOutput(path_port)] data = msg.data pkt = packet.Packet(data) eth = pkt.get_protocols(ethernet.ethernet)[0] eth.src = self.ip_to_mac[src_ip] eth.dst = self.ip_to_mac[dst_ip] # self.logger.info(" --- Changing destination mac to %s" % (eth.dst)) pkt.serialize() out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) datapath.send_msg(out) elif len(path) > 2: # Add flows in the middle of the network path for i in range(1, len(path)-1): In_Port = self.net[path[i]][path[i-1]]['port'] Out_Port = self.net[path[i]][path[i+1]]['port'] dp = get_datapath(self, path[i]) # self.logger.info("Matched OpenFlow Rule = switch: %s, from in port: %s, to out port: %s, source IP: %s, and destination IP: %s", path[i], In_Port, Out_Port, src_ip, dst_ip) actions_1 = [dp.ofproto_parser.OFPActionOutput(Out_Port)] match_1 = parser.OFPMatch(in_port=In_Port, eth_type = 0x0800, ipv4_src=src_ip, ipv4_dst=dst_ip) self.add_flow(dp, 1, match_1, actions_1) path_port = self.net[path[0]][path[1]]['port'] actions = [datapath.ofproto_parser.OFPActionOutput(path_port)] data = msg.data pkt = packet.Packet(data) eth = pkt.get_protocols(ethernet.ethernet)[0] # change the mac address of packet eth.src = self.ip_to_mac[src_ip] eth.dst = self.ip_to_mac[dst_ip] # self.logger.info(" --- Changing destination mac to %s" % (eth.dst)) pkt.serialize() out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) datapath.send_msg(out)
def handler_switch_enter(self, ev): self.logger.info('switch entered') # The Function get_switch(self, None) outputs the list of switches. self.topo_raw_switches = copy.copy(get_switch(self, None)) # The Function get_link(self, None) outputs the list of links. self.topo_raw_links = copy.copy(get_link(self, None))
def _packet_in_handler(self, ev): """ Executes everytime a packet arrives on a controller """ # 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 self.logger.info( "Na controller dorazi paket. Predtym prisiel na Switch cislo %s, na port %s. Dst: %s, Src: %s", datapath.id, in_port, dst, src) t = pkt.get_protocol(ipv4.ipv4) if t: print 'zdrojova ip: ', t.src print 'dest ip: ', t.dst ht = pkt.get_protocol(tcp.tcp) mam = 0 found_path = 0 random_path = () # If TCP if ht: print 'zdrojovy port: ', ht.src_port print 'destination port: ', ht.dst_port mam = 1 options = ht.option # Parse TCP options if options and len(options) > 0: for opt in options: # Parse MPTCP options if opt.kind == 30: # Parse MPTCP subtype. 00 = MP_CAPABLE. 01 = MP_JOIN. 11 = MP_JOIN hexopt = binascii.hexlify(opt.value) subtype = hexopt[:2] # MP CAPABLE if subtype == "00": # MP CAPABLE SYN if ht.bits == 2: self.logger.info("MP_CAPABLE SYN") dpid = datapath.id if src not in self.net: self.net.add_node(src) self.net.add_edge(dpid, src, port=in_port) self.net.add_edge(src, dpid) # Send A->B traffic to controller match = parser.OFPMatch(eth_type=0x0800, ip_proto=6, ipv4_src=t.src, ipv4_dst=t.dst, tcp_src=ht.src_port, tcp_dst=ht.dst_port) actions = [ parser.OFPActionOutput( ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] self.add_flow(datapath, 3, match, actions) # Send B->A traffic to controller match = parser.OFPMatch(eth_type=0x0800, ip_proto=6, ipv4_src=t.dst, ipv4_dst=t.src, tcp_src=ht.dst_port, tcp_dst=ht.src_port) actions = [ parser.OFPActionOutput( ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] self.add_flow(datapath, 3, match, actions) # Sender's key. keya = hexopt[4:] # Sender's token is a SHA1 truncated hash of the key. tokena = int( hashlib.sha1(binascii.unhexlify( hexopt[4:])).hexdigest()[:8], 16) # Store IPs, ports, sender's key and sender's token. values = { 'tsrc': t.src, 'tdst': t.dst, 'keya': keya, 'tokena': tokena, 'htsrc_port': ht.src_port, 'htdst_port': ht.dst_port, 'src': src, 'dst': dst } query = "replace INTO mptcp.conn (ip_src,ip_dst,keya,tokena,tcp_src,tcp_dst,src,dst) values('{tsrc}','{tdst}','{keya}',{tokena},{htsrc_port},{htdst_port},'{src}','{dst}');" self.executeInsert(query.format(**values)) # MP_CAPABLE SYN-ACK elif ht.bits == 18: self.logger.info("MP_CAPABLE SYN-ACK") dpid = datapath.id if src not in self.net: self.net.add_node(src) self.net.add_edge(dpid, src, port=in_port) self.net.add_edge(src, dpid) # Change out_port so traffic does not go to controller anymore match = parser.OFPMatch(eth_type=0x0800, ip_proto=6, ipv4_src=t.src, ipv4_dst=t.dst, tcp_src=ht.src_port, tcp_dst=ht.dst_port) # All shortest paths between srcmac and dst mac paths = list( nx.all_shortest_paths(self.net, src, dst)) print("Found path for SYN-ACK. %s to %s Its:", src, dst) # Random index in list of paths path_index = randrange(0, len(paths)) print( "Volim random index z 0 az do %d. Zvolil som: %d'", len(paths), path_index) # Select random path path = paths[path_index] print(path) macs = dst + '-' + src self.connpaths[macs] = path_index print( "Zlozil som kluc do connpaths: %s. Pridelil som path_index %d. Obsah conppaths:", macs, path_index) print(self.connpaths) next = path[path.index(dpid) + 1] out_port = self.net[dpid][next]['port'] print("Out_port: %d", out_port) actions = [parser.OFPActionOutput(out_port)] self.add_flow(datapath, 3, match, actions) # Receiver's key. keyb = hexopt[4:] # Receiver's token is a SHA1 truncated hash of the key. tokenb = int( hashlib.sha1(binascii.unhexlify( hexopt[4:])).hexdigest()[:8], 16) # Store receiver's key and receiver's token to the appropriate connection. values = { 'tsrc': t.src, 'tdst': t.dst, 'htsrc_port': ht.src_port, 'htdst_port': ht.dst_port, 'keyb': keyb, 'tokenb': tokenb } query = "UPDATE mptcp.conn SET keyb='{keyb}',tokenb={tokenb} WHERE ip_src='{tdst}' AND ip_dst='{tsrc}' AND tcp_src={htdst_port} AND tcp_dst={htsrc_port};" self.executeInsert(query.format(**values)) # MP_CAPABLE ACK elif ht.bits == 16: self.logger.info("MP_CAPABLE ACK") # Change out_port so traffic does not go to controller anymore dpid = datapath.id match = parser.OFPMatch(eth_type=0x0800, ip_proto=6, ipv4_src=t.src, ipv4_dst=t.dst, tcp_src=ht.src_port, tcp_dst=ht.dst_port) # Construct key in connpaths macs = src + '-' + dst print('Som v ACK. macs: %s', macs) # Get all shortest paths paths = list( nx.all_shortest_paths(self.net, src, dst)) path = paths[self.connpaths[macs]] print('Random index v ACK: ', self.connpaths[macs]) print("Found path for ACK. %s to %s Its:", src, dst) print(path) next = path[path.index(dpid) + 1] out_port = self.net[dpid][next]['port'] print("Out_port: %d", out_port) actions = [parser.OFPActionOutput(out_port)] self.add_flow(datapath, 3, match, actions) command = 'ovs-ofctl -OOpenFlow13 del-flows s1 "eth_dst=' + dst + ',tcp,tcp_flags=0x010"' os.system(command) # MP_JOIN elif subtype == "10" or subtype == "11": # MP_JOIN SYN if ht.bits == 2: self.logger.info("MP_JOIN SYN") dpid = datapath.id if src not in self.net: self.net.add_node(src) self.net.add_edge(dpid, src, port=in_port) self.net.add_edge(src, dpid) # Send A->B traffic to controller match = parser.OFPMatch(eth_type=0x0800, ip_proto=6, ipv4_src=t.src, ipv4_dst=t.dst, tcp_src=ht.src_port, tcp_dst=ht.dst_port) actions = [ parser.OFPActionOutput( ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] self.add_flow(datapath, 3, match, actions) # Send B->A traffic to controller match = parser.OFPMatch(eth_type=0x0800, ip_proto=6, ipv4_src=t.dst, ipv4_dst=t.src, tcp_src=ht.dst_port, tcp_dst=ht.src_port) actions = [ parser.OFPActionOutput( ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] self.add_flow(datapath, 3, match, actions) # Receiver's token. From the MPTCP connection. tokenb = int(hexopt[4:][:8], 16) # Sender's nonce. noncea = hexopt[12:] # Store IPs, ports, sender's nonce into subflow table. values = { 'tsrc': t.src, 'tdst': t.dst, 'tokenb': tokenb, 'noncea': noncea, 'htsrc_port': ht.src_port, 'htdst_port': ht.dst_port } query = "replace INTO mptcp.subflow (ip_src,ip_dst,tokenb,noncea,tcp_src,tcp_dst) values('{tsrc}','{tdst}',{tokenb},'{noncea}',{htsrc_port},{htdst_port});" self.executeInsert(query.format(**values)) # MP_JOIN SYN-ACK elif ht.bits == 18: self.logger.info("MP_JOIN SYN-ACK.") # Change out_port so traffic does not go to controller anymore dpid = datapath.id match = parser.OFPMatch(eth_type=0x0800, ip_proto=6, ipv4_src=t.src, ipv4_dst=t.dst, tcp_src=ht.src_port, tcp_dst=ht.dst_port) if src not in self.net: self.net.add_node(src) self.net.add_edge(dpid, src, port=in_port) self.net.add_edge(src, dpid) paths = list( nx.all_shortest_paths(self.net, src, dst)) print("Found path for SYN-ACK. %s to %s Its:", src, dst) # Random index in list of paths path_index = randrange(0, len(paths)) print( "JOIN volim random index z 0 az do %d. Zvolil som: %d'", len(paths), path_index) # Select random path path = paths[path_index] print(path) macs = dst + '-' + src self.connpaths[macs] = path_index print( "Zlozil som kluc do connpaths: %s. Pridelil som path_index %d. Obsah conppaths:", macs, path_index) print(self.connpaths) next = path[path.index(dpid) + 1] out_port = self.net[dpid][next]['port'] print("Out_port: %d", out_port) actions = [parser.OFPActionOutput(out_port)] self.add_flow(datapath, 3, match, actions) # Receiver's truncated HASH. trunhash = int(hexopt[4:][:16], 16) # Receiver's nonce. nonceb = hexopt[20:] # Store truncated HASH and receiver's nonce into appropriate subflow. values = { 'tsrc': t.src, 'tdst': t.dst, 'htsrc_port': ht.src_port, 'htdst_port': ht.dst_port, 'trunhash': trunhash, 'nonceb': nonceb } query = "UPDATE mptcp.subflow SET trunhash={trunhash},nonceb='{nonceb}' WHERE ip_src='{tdst}' AND ip_dst='{tsrc}' AND tcp_src={htdst_port} AND tcp_dst={htsrc_port};" self.executeInsert(query.format(**values)) # MP_JOIN ACK elif ht.bits == 16: self.logger.info("MP_JOIN ACK.") # Change out_port so traffic does not go to controller anymore dpid = datapath.id match = parser.OFPMatch(eth_type=0x0800, ip_proto=6, ipv4_src=t.src, ipv4_dst=t.dst, tcp_src=ht.src_port, tcp_dst=ht.dst_port) # Construct key in connpaths macs = src + '-' + dst print('Som v JOIN ACK. macs: %s', macs) # Get all paths paths = list( nx.all_shortest_paths(self.net, src, dst)) path = paths[self.connpaths[macs]] print('Random index v ACK: ', self.connpaths[macs]) print("Found path for ACK. %s to %s Its:", src, dst) print(path) next = path[path.index(dpid) + 1] out_port = self.net[dpid][next]['port'] print("Out_port: %d", out_port) actions = [parser.OFPActionOutput(out_port)] self.add_flow(datapath, 3, match, actions) # Sender's HASH. hmachash = hexopt[4:] # Store sender's HASH to appropriate subflow. values = { 'tsrc': t.src, 'tdst': t.dst, 'htsrc_port': ht.src_port, 'htdst_port': ht.dst_port, 'hmachash': hmachash } query = "UPDATE mptcp.subflow SET hash='{hmachash}' WHERE ip_src='{tsrc}' AND ip_dst='{tdst}' AND tcp_src={htsrc_port} AND tcp_dst={htdst_port};" self.executeInsert(query.format(**values)) # Select keys from appropriate connection based on receiver's token. values = { 'tsrc': t.src, 'tdst': t.dst, 'htsrc_port': ht.src_port, 'htdst_port': ht.dst_port } query = "SELECT keya,keyb from conn where tokenb in (SELECT tokenb from subflow where ip_src='{tsrc}' and ip_dst='{tdst}' and tcp_src={htsrc_port} and tcp_dst={htdst_port});" keys = self.executeSelect( query.format(**values)) # Select nonces for current subflow. values = { 'tsrc': t.src, 'tdst': t.dst, 'htsrc_port': ht.src_port, 'htdst_port': ht.dst_port } query = "SELECT noncea,nonceb from subflow where ip_src='{tsrc}' AND ip_dst='{tdst}' AND tcp_src={htsrc_port} AND tcp_dst={htdst_port};" nonces = self.executeSelect( query.format(**values)) # Key for generating HMAC is a concatenation of two keys. Message is a concatenation of two nonces. keyhmac = binascii.unhexlify(keys[0] + keys[1]) message = binascii.unhexlify(nonces[0] + nonces[1]) # Generate hash. vysledok = hmac.new(keyhmac, message, hashlib.sha1).hexdigest() print(vysledok) # Compare generated HASH to the one from MP_JOIN ACK. if vysledok == hmachash: # Get connection ID based on tokens. values = { 'tsrc': t.src, 'tdst': t.dst, 'htsrc_port': ht.src_port, 'htdst_port': ht.dst_port } query = "SELECT id from conn where tokenb in (SELECT tokenb from subflow where ip_src='{tsrc}' and ip_dst='{tdst}' and tcp_src={htsrc_port} and tcp_dst={htdst_port});" ids = self.executeSelect( query.format(**values))[0] # Insert connection ID to a current subflow. values = { 'tsrc': t.src, 'tdst': t.dst, 'htsrc_port': ht.src_port, 'htdst_port': ht.dst_port, 'id': ids } query = "update subflow set connid = {id} where ip_src='{tsrc}' and ip_dst='{tdst}' and tcp_src={htsrc_port} and tcp_dst={htdst_port};" self.executeInsert(query.format(**values)) query = "select src,dst from conn join subflow on subflow.connid=conn.id where conn.id=(select connid from subflow where ip_src='{tsrc}' and ip_dst='{tdst}' and tcp_src={htsrc_port} and tcp_dst={htdst_port}) group by src;" result = self.executeSelect( query.format(**values)) srcmac = result[0] dstmac = result[1] print('srcmac = %s', srcmac) print('dstmac = %s', dstmac) # paths = list(nx.all_shortest_paths(self.net,srcmac,dstmac)) # print ("Available paths: ") # for p in paths: # print p # print ("Random_path: ") # random_path = random.choice(paths) # print (random_path) # found_path = 1 # print ("Found_path: %d",found_path) # Learn MAC addresses to avoid FLOOD. dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.mac_to_port[dpid][src] = in_port # Shortest path forwarding # for f in msg.match.fields: # if f.header == ofproto_v1_3.OXM_OF_IN_PORT: # in_port = f.value # # if src not in self.net: # self.net.add_node(src) # self.net.add_edge(dpid,src,port=in_port) # self.net.add_edge(src,dpid) # if dst in self.net: # print("Som v rozhodovani.") # if found_path == 1: # print ("Assingin random path.") # path = random_path # next = path[path.index(dpid) + 1] # out_port = self.net[dpid][next]['port'] # else: # print ("Assining not random path.") # path = nx.shortest_path(self.net,src,dst) # next = path[path.index(dpid) + 1] # out_port = self.net[dpid][next]['port'] # else: # out_port = ofproto.OFPP_FLOOD 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 flow to avoid FLOOD next time. if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=dst) 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) """ Get topology data. Links and switches. """ 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] print("Linky: ", 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("Linky znova: ", links) self.net.add_edges_from(links) print("Linky z programu: ", self.net.edges()) print("Nodes z programu: ", self.net.nodes())
def handler_link_add(self, ev): self.logger.info("Link detected") self.topo_blueprint.topo_raw_links = get_link(self, None)
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 _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 src = eth.src dst = eth.dst if str(dst) in ("00:00:00:00:00:01", "00:00:00:00:00:02", "00:00:00:00:00:03", "00:00:00:00:00:04", "00:00:00:00:00:05", "00:00:00:00:00:06"): msg = ev.msg dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.logger.info("packet from Source: %s to Destination: %s", src, dst) if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] 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} self.g.add_nodes_from(switches) links = [(link.src.dpid, link.dst.dpid, { 'port': link.src.port_no }) for link in links_list] self.g.add_edges_from(links) links = [(link.dst.dpid, link.src.dpid, { 'port': link.dst.port_no }) for link in links_list] topo = { '1': { '3': 10, '2': 10, '5': 15 }, '2': { '1': 10, '3': 15, '4': 15 }, '3': { '1': 10, '2': 15, '4': 5 }, '4': { '2': 15, '3': 5, '6': 10 }, '5': { '1': 15, '6': 15 }, '6': { '4': 10, '5': 15 } } dst_dpid = dpid_hostLookup(self, dst) path3 = [] src = str(src) dst = str(dst) dijkstra(topo, str(dpid), str(dst_dpid)) global path2 path3 = list(map(int, path2)) path3.reverse() if not self.g.has_node(eth.src): self.g.add_node(eth.src) self.g.add_edge(eth.src, datapath.id) self.g.add_edge(datapath.id, eth.src, port=in_port) if not self.g.has_node(eth.dst): self.g.add_node(eth.dst) self.g.add_edge(eth.dst, datapath.id) self.g.add_edge(datapath.id, eth.dst, port=in_port) if (path3 != []): if self.g.has_node(eth.dst): next_match = parser.OFPMatch(eth_dst=eth.dst) back_match = parser.OFPMatch(eth_dst=eth.src) for on_path_switch in range(1, len(path3) - 1): now_switch = path3[on_path_switch] next_switch = path3[on_path_switch + 1] back_switch = path3[on_path_switch - 1] next_port = link_port[(now_switch, next_switch)] back_port = link_port[(now_switch, back_switch)] new_dp = get_datapath(self, next_switch) action = parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, [parser.OFPActionOutput(next_port)]) inst = [action] actions = [parser.OFPActionOutput(next_port)] self.add_flow(datapath=new_dp, priority=1, actions=actions, match=next_match, buffer_id=0) action = parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, [parser.OFPActionOutput(back_port)]) inst = [action] actions = [parser.OFPActionOutput(back_port)] new_dp = get_datapath(self, back_switch) self.add_flow(datapath=new_dp, match=back_match, priority=1, actions=actions, buffer_id=0) out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions) datapath.send_msg(out) else: return else: if out_port != ofproto.OFPP_FLOOD: self.add_flow(datapath, msg.in_port, dst, actions) out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions) datapath.send_msg(out)
def push_flow(self, req, source_dpid_int, destn_dpid_int, mac, **_kwargs): path = self.shortest_route(source_dpid_int, destn_dpid_int) source_dpid = self.append(source_dpid_int) destn_dpid = self.append(destn_dpid_int) source_dpid1 = dpid_lib.str_to_dpid(source_dpid) destn_dpid1 = dpid_lib.str_to_dpid(destn_dpid) source_dp = self.dpset.get(source_dpid1) destn_dp = self.dpset.get(destn_dpid1) if source_dp is None: return Response(status=404) for node in range(len(path) - 1): tsrc_dpid = int(path[node].replace("dpid=", "")) tdst_dpid = int(path[node + 1].replace("dpid=", "")) tsrc_dpid = self.append(tsrc_dpid) tdst_dpid = self.append(tdst_dpid) tsrc_dpid = dpid_lib.str_to_dpid(tsrc_dpid) tdst_dpid = dpid_lib.str_to_dpid(tdst_dpid) tsrc_dp = self.dpset.get(tsrc_dpid) links = get_link(self.topology_api_app, tsrc_dpid) if links is None: return Response(status=404) for i in range(len(links)): links_dpid = dpid_lib.str_to_dpid( links[i].to_dict()["dst"]["dpid"]) if links_dpid == tdst_dpid: str_port = links[i].to_dict()["src"]["port_no"] break port = port_lib.str_to_port_no(str_port) actions = [tsrc_dp.ofproto_parser.OFPActionOutput(int(port))] # pushing flows ofproto = tsrc_dp.ofproto match = tsrc_dp.ofproto_parser.OFPMatch(dl_dst=haddr_to_bin(mac)) mod = tsrc_dp.ofproto_parser.OFPFlowMod( datapath=tsrc_dp, match=match, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=ofproto.OFP_DEFAULT_PRIORITY, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions) tsrc_dp.send_msg(mod) ofproto = destn_dp.ofproto if (destn_dpid1 == 0000000000000001): logging.debug("PORT") out_port = 1 logging.debug(out_port) logging.debug("PORT") if (destn_dpid1 == 0000000000000002): out_port = 3 if (destn_dpid1 == 0000000000000003): out_port = 2 actions1 = [destn_dp.ofproto_parser.OFPActionOutput(1)] match1 = destn_dp.ofproto_parser.OFPMatch(dl_dst=haddr_to_bin(mac)) mod1 = destn_dp.ofproto_parser.OFPFlowMod( datapath=destn_dp, match=match1, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=ofproto.OFP_DEFAULT_PRIORITY, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions1) destn_dp.send_msg(mod1) body = json.dumps([link.to_dict() for link in links]) return Response(content_type='application/json', body=body)
def _packet_in_handler(self, ev): pkt = packet.Packet(ev.msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] arp_pkt = pkt.get_protocol(arp.arp) ip4_pkt = pkt.get_protocol(ipv4.ipv4) if arp_pkt: pak = arp_pkt elif ip4_pkt: pak = ip4_pkt else: pak = eth self.logger.info(' _packet_in_handler: src_mac -> %s' % eth.src) self.logger.info(' _packet_in_handler: dst_mac -> %s' % eth.dst) self.logger.info(' _packet_in_handler: %s' % pak) self.logger.info(' ------') if eth.ethertype == ether_types.ETH_TYPE_LLDP or eth.ethertype == ether_types.ETH_TYPE_IPV6: # ignore lldp packet return dst = eth.src src = eth.dst msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] 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 print(src) print(dst) if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] 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} # g = nx.DiGraph() self.g.add_nodes_from(switches) links = [(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list] print(links) self.g.add_edges_from(links) links = [(link.dst.dpid,link.src.dpid,{'port':link.dst.port_no}) for link in links_list] self.g.add_edges_from(links) #print(links) #print(self.g) topo = {'1': {'3': 50, '4': 100}, '2': {'3': 100, '4': 50}, '3': {'1': 50, '2': 100, '13': 15, '14': 100}, '4': {'1': 100, '2': 50, '14': 5}, '5': {'7': 50, '8': 100}, '6': {'7': 100, '8': 50}, '7': {'5': 50, '6': 100, '13': 15, '14': 20, '15': 5}, '8': {'5': 100, '6': 50, '15': 10, '16': 15}, '9': {'11': 50, '12': 100}, '10': {'11': 100, '12': 50}, '11': {'9': 50, '10': 100, '14': 10}, '12': {'9': 100, '10': 50, '15': 15, '16': 10}, '13': {'3': 15, '7': 15}, '14': {'3': 10, '4': 5, '7': 20, '11': 10}, '15': {'7': 5, '8': 10, '12': 15}, '16': {'8': 15, '12': 10}} dst_dpid = dpid_hostLookup(self, dst) print("dpid",str(dpid)) print("dst",dst) # if(dst=='ff:ff:ff:ff:ff:ff'): # return() path3=[] src=str(src) dst=str(dst) print("dst dpid",str(dst_dpid)) if ((src == '00:00:00:00:00:01' and dst == '00:00:00:00:00:13') or (src == '00:00:00:00:00:01' and dst == '00:00:00:00:00:23') or ( src == '00:00:00:00:00:01' and dst == '00:00:00:00:00:33') or(src == '00:00:00:00:00:02' and dst == '00:00:00:00:00:12') or ( src == '00:00:00:00:00:02' and dst == '00:00:00:00:00:22') or (src == '00:00:00:00:00:02' and dst == '00:00:00:00:00:32') or (src == '00:00:00:00:00:03' and dst == '00:00:00:00:00:14') or (src == '00:00:00:00:00:03' and dst == '00:00:00:00:00:24') or ( src == '00:00:00:00:00:03' and dst == '00:00:00:00:00:34')): dijkstra(topo, str(dpid), str(dst_dpid)) global path2 path3= list(map(int, path2)) print(path3) path3.reverse() elif ((src == '00:00:00:00:00:01' and (dst == '00:00:00:00:00:11' or dst == '00:00:00:00:00:12' or dst == '00:00:00:00:00:14' or dst == '00:00:00:00:00:21' or dst == '00:00:00:00:00:22' or dst == '00:00:00:00:00:24' or dst == '00:00:00:00:00:31' or dst == '00:00:00:00:00:32' or dst == '00:00:00:00:00:34')) or (src == '00:00:00:00:00:02' and (dst == '00:00:00:00:00:11' or dst == '00:00:00:00:00:13' or dst == '00:00:00:00:00:14' or dst == '00:00:00:00:00:21' or dst == '00:00:00:00:00:23' or dst == '00:00:00:00:00:24' or dst == '00:00:00:00:00:31' or dst == '00:00:00:00:00:33' or dst == '00:00:00:00:00:34')) or (src == '00:00:00:00:00:03' and (dst == '00:00:00:00:00:11' or dst == '00:00:00:00:00:12' or dst == '00:00:00:00:00:13' or dst == '00:00:00:00:00:21' or dst == '00:00:00:00:00:22' or dst == '00:00:00:00:00:23' or dst == '00:00:00:00:00:31' or dst == '00:00:00:00:00:32' or dst == '00:00:00:00:00:33'))): dijkstra_longestpath(topo, str(dpid), str(dst_dpid)) path3 = list(map(int, path2)) print(path3) path3.reverse() if not self.g.has_node(eth.src): print("add %s in self.net" % eth.src) self.g.add_node(eth.src) self.g.add_edge(eth.src, datapath.id) self.g.add_edge(datapath.id, eth.src, {'port': in_port}) print(self.g.node) if not self.g.has_node(eth.dst): print("add %s in self.net" % eth.dst) self.g.add_node(eth.dst) self.g.add_edge(eth.dst, datapath.id) self.g.add_edge(datapath.id, eth.dst, {'port': in_port}) print(self.g.node) # path3=[13,3,1] print("before loop") if(path3!=[]): if self.g.has_node(eth.dst): next_match = parser.OFPMatch(eth_dst=eth.dst) back_match = parser.OFPMatch(eth_dst=eth.src) print(path3) for on_path_switch in range(1, len(path3) - 1): print("hi in loop") now_switch = path3[on_path_switch] next_switch = path3[on_path_switch + 1] back_switch = path3[on_path_switch - 1] next_port = link_port[(now_switch,next_switch)] back_port = link_port[(now_switch,back_switch)] print("next_port",next_port) print("back_port",back_port) new_dp=get_datapath(self, next_switch) action = parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, [parser.OFPActionOutput(next_port)]) inst = [action] self.add_flow(datapath=new_dp, match=next_match, inst=inst, table=0) action = parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, [parser.OFPActionOutput(back_port)]) inst = [action] actions = [parser.OFPActionOutput(next_port)] new_dp = get_datapath(self, back_switch) self.add_flow(datapath=new_dp, match=back_match, inst=inst,actions=action, table=0) print ("now switch:%s",now_switch) out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions) datapath.send_msg(out) print("final") else: return else: if out_port != ofproto.OFPP_FLOOD: self.add_flow(datapath, msg.in_port, dst, actions) out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions) datapath.send_msg(out)
def update_topology(self, ev): # clear graph and precomputed paths self.net.clear() self.labels = {} self.mac_to_port = {} # wait a moment for ryu's topology info to update sleep(0.05) # get switches and links from ryu.topology switch_list = get_switch(self.topology_api_app, None) switches = [switch.dp.id for switch in switch_list] 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] # remove all the flows in the switches for switch in switch_list: self.remove_flows(switch.dp) # add switches and links to graph self.net.add_nodes_from(switches) self.net.add_edges_from(links) #self.logger.info("switches: %s", str(switches)) #self.logger.info("links: %s", str(links)) # get link bandwidth info from file and add it to the graph bw_list = open('bandwidths.edgelist', 'rb') bw_graph = nx.read_edgelist(bw_list, nodetype=int, data=(('bw', float),) ) bw_list.close() #self.logger.info("bw_graph.edges(): %s", str(bw_graph.edges())) for edge in bw_graph.edges(): # .edges() only returns ends, not data #self.logger.info("edge = %s", str(edge)) # if the edge is not in the edgelist of known/expected edges or # the bw field for the edge is missing, use a default bandwidth link_bw = 1 if edge in self.net.edges(): #self.logger.info("edge %s in self.net.edges()", str(edge)) try: link_bw = bw_graph[edge[0]][edge[1]]['bw'] #self.logger.info("link_bw = %f", link_bw) except: #self.logger.info("no link_bw found") pass try: port01 = self.net[edge[0]][edge[1]]['port'] port10 = self.net[edge[1]][edge[0]]['port'] self.net.add_edge(edge[0],edge[1], {'port': port01, 'bw': link_bw}) self.net.add_edge(edge[1],edge[0], {'port': port10, 'bw': link_bw}) except KeyError: #self.logger.info("KeyError for edge %s", str(edge)) continue # calculate labels #self.logger.info("calculating labels") self.labels = compute_mpls_labels(self.net) # add label-swapping flows to the switches for switch in switch_list: switch_id = switch.dp.id ofproto = self.switch_ofprotos[switch_id] parser = self.switch_parsers[switch_id] for dst in self.labels[switch_id].keys(): for path in range(len(self.labels[switch_id][dst])): # create a match for the path using its label match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_MPLS, mpls_label=self.labels[switch_id][dst][path][3]) # determine actions the switch_id should take if switch_id == dst: # check if this is the ARP path or not if self.labels[switch_id][dst][path][3] < 1000: packet_ethertype = ether_types.ETH_TYPE_ARP else: packet_ethertype = ether_types.ETH_TYPE_IP # create an instruction to pop the MPLS header actions = [parser.OFPActionPopMpls(packet_ethertype)] # create an instruction to go to the next table table_instruction = parser.OFPInstructionGotoTable( self.mpls_dst_table) instructions = [parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions), table_instruction] else: next_hop = self.labels[switch_id][dst][path][2][1] next_hop_label = self.labels[switch_id][dst][path][4] out_port = self.net[switch_id][next_hop]['port'] actions = [parser.OFPActionSetField( mpls_label = next_hop_label), parser.OFPActionDecMplsTtl(), parser.OFPActionOutput(out_port) ] instructions = [parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions)] # now add the flow self.add_flow(switch.dp, 1200, match, instructions, self.routing_table) self.print_graph() self.print_labels() print("")
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): #TODO using two methods to do two things respectively ? #TODO using server MAC learning period T to separate the two methods ? ## end=time.time() ## if (end-start)*1000 < self.T: ## #TODO compute the route ## print (end-start)*1000 ## self.MACLearning(ev) ## else: ## print (end-start)*1000 ## #TODO learning server MAC ## self.Routing(ev) #TODO add the topology collecting periodically self.edgenum=0 start = time.time() print start self.switches = get_switch(self) self.links = get_link(self) self.topo_col_num = self.topo_col_num + 1 end = time.time() print end print 'topology collecting time:' print end-start self.topo_col_period = self.topo_col_period + end-start #n=len(self.switches) #m=len(self.links) ## self.startnum=0 ## self.dpids_to_nums={} ## self.nums_to_dpids={} print 'dpids nums:' for switch in self.switches:#TODO this may has error if self.dpids_to_nums.get(switch.dp.id)==None: self.nums_to_dpids[self.startnum] = switch.dp.id self.dpids_to_nums[switch.dp.id] = self.startnum print str(switch.dp.id)+' '+str(self.startnum) self.startnum = self.startnum + 1 print self.dpids_to_nums self.n=self.startnum print 'edges:' self.linkgraph=[] for i in xrange(self.switch_num): self.linkgraph.append([]) for j in xrange(self.switch_num): self.linkgraph[i].append(0) for link in self.links: self.edgenum=self.edgenum+1 srcnum = self.dpids_to_nums[link.src.dpid] dstnum = self.dpids_to_nums[link.dst.dpid] self.linkgraph[srcnum][dstnum]=1 if self.graph[srcnum][dstnum]==0 and self.graph[dstnum][srcnum]==0: print str(srcnum)+' '+str(dstnum) self.dpid_to_port[(link.src.dpid, link.dst.dpid)] = (link.src.port_no, link.dst.port_no) self.dpid_to_port[(link.dst.dpid, link.src.dpid)]=(link.dst.port_no, link.src.port_no) #print>>devicegraph, str(srcnum)+' '+str(dstnum) self.graph[srcnum][dstnum] = 1 self.graph[dstnum][srcnum] = 1 self.undirected[srcnum][dstnum] = 1 self.m=self.m+1 self.G={} for i in xrange(self.switch_num): self.G[i]={} for j in xrange(self.switch_num): if self.linkgraph[i][j]==1 and self.linkgraph[j][i]==1:#TODO if only one way is ok then regard it as not ok self.G[i][j]=1 print self.G flag=0 if self.n<4 or self.m<4 or self.topo_col_num<self.topo_col_num_max or self.topo_col_period<self.topo_col_period_max:#TODO test,but when the edge is error, then it will not be ok flag=1#TODO print 'topology ok' if self.servernum<2: self.MACLearning(ev) if 2==self.servernum: #and 0==flag: src=self.server1 dst=self.server2 self.short(ev, src, dst, self.G)#add the flow entries of FF:FF:FF:FF:FF:FF src=self.server2 dst=self.server1 self.short(ev, src, dst, self.G) elif 2==self.servernum or self.edgenum!=8: #and 0==flag: #it means that two servers' MAC have been added, then add the src=self.server1 dst=self.server2 self.short(ev, src, dst, self.G)#add the flow entries of FF:FF:FF:FF:FF:FF src=self.server2 dst=self.server1 self.short(ev, src, dst, self.G)
def get_topo(self, ev): links_list = get_link(self.topology_get, None) for link in links_list: self.net.add_edge(link.src.dpid, link.dst.dpid, port=link.src.port_no)
def AAR(self, h1, h2): count = 0 count_flow = 0 start_time = time.time() net = nx.DiGraph() print "----------------------------------" print "Failure link:(", h1, ",", h2, ")" links = copy.copy(get_link(self, None)) edges_list = [] # extra list item for constructing nx graph if len(links) > 0: for link in links: src = link.src dst = link.dst edges_list.append((src.dpid, dst.dpid, {'port': src.port_no})) net.add_edges_from(edges_list) for key in self.all_pair_shortest_path.keys(): path = self.all_pair_shortest_path[key][0] back_path = self.all_pair_shortest_path[key][1] anchor_nodes = self.all_pair_shortest_path[key][2] src, dst = key if src in [19, 21, 22, 23, 24] and dst in [9, 10, 11, 18, 17]: pass else: continue if h1 in path and h2 in path: count_flow = count_flow + 1 index = path.index(h1) index2 = path.index(h2) if index != index2 - 1 and index != index2 + 1: continue print "Original path:", path if index2 < index: index = index2 new_path = None while index != -1: if path[index] in anchor_nodes: count += 1 try: new_path = nx.shortest_path( net, path[index], path[-1]) for sw in path[:index]: if sw in new_path: continue break except: log = "do nothing" index = index - 1 old_path = path[:index] if new_path == None: try: count += 1 new_path = nx.shortest_path(net, path[0], path[-1]) old_path = [] except: print "no alternative path found" continue print "change to:", old_path, "+", new_path path = old_path path.extend(new_path) if path == back_path: print 'new path is already existed in backup path' else: # update monitoring list spath = set(path) ss = set(self.monitoring_list) if (spath & ss): pass else: self.monitoring_list.append(path[-1]) # update anchor nodes anchor_nodes = [] for sw in path: if len(list(set(nx.all_neighbors(net, sw)))) > 2: anchor_nodes.append(sw) self.all_pair_shortest_path[key][0] = path self.all_pair_shortest_path[key][2] = anchor_nodes # add new flow entry for anchor node datapath = self.dp_list[new_path[0]] out_port = self.net[new_path[0]][new_path[1]]['port'] ofp_parser = datapath.ofproto_parser actions = [ofp_parser.OFPActionOutput(out_port)] src, dst = key src = "10.0.0.%s" % (str(src)) dst = "10.0.0.%s" % (str(dst)) match = ofp_parser.OFPMatch(eth_type=self.eth_type, ipv4_dst=dst, ipv4_src=src) self.add_flow(datapath, 1000, match, actions, table=0) print "Compute time:", (time.time() - start_time) * 1000, "ms" print "Number of computation:", count print "Number of flow change:", count_flow print "-----------------------------------\n" print self.monitoring_list print "Total ", len(self.monitoring_list), " switches"
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) # add trace flow and update hosts' data self.trace_flow(None) return "DPI_INIT_OK"