标签:color load lazy path 建立 wait packet sel ase
from ryu.base import app_manager from ryu.ofproto import ofproto_v1_3 from ryu.controller import ofp_event from ryu.controller.handler import MAIN_DISPATCHER,CONFIG_DISPATCHER,DEAD_DISPATCHER #只是表示datapath数据路径的状态 from ryu.controller.handler import set_ev_cls from ryu.lib import hub from ryu.lib.packet import packet,ethernet from ryu.topology import event,switches from ryu.topology.api import get_switch,get_link,get_host
class TopoDetect(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] def __init__(self,*args,**kwargs): super(TopoDetect,self).__init__(*args,**kwargs) self.topology_api_app = self #用于保持对象本身,后面get_switch等方法需要(我们也可以直接传入self) self.link_list = None #保存所有的link信息,由get_link获得 self.switch_list = None #保存所有的switch信息,由get_switch获得 self.host_list = None #保存所有的host信息,由get_host获得 self.dpid2id = {} #获取交换机dpid,以及自定义id--->{dpid:id} self.id2dpid = {} #对应上面的self.dpid2id,翻转即可,因为我们使用id进行建立邻接矩阵,这两个结构方便查找 self.dpid2switch = {} #保存dpid和对应的交换机全部信息---->通过矩阵获得id,然后获得dpid,最后获得交换机对象信息 self.ip2host = {} #根据ip,保存主机对象信息--->{ip:host} self.ip2switch = {} #根据ip,获取当前主机是连接到哪个交换机--->{ip:dpid} self.net_size = 0 #记录交换机个数(网络拓扑大小) self.net_topo = [] #用于保存邻接矩阵 self.monitor_thread = hub.spawn(self._monitor) #协程实现定时检测网络拓扑
@set_ev_cls(ofp_event.EventOFPSwitchFeatures,CONFIG_DISPATCHER) def switch_feature_handle(self,ev): """ datapath中有配置消息到达 """ #print("------------------switch_feature_handle") msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser match = ofp_parser.OFPMatch() actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,ofproto.OFPCML_NO_BUFFER)] self.add_flow(datapath=datapath,priority=0,match=match,actions=actions,extra_info="config infomation arrived!!") def add_flow(self,datapath,priority,match,actions,idle_timeout=0,hard_timeout=0,extra_info=None): #print("------------------add_flow:") if extra_info != None: print(extra_info) ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser inst = [ofp_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)] mod = ofp_parser.OFPFlowMod(datapath=datapath,priority=priority, idle_timeout=idle_timeout, hard_timeout=hard_timeout, match=match,instructions=inst) datapath.send_msg(mod); @set_ev_cls(ofp_event.EventOFPPacketIn,MAIN_DISPATCHER) def packet_in_handler(self,ev): #print("------------------packet_in_handler") msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser dpid = datapath.id in_port = msg.match[‘in_port‘] pkt = packet.Packet(msg.data) eth_pkt = pkt.get_protocol(ethernet.ethernet) dst = eth_pkt.dst src = eth_pkt.src #self.logger.info("------------------Controller %s get packet, Mac address from: %s send to: %s , send from datapath: %s,in port is: %s" # ,dpid,src,dst,dpid,in_port) #self.get_topology(None)
def _monitor(self): """ 协程实现伪并发,探测拓扑状态 """ while True: #print("------------------_monitor") self.get_topology(None) try: self.show_topology() except Exception as err: print("Please use cmd: pingall to detect topology and wait a moment") hub.sleep(5) #5秒一次 events = [event.EventSwitchEnter, event.EventSwitchLeave, event.EventSwitchReconnected, event.EventPortAdd, event.EventPortDelete, event.EventPortModify, event.EventLinkAdd, event.EventLinkDelete, event.EventHostAdd] @set_ev_cls(events) def get_topology(self,ev): print("-----------------get_topology") #获取所有的交换机、链路、主机信息 self.switch_list = get_switch(self.topology_api_app) #1.只要交换机与控制器联通,就可以获取 self.link_list = get_link(self.topology_api_app) #2.在ryu启动时,加上--observe-links即可用于拓扑发现 self.host_list = get_host(self.topology_api_app) #3.需要使用pingall,主机通过与边缘交换机连接,才能告诉控制器 #获取交换机字典id2dpid{id:dpid} dpid2switch{dpid:switch object} for i,switch in enumerate(self.switch_list): self.id2dpid[i] = switch.dp.id self.dpid2id[switch.dp.id] = i self.dpid2switch[switch.dp.id] = switch #获取主机信息字典ip2host{ipv4:host object} ip2switch{ipv4:dpid} for i,host in enumerate(self.host_list): self.ip2switch["%s"%host.ipv4] = host.port.dpid self.ip2host["%s"%host.ipv4] = host #根据链路信息,开始获取拓扑信息 self.net_size = len(self.id2dpid) #表示网络中交换机个数 for i in range(self.net_size): self.net_topo.append([0]*self.net_size) for link in self.link_list: src_dpid = link.src.dpid src_port = link.src.port_no dst_dpid = link.dst.dpid dst_port = link.dst.port_no sid = self.dpid2id[src_dpid] did = self.dpid2id[dst_dpid] self.net_topo[sid][did] = (src_port,1) #注意:这里1表示存在链路,后面可以修改为时延 self.net_topo[did][sid] = (dst_port,1) def show_topology(self): print("-----------------show_topology") print("----------switch network----------") line_info = " " for i in range(self.net_size): line_info+="s%d "%self.id2dpid[i] print(line_info) for i in range(self.net_size): line_info = "s%d "%self.id2dpid[i] for j in range(self.net_size): if self.net_topo[i][j] == 0: line_info+="0 " else: line_info+="(%d,%d) "%self.net_topo[i][j] print(line_info) print("----------host 2 switch----------") for key,val in self.ip2switch.items(): print("%s---s%d"%(key,val))
from ryu.base import app_manager from ryu.ofproto import ofproto_v1_3 from ryu.controller import ofp_event from ryu.controller.handler import MAIN_DISPATCHER,CONFIG_DISPATCHER,DEAD_DISPATCHER #只是表示datapath数据路径的状态 from ryu.controller.handler import set_ev_cls from ryu.lib import hub from ryu.lib.packet import packet,ethernet from ryu.topology import event,switches from ryu.topology.api import get_switch,get_link,get_host class TopoDetect(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] def __init__(self,*args,**kwargs): super(TopoDetect,self).__init__(*args,**kwargs) self.topology_api_app = self self.link_list = None self.switch_list = None self.host_list = None self.dpid2id = {} self.id2dpid = {} self.dpid2switch = {} self.ip2host = {} self.ip2switch = {} self.net_size = 0 self.net_topo = [] self.monitor_thread = hub.spawn(self._monitor) def _monitor(self): """ 协程实现伪并发,探测拓扑状态 """ while True: #print("------------------_monitor") self.get_topology(None) try: self.show_topology() except Exception as err: print("Please use cmd: pingall to detect topology and wait a moment") hub.sleep(5) #5秒一次 @set_ev_cls(ofp_event.EventOFPSwitchFeatures,CONFIG_DISPATCHER) def switch_feature_handle(self,ev): """ datapath中有配置消息到达 """ #print("------------------switch_feature_handle") msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser match = ofp_parser.OFPMatch() actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,ofproto.OFPCML_NO_BUFFER)] self.add_flow(datapath=datapath,priority=0,match=match,actions=actions,extra_info="config infomation arrived!!") def add_flow(self,datapath,priority,match,actions,idle_timeout=0,hard_timeout=0,extra_info=None): #print("------------------add_flow:") if extra_info != None: print(extra_info) ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser inst = [ofp_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)] mod = ofp_parser.OFPFlowMod(datapath=datapath,priority=priority, idle_timeout=idle_timeout, hard_timeout=hard_timeout, match=match,instructions=inst) datapath.send_msg(mod); @set_ev_cls(ofp_event.EventOFPPacketIn,MAIN_DISPATCHER) def packet_in_handler(self,ev): #print("------------------packet_in_handler") msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser dpid = datapath.id in_port = msg.match[‘in_port‘] pkt = packet.Packet(msg.data) eth_pkt = pkt.get_protocol(ethernet.ethernet) dst = eth_pkt.dst src = eth_pkt.src #self.logger.info("------------------Controller %s get packet, Mac address from: %s send to: %s , send from datapath: %s,in port is: %s" # ,dpid,src,dst,dpid,in_port) #self.get_topology(None) events = [event.EventSwitchEnter, event.EventSwitchLeave, event.EventSwitchReconnected, event.EventPortAdd, event.EventPortDelete, event.EventPortModify, event.EventLinkAdd, event.EventLinkDelete, event.EventHostAdd] @set_ev_cls(events) def get_topology(self,ev): print("-----------------get_topology") #获取所有的交换机、链路、主机信息 self.switch_list = get_switch(self.topology_api_app) #1.只要交换机与控制器联通,就可以获取 self.link_list = get_link(self.topology_api_app) #2.在ryu启动时,加上--observe-links即可用于拓扑发现 self.host_list = get_host(self.topology_api_app) #3.需要使用pingall,主机通过与边缘交换机连接,才能告诉控制器 #获取交换机字典id2dpid{id:dpid} dpid2switch{dpid:switch object} for i,switch in enumerate(self.switch_list): self.id2dpid[i] = switch.dp.id self.dpid2id[switch.dp.id] = i self.dpid2switch[switch.dp.id] = switch #获取主机信息字典ip2host{ipv4:host object} ip2switch{ipv4:dpid} for i,host in enumerate(self.host_list): self.ip2switch["%s"%host.ipv4] = host.port.dpid self.ip2host["%s"%host.ipv4] = host #根据链路信息,开始获取拓扑信息 self.net_size = len(self.id2dpid) #表示网络中交换机个数 for i in range(self.net_size): self.net_topo.append([0]*self.net_size) for link in self.link_list: src_dpid = link.src.dpid src_port = link.src.port_no dst_dpid = link.dst.dpid dst_port = link.dst.port_no sid = self.dpid2id[src_dpid] did = self.dpid2id[dst_dpid] self.net_topo[sid][did] = (src_port,1) #注意:这里1表示存在链路,后面可以修改为时延 self.net_topo[did][sid] = (dst_port,1) #print("+++++++++++allSwitch:") #for i,switch in enumerate(allSwitch): #switch中含有datapath和port对象 # print("===%d datapath:"%i) # print(switch.dp,switch.dp.id) # print("===%d ports: dpid portno name hwaddr:"%i) # print(switch.ports) # for port in switch.ports: # print(port.dpid,port.port_no,port.name,port.hw_addr) #===0 datapath: #<ryu.controller.controller.Datapath object at 0x7f8275748940> 1 #===0 ports: dpid portno name hwaddr: #[<ryu.topology.switches.Port object at 0x7f8275862c50>, <ryu.topology.switches.Port object at 0x7f8275862da0>] #1 1 b‘s1-eth1‘ ae:22:48:41:18:1d #1 2 b‘s1-eth2‘ 8a:71:db:bd:a1:86 #print("+++++++++++allLink:") #for link in self.link_list: # print(link.src,link.dst) #+++++++++++allLink: #Port<dpid=2, port_no=2, LIVE> Port<dpid=1, port_no=2, LIVE> #Port<dpid=1, port_no=2, LIVE> Port<dpid=2, port_no=2, LIVE> #print("+++++++++++allHost:") #for host in self.host_list: # print("%s %s %s"%(host.ipv4,host.mac,host.port)) #+++++++++++allHost: #[‘10.0.0.2‘] 5e:20:b8:90:dd:0e Port<dpid=2, port_no=1, LIVE> #[‘10.0.0.1‘] 6e:a0:c2:a0:f0:2a Port<dpid=1, port_no=1, LIVE> def show_topology(self): print("-----------------show_topology") print("----------switch network----------") line_info = " " for i in range(self.net_size): line_info+="s%d "%self.id2dpid[i] print(line_info) for i in range(self.net_size): line_info = "s%d "%self.id2dpid[i] for j in range(self.net_size): if self.net_topo[i][j] == 0: line_info+="0 " else: line_info+="(%d,%d) "%self.net_topo[i][j] print(line_info) print("----------host 2 switch----------") for key,val in self.ip2switch.items(): print("%s---s%d"%(key,val))
ryu-manager TopoDetect.py --verbose --observe-links
sudo mn --topo=linear,4 --switch=ovsk --controller=remote --link=tc
标签:color load lazy path 建立 wait packet sel ase
原文地址:https://www.cnblogs.com/ssyfj/p/14187621.html