2015-07-10 36 views
1

我正在使用Ryu作爲我的SDN控制器來控制具有環路的地形。Mininet pingall失敗,當地形中有環路

我正在使用學習切換技術來路由數據包。我的主要功能/處理程序是:

@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) 
def switch_features_handler(self, ev): 
    msg = ev.msg 
    self.logger.info('OFPSwitchFeatures received: ' 
        '\n\tdatapath_id=0x%016x n_buffers=%d ' 
        '\n\tn_tables=%d auxiliary_id=%d ' 
        '\n\tcapabilities=0x%08x', 
        msg.datapath_id, msg.n_buffers, msg.n_tables, 
        msg.auxiliary_id, msg.capabilities) 

    datapath = ev.msg.datapath 
    ofproto = datapath.ofproto 
    parser = datapath.ofproto_parser 
    match = parser.OFPMatch() 
    actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, 
             ofproto.OFPCML_NO_BUFFER)] 
    self.add_flow(datapath, 0, match, actions) 

def add_flow(self, datapath, priority, match, actions, buffer_id=None): 
    ofproto = datapath.ofproto 
    parser = datapath.ofproto_parser 

    inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, 
             actions)] 
    if buffer_id: 
     mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, 
           priority=priority, match=match, 
           instructions=inst) 
    else: 
     mod = parser.OFPFlowMod(datapath=datapath, priority=priority, 
           match=match, instructions=inst) 
    datapath.send_msg(mod) 

""" 
This is called when Ryu receives an OpenFlow packet_in message. The trick is set_ev_cls decorator. This decorator 
tells Ryu when the decorated function should be called. 
""" 
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) 
def _packet_in_handler(self, ev): 
    #print(self.mac_to_port) 
    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] 

    dst = eth.dst 
    src = eth.src 

    dpid = datapath.id 
    self.mac_to_port.setdefault(dpid, {}) 

    # self.logger.info("\tpacket 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 

    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) 
     # 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) 

我需要在我的topo中有循環。是否有人知道如何正確配置topo /控制器,以便循環可以ping通?

我的全控制器代碼:https://github.com/Ehsan70/RyuApps/blob/master/topo_learner.py 我的地形代碼:https://github.com/Ehsan70/RyuApps/blob/master/Pkt_Topo_with_loop.py

回答

0

好了,所以一些挖後,顯然,理想的網絡應該不會有循環。但是他們在現實世界的設計中。因此,爲了應對這種情況並且有所突破,使用了生成樹算法。該算法找出可以到達每個節點的最小邊集。

請參閱this link瞭解如何使用Ryu的STP。還可以克隆this repo瞭解一些教程和示例代碼。