1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| import json from ryu.base import app_manager from ryu.controller import ofp_event from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER from ryu.controller.handler import set_ev_cls from ryu.lib import hub from ryu.ofproto import ofproto_v1_3 from ryu.topology import event, switches
class LinkCollector(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
def __init__(self, *args, **kwargs): super(LinkCollector, self).__init__(*args, **kwargs) self.topology_api_app = self self.links = {} self.switches = {} self.datapaths = {} self.link_counter = 1 self.monitor_thread = hub.spawn(self._monitor)
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser
self.datapaths[datapath.id] = datapath
match = parser.OFPMatch() actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = parser.OFPFlowMod(datapath=datapath, priority=0, match=match, instructions=inst) datapath.send_msg(mod)
@set_ev_cls(event.EventSwitchEnter) def get_topology_data(self, ev): switch = ev.switch self.switches[switch.dp.id] = switch
@set_ev_cls(event.EventSwitchLeave) def switch_leave_handler(self, ev): switch = ev.switch if switch.dp.id in self.switches: del self.switches[switch.dp.id]
@set_ev_cls(event.EventLinkAdd) def link_add_handler(self, ev): link = ev.link if link.src.dpid not in self.switches or link.dst.dpid not in self.switches: return else: link_id = self.link_counter self.link_counter += 1 self.links[link] = {'id': link_id, 'ports': (link.src.port_no, link.dst.port_no)}
with open("link_dest_sw.txt", "a") as f: f.write(f"Link ID: {link_id}, Destination Switch: {link.dst.dpid}\n")
@set_ev_cls(event.EventLinkDelete) def link_delete_handler(self, ev): link = ev.link if link in self.links: del self.links[link]
def _monitor(self): i=21 while i>=0: for link, info in self.links.items(): src_sw, dst_sw = link.src.dpid, link.dst.dpid src_port, dst_port = info['ports'] for datapath_id, datapath in self.datapaths.items(): if datapath_id == src_sw: self._request_stats(datapath, src_port) elif datapath_id == dst_sw: self._request_stats(datapath, dst_port) i=i-1 hub.sleep(10) self.logger.info('finish!!!!')
def _request_stats(self, datapath, port_no): parser = datapath.ofproto_parser req = parser.OFPPortStatsRequest(datapath, 0, port_no) datapath.send_msg(req)
@set_ev_cls(ofp_event.EventOFPPortStatsReply, MAIN_DISPATCHER) def _port_stats_reply_handler(self, ev): body = ev.msg.body datapath = ev.msg.datapath for stat in body: port_no = stat.port_no rx_bytes = stat.rx_bytes tx_bytes = stat.tx_bytes link_info = self._get_link_info(datapath.id, port_no) if link_info: link_id, remote_dpid = link_info with open("link_stats.txt", "a") as f: f.write(f"Link ID: {link_id}, Switch {datapath.id} Port {port_no}: " f"RX bytes: {rx_bytes}, TX bytes: {tx_bytes}\n")
def _get_link_info(self, dpid, port_no): for link, info in self.links.items(): src_sw, dst_sw = link.src.dpid, link.dst.dpid src_port, dst_port = info['ports'] if src_sw == dpid and src_port == port_no: return info['id'], dst_sw elif dst_sw == dpid and dst_port == port_no: return info['id'], src_sw return None
|