def _link_down(self, port): try: dst, rev_link_dst = self.links.port_deleted(port) except KeyError: # LOG.debug('key error. src=%s, dst=%s', # port, self.links.get_peer(port)) return link = Link(port, dst) self.send_event_to_observers(event.EventLinkDelete(link)) if rev_link_dst: rev_link = Link(dst, rev_link_dst) self.send_event_to_observers(event.EventLinkDelete(rev_link)) self.ports.move_front(dst)
def link_loop(self): while self.is_active: self.link_event.clear() now = time.time() deleted = [] for (link, timestamp) in self.links.items(): # LOG.debug('%s timestamp %d (now %d)', link, timestamp, now) if timestamp + self.LINK_TIMEOUT < now: deleted.append(link) for link in deleted: self.links.link_down(link) # LOG.debug('delete %s', link) self.send_event_to_observers(event.EventLinkDelete(link)) dst = link.dst rev_link = Link(dst, link.src) if rev_link not in deleted: # It is very likely that the reverse link is also # disconnected. Check it early. expire = now - self.LINK_TIMEOUT self.links.rev_link_set_timestamp(rev_link, expire) if dst in self.ports: self.ports.move_front(dst) self.lldp_event.set() self.link_event.wait(timeout=self.TIMEOUT_CHECK_PERIOD)
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)