def register_for_fv_in(self, **kwargs): vlan = kwargs.get('vlan') #ether type 88b6 is experimental #88b6 IEEE 802.1 IEEE Std 802 - Local Experimental if (self.registered_for_fv_in == 1): return 1 logger.info("Registered for packet in events for FV") if (vlan == None): match = { DL_TYPE: 0x88b6, DL_DST: array_to_octstr(array.array('B', NDP_MULTICAST)) } else: match = { DL_TYPE: 0x88b6, DL_DST: array_to_octstr(array.array('B', NDP_MULTICAST)), DL_VLAN: vlan } inst.register_for_packet_match( lambda dpid, inport, reason, len, bid, packet: fv_packet_in_callback( self, dpid, inport, reason, len, bid, packet), 0xffff, match) self.registered_for_fv_in = 1 return 1
def register_for_fv_in(self, **kwargs): vlan = kwargs.get('vlan') #ether type 88b6 is experimental #88b6 IEEE 802.1 IEEE Std 802 - Local Experimental if(self.registered_for_fv_in == 1): return 1 logger.info("Registered for packet in events for FV") if(vlan == None): match = { DL_TYPE: 0x88b6, DL_DST: array_to_octstr(array.array('B', NDP_MULTICAST)) } else: match = { DL_TYPE: 0x88b6, DL_DST: array_to_octstr(array.array('B',NDP_MULTICAST)), DL_VLAN: vlan } inst.register_for_packet_match(lambda dpid, inport, reason, len, bid,packet : fv_packet_in_callback(self, dpid, inport, reason, len, bid, packet), 0xffff, match) self.registered_for_fv_in = 1 return 1
def install(self): self.register_for_datapath_join ( lambda dp,stats : discovery.dp_join(self, dp, stats) ) self.register_for_datapath_leave( lambda dp : discovery.dp_leave(self, dp) ) self.register_for_port_status( lambda dp, reason, port : discovery.port_status_change(self, dp, reason, port) ) # register handler for all LLDP packets if(self.vlan_id != None): match = { DL_DST : array_to_octstr(array.array('B',NDP_MULTICAST)),DL_TYPE: ethernet.LLDP_TYPE, DL_VLAN: self.vlan_id} else: match = { DL_DST: array_to_octstr(array.array('B',NDP_MULTICAST)),DL_TYPE: ethernet.LLDP_TYPE } self.register_for_packet_match(lambda dp,inport,reason,len,bid,packet : discovery.lldp_input_handler(self,dp,inport,reason,len,bid,packet), 0xffff, match) self.start_lldp_timer_thread()
def lldp_input_handler(self, dp_id, inport, ofp_reason, total_frame_len, buffer_id, packet): assert (packet.type == ethernet.LLDP_TYPE) if not packet.next: lg.error("lldp_input_handler lldp packet could not be parsed") return assert (isinstance(packet.next, lldp)) lldph = packet.next if (len(lldph.tlvs) < 4) or \ (lldph.tlvs[0].type != lldp.CHASSIS_ID_TLV) or\ (lldph.tlvs[1].type != lldp.PORT_ID_TLV) or\ (lldph.tlvs[2].type != lldp.TTL_TLV): lg.error("lldp_input_handler invalid lldp packet") return # parse out chassis id if lldph.tlvs[0].subtype != chassis_id.SUB_MAC: lg.error("lldp chassis ID subtype is not MAC, ignoring") return assert(len(lldph.tlvs[0].id) == 6) cid = lldph.tlvs[0].id # convert 48bit cid (in nbo) to longlong chassid = cid[5] | cid[4] << 8 | \ cid[3] << 16 | cid[2] << 24 | \ cid[1] << 32 | cid[0] << 40 # if chassid is from a switch we're not connected to, ignore dst_dpid_ = None for k_ in self.dps.keys(): if chassid == (k_ & 0x00ffffff): dst_dpid_ = k_ break else: for info in self.dps[k_]['ports']: chassid_mac = array_to_octstr(array.array('B',struct.pack('!Q',chassid))[2:]) if chassid_mac == mac_to_str(info['hw_addr']): dst_dpid_ = k_ break if dst_dpid_: break if not dst_dpid_: lg.debug('Received LLDP packet from unconnected switch') return chassid = dst_dpid_ # grab 16bit port ID from port tlv if lldph.tlvs[1].subtype != port_id.SUB_PORT: return # not one of ours if len(lldph.tlvs[1].id) != 2: lg.error("invalid lldph port_id format") return (portid,) = struct.unpack("!H", lldph.tlvs[1].id) if (dp_id, inport) == (chassid, portid): lg.error('Loop detected, received our own LLDP event') return # print 'LLDP packet in from',longlong_to_octstr(chassid),' port',str(portid) #linktuple = (longlong_to_octstr(dp_id), inport, longlong_to_octstr(chassid), portid) linktuple = (dp_id, inport, chassid, portid) if linktuple not in self.adjacency_list: self.add_link(linktuple) lg.warn('new link detected ('+longlong_to_octstr(linktuple[0])+' p:'\ +str(linktuple[1]) +' -> '+\ longlong_to_octstr(linktuple[2])+\ ' p:'+str(linktuple[3])+')') # add to adjaceny list or update timestamp self.adjacency_list[(dp_id, inport, chassid, portid)] = time.time()