zoukankan      html  css  js  c++  java
  • sdn控制器拓扑发现(三) --lldp

       


    def _port_added(self, port): lldp_data
    = LLDPPacket.lldp_packet( port.dpid, port.port_no, port.hw_addr, self.DEFAULT_TTL) self.ports.add_port(port, lldp_data) # LOG.debug('_port_added dpid=%s, port_no=%s, live=%s', # port.dpid, port.port_no, port.is_live())
        @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
        def port_status_handler(self, ev):
            msg = ev.msg
            reason = msg.reason
            dp = msg.datapath
            ofpport = msg.desc
    
            if reason == dp.ofproto.OFPPR_ADD:
                # LOG.debug('A port was added.' +
                #           '(datapath id = %s, port number = %s)',
                #           dp.id, ofpport.port_no)
                self.port_state[dp.id].add(ofpport.port_no, ofpport)
                self.send_event_to_observers(
                    event.EventPortAdd(Port(dp.id, dp.ofproto, ofpport)))
    
                if not self.link_discovery:
                    return
    
                port = self._get_port(dp.id, ofpport.port_no)
                if port and not port.is_reserved():
                    self._port_added(port)
                    self.lldp_event.set()
     def state_change_handler(self, ev):
            dp = ev.datapath
            assert dp is not None
            LOG.debug(dp)
    
                # Do not add ports while dp has multiple connections to controller.
                if not dp_multiple_conns:
                    for port in switch.ports:
                        if not port.is_reserved():
                            self._port_added(port)
        @staticmethod
        def lldp_packet(dpid, port_no, dl_addr, ttl):
            pkt = packet.Packet()
    
            dst = lldp.LLDP_MAC_NEAREST_BRIDGE
            src = dl_addr
            ethertype = ETH_TYPE_LLDP
            eth_pkt = ethernet.ethernet(dst, src, ethertype)
            pkt.add_protocol(eth_pkt)
    
            tlv_chassis_id = lldp.ChassisID(
                subtype=lldp.ChassisID.SUB_LOCALLY_ASSIGNED,
                chassis_id=(LLDPPacket.CHASSIS_ID_FMT %
                            dpid_to_str(dpid)).encode('ascii'))
    
            tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_PORT_COMPONENT,
                                      port_id=struct.pack(
                                          LLDPPacket.PORT_ID_STR,
                                          port_no))
    
            tlv_ttl = lldp.TTL(ttl=ttl)
            tlv_end = lldp.End()
    
            tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_end)
            lldp_pkt = lldp.lldp(tlvs)
            pkt.add_protocol(lldp_pkt)
    
            pkt.serialize()
            return pkt.data
        @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
        def lldp_packet_in_handler(self, ev):
            if not self.link_discovery:
                return
    
            msg = ev.msg
            try:
                src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
            except LLDPPacket.LLDPUnknownFormat:
                # This handler can receive all the packets which can be
                # not-LLDP packet. Ignore it silently
                return
    
            dst_dpid = msg.datapath.id
            if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
                dst_port_no = msg.in_port
            elif msg.datapath.ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION:
                dst_port_no = msg.match['in_port']
            else:
                LOG.error('cannot accept LLDP. unsupported version. %x',
                          msg.datapath.ofproto.OFP_VERSION)
    
            src = self._get_port(src_dpid, src_port_no)
            if not src or src.dpid == dst_dpid:
                return
            try:
                self.ports.lldp_received(src)
            except KeyError:
                # There are races between EventOFPPacketIn and
                # EventDPPortAdd. So packet-in event can happend before
                # port add event. In that case key error can happend.
                # LOG.debug('lldp_received error', exc_info=True)
                pass
    
            dst = self._get_port(dst_dpid, dst_port_no)
            if not dst:
                return
    
            old_peer = self.links.get_peer(src)
            # LOG.debug("Packet-In")
            # LOG.debug("  src=%s", src)
            # LOG.debug("  dst=%s", dst)
            # LOG.debug("  old_peer=%s", old_peer)
            if old_peer and old_peer != dst:
                old_link = Link(src, old_peer)
                del self.links[old_link]
                self.send_event_to_observers(event.EventLinkDelete(old_link))
    
            link = Link(src, dst)
            if link not in self.links:
                self.send_event_to_observers(event.EventLinkAdd(link))
    
                # remove hosts if it's not attached to edge port
                host_to_del = []
                for host in self.hosts.values():
                    if not self._is_edge_port(host.port):
                        host_to_del.append(host.mac)
    
                for host_mac in host_to_del:
                    del self.hosts[host_mac]
    
            if not self.links.update_link(src, dst):
                # reverse link is not detected yet.
                # So schedule the check early because it's very likely it's up
                self.ports.move_front(dst)
                self.lldp_event.set()
            if self.explicit_drop:
                self._drop_packet(msg)
  • 相关阅读:
    Pure-ftpd无法连接到服务器 425错误
    jQuery 取选中的radio的值方法
    Linux中RM快速删除大量文件/文件夹方法
    CSS(七):浮动
    CSS(六):盒子模型
    CSS(五):背景、列表、超链接伪类、鼠标形状控制属性
    CSS(四):字体和文本属性
    CSS三:CSS的三种引入方式
    CSS(二):选择器
    CSS(一):CSS简介和基本语法
  • 原文地址:https://www.cnblogs.com/dream397/p/13180412.html
Copyright © 2011-2022 走看看