Untitled
unknown
python
2 years ago
5.6 kB
4
Indexable
from ryu.base import app_manager from ryu.controller.handler import set_ev_cls from ryu.ofproto import ofproto_v1_3 from ryu.topology import event from ryu.topology.api import get_switch, get_link from ryu.lib import hub import networkx as nx class EuclerCycle(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] def __init__(self, *args, **kwargs): super(EuclerCycle, self).__init__(*args, **kwargs) self.Topology_db = {} self.network_changed_thread = hub.spawn_after(1,None) self.graph = nx.Graph() @set_ev_cls(event.EventSwitchEnter) def handler_switch_enter(self, ev): print("Switch entering---------------") hub.kill(self.network_changed_thread) self.network_changed_thread = hub.spawn_after(1,self.network_changed) @set_ev_cls(event.EventSwitchLeave) def handler_switch_leave(self, ev): print("Switch leaving---------------") hub.kill(self.network_changed_thread) self.network_changed_thread = hub.spawn_after(1,self.network_changed) def network_changed(self): self.topo_raw_switches = get_switch(self, None) self.topo_raw_links = get_link(self, None) print("\nCurrent Links:") for l in self.topo_raw_links: print (str(l)) print("\nCurrent Switches:") for s in self.topo_raw_switches: print (str(s)) print("") self.BuildTopology() def BuildTopology(self): self.graph.clear() for l in self.topo_raw_links: _dpid_src = l.src.dpid _dpid_dst = l.dst.dpid _port_src = l.src.port_no _port_dst = l.dst.port_no self.graph.add_edge(_dpid_src, _dpid_dst, port_src=_port_src, port_dst=_port_dst) print("\nTopology Graph -------------------------------") print(self.graph.edges()) self.FindEulerCycle() self.Topology_db = {} for switch in self.topo_raw_switches: self.Topology_db[switch.dp.id] = {'datapath': switch.dp, 'ports': {}} for port in switch.ports.values(): self.Topology_db[switch.dp.id]['ports'][port.port_no] = port print("\nTopology Database -------------------------------") print(self.Topology_db) def FindEulerCycle(self): try: cycle = nx.eulerian_circuit(self.graph) euler_cycle_nodes = [] print("\nEuler Cycle: ") for node in cycle: euler_cycle_nodes.append(node[0]) # Euler_cycle_nodes is a list containing the nodes in the Euler cycle first_node = euler_cycle_nodes[0] euler_cycle_nodes.append(first_node) print(euler_cycle_nodes) #self.AddReversePaths(euler_cycle_nodes, num_segments=2) # call the method to add branch paths self.AddReversePaths(euler_cycle_nodes, num_segments=3) except nx.NetworkXError as e: print("Could not find Euler cycle: ", e) def AddReversePaths(self, backbone_path, num_segments): segment_length = len(backbone_path) // num_segments branch_nodes = [backbone_path[i * segment_length] for i in range(1, num_segments)] branch_nodes.append(backbone_path[-1]) # add the last node as a branch node reverse_paths = [] for i in range(num_segments): start = backbone_path[i * segment_length] end = branch_nodes[i] path = nx.shortest_path(self.graph, start, end) path.reverse() reverse_paths.append(path) # Convert branch paths to topology paths branch_paths = [] for i, path in enumerate(reverse_paths): branch_path = [] for node in path: if node in self.Topology_db: datapath = self.Topology_db[node]['datapath'] branch_path.append(datapath) else: print("Switch {} not found in Topology_db".format(node)) branch_paths.append(branch_path) # Print the branch paths print(branch_paths) # Modify the flow tables of switches based on the branch paths for i, path in enumerate(branch_paths): for j in range(len(path) - 1): src_dpid = path[j].id dst_dpid = path[j+1].id if src_dpid in self.Topology_db: datapath = self.Topology_db[src_dpid]['datapath'] src_port = self.graph[src_dpid][dst_dpid]['port_src'] dst_port = self.graph[src_dpid][dst_dpid]['port_dst'] ofproto = datapath.ofproto parser = datapath.ofproto_parser match = parser.OFPMatch(in_port=src_port) actions = [parser.OFPActionOutput(dst_port)] inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = parser.OFPFlowMod(datapath=datapath, priority=1, match=match, instructions=inst) datapath.send_msg(mod) print("Added flow entry to switch {} to forward packets from port {} to port {}".format(src_dpid, src_port, dst_port)) else: print("Switch {} not found in Topology_db".format(src_dpid))
Editor is loading...