mininet - get_all_link(self) outputting all possible LINKs for a topo -
i have topo 4 switches , 4 hosts. switches construct loop. goal learn topology of network when switches connected controller. problem function get_all_links()
returns of possible links or @ least doesn't make sense. call function when port_modify
event fired.
here code use construct topo:
<removed imports save space> class simple3pktswitch(topo): """simple topology example.""" def __init__(self): """create custom topo.""" # initialize topology topo.__init__(self) # add hosts , switches h1 = self.addhost('h1') h2 = self.addhost('h2') h3 = self.addhost('h3') h4 = self.addhost('h4') # adding switches p1 = self.addswitch('p1', dpid="0000000000000001") p2 = self.addswitch('p2', dpid="0000000000000002") p3 = self.addswitch('p3', dpid="0000000000000003") p4 = self.addswitch('p4', dpid="0000000000000004") # add links self.addlink(h1, p1) self.addlink(h2, p2) self.addlink(h3, p3) self.addlink(h4, p4) self.addlink(p2, p4) self.addlink(p1, p2) self.addlink(p3, p4) self.addlink(p1, p3) def run(): c = remotecontroller('c', '0.0.0.0', 6633) net = mininet(topo=simple3pktswitch(), controller=none, autosetmacs=true) net.addcontroller(c) net.start() # installstaticflows( net ) cli(net) net.stop() # if script run directly (sudo custom/optical.py): if __name__ == '__main__': setloglevel('info') run()
here code ryu:
from ryu.base import app_manager ryu.controller import ofp_event ryu.controller.handler import config_dispatcher, main_dispatcher, dead_dispatcher ryu.controller.handler import set_ev_cls ryu.ofproto import ofproto_v1_3 ryu.lib.packet import packet ryu.lib.packet import ethernet ryu.topology import event ryu.topology.api import get_all_switch, get_all_link ryu.lib import dpid dpid_lib ryu.controller import dpset import networkx nx = 1 down = 0 class simpleswitch13(app_manager.ryuapp): ofp_versions = [ofproto_v1_3.ofp_version] def __init__(self, *args, **kwargs): super(simpleswitch13, self).__init__(*args, **kwargs) # used learning switch functioning self.mac_to_port = {} # holds topology data , structure self.topo_shape = topostructure() """ function determines links , switches in topology """ def get_topology_data(self): # call get_switch() list of objects switch. self.topo_shape.topo_raw_switches = get_all_switch(self) # call get_link() list of objects link. self.topo_shape.topo_raw_links = get_all_link(self) self.topo_shape.print_links("get_topology_data") self.topo_shape.print_switches("get_topology_data") ################################################################################### """ eventofpportstatus: event class switch port status notification. bellow handles event. """ @set_ev_cls(dpset.eventportmodify, main_dispatcher) def port_modify_handler(self, ev): dp = ev.dp port_attr = ev.port dp_str = dpid_lib.dpid_to_str(dp.id) self.logger.info("\t ***switch dpid=%s" "\n \t port_no=%d hw_addr=%s name=%s config=0x%08x " "\n \t state=0x%08x curr=0x%08x advertised=0x%08x " "\n \t supported=0x%08x peer=0x%08x curr_speed=%d max_speed=%d" % (dp_str, port_attr.port_no, port_attr.hw_addr, port_attr.name, port_attr.config, port_attr.state, port_attr.curr, port_attr.advertised, port_attr.supported, port_attr.peer, port_attr.curr_speed, port_attr.max_speed)) if port_attr.state == 1: self.topo_shape.print_links("link down") out = self.topo_shape.link_with_src_port(port_attr.port_no, dp.id) print "out"+str(out) if out not none: print(self.topo_shape.find_shortest_path(out.src.dpid)) elif port_attr.state == 0: self.topo_shape.topo_raw_links = get_all_link(self) ### here ### print ("link count: "+str(len(self.topo_shape.topo_raw_links))) self.topo_shape.print_links("link up") #self.topo_shape.topo_raw_links = get_all_link(self) #self.topo_shape.print_links("link up") ################################################################################### """ class holds list of links , switches in topology , provides useful functions """ class topostructure(): def __init__(self, *args, **kwargs): self.topo_raw_switches = [] self.topo_raw_links = [] self.topo_links = [] self.net = nx.digraph() def print_links(self, func_str=none): # convert raw link list printed print(" \t"+str(func_str)+": current links:") l in self.topo_raw_links: print (" \t\t"+str(l)) def print_switches(self, func_str=none): print(" \t"+str(func_str)+": current switches:") s in self.topo_raw_switches: print (" \t\t"+str(s)) def switches_count(self): return len(self.topo_raw_switches) def convert_raw_links_to_list(self): # build list links [((srcnode,port), (dstnode, port))]. # list easier printing. self.lock.acquire() self.topo_links = [((link.src.dpid, link.src.port_no), (link.dst.dpid, link.dst.port_no)) link in self.topo_raw_links] self.lock.release() def convert_raw_switch_to_list(self): # build list switches ([switches]) self.lock.acquire() self.topo_switches = [(switch.dp.id, up) switch in self.topo_raw_switches] self.lock.release() """ adds link list of raw links """ def bring_up_link(self, link): self.topo_raw_links.append(link) """ check if link specific nodes exists. """ def check_link(self,sdpid, sport, ddpid, dport): i, link in self.topo_raw_links: if ((sdpid, sport), (ddpid, dport)) == ((link.src.dpid, link.src.port_no), (link.dst.dpid, link.dst.port_no)): return true return false """ finds shortest path source s destination d. both s , d switches. """ def find_shortest_path(self, s): s_count = self.switches_count() s_temp = s visited = [] shortest_path = {} while s_count != len(visited): print visited visited.append(s_temp) print visited print ("s_temp 1: " + str(s_temp)) l in self.find_links_with_src(s_temp): print "\t"+str(l) if l.dst.dpid not in visited: print ("\t\tdpid dst: "+ str(l.dst.dpid)) if l.src.dpid in shortest_path: shortest_path[l.dst.dpid] += 1 print("\t\t\tdpid found. count: "+str(shortest_path[l.dst.dpid])) else: print("\t\t\tdpid not found.") shortest_path[l.dst.dpid] = 0 print ("shortest_path: "+str(shortest_path)) min_val = min(shortest_path.itervalues()) t = [k k,v in shortest_path.iteritems() if v == min_val] s_temp = t[0] print "s_temp 2: " + str(s_temp)+"\n" return shortest_path """ finds dpids of destinations links' source s_dpid """ def find_dst_with_src(self, s_dpid): d = [] l in self.topo_raw_links: if l.src.dpid == s_dpid: d.append(l.dst.dpid) return d """ finds list of link objects links' src dpid s_dpid """ def find_links_with_src(self, s_dpid): d_links = [] l in self.topo_raw_links: if l.src.dpid == s_dpid: d_links.append(l) return d_links """ returns link object has in_dpid , in_port either source or destination dpid , port. """ def link_with_src_dst_port(self, in_port, in_dpid): l in self.topo_raw_links: if (l.src.dpid == in_dpid , l.src.port_no == in_port) or (l.dst.dpid == in_dpid , l.src.port_no == in_port): return l return none """ returns link object has in_dpid , in_port either source dpid , port. """ def link_with_src_port(self, in_port, in_dpid): l in self.topo_raw_links: if (l.src.dpid == in_dpid , l.src.port_no == in_port) or (l.dst.dpid == in_dpid , l.src.port_no == in_port): return l return none
so when check links gives me 24 links while there 4.
the code partially on sdnlab. removed of events save space. full code please visit: https://github.com/ehsan70/ryuapps/blob/master/topo_learner.py
problem solved.
i had use copy.copy()
update self.topo_shape.topo_raw_switches
. i.e: self.topo_shape.topo_raw_switches = copy.copy(get_all_switch(self))
Comments
Post a Comment