Exemple #1
0
    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
Exemple #2
0
    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
Exemple #3
0
    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()
Exemple #4
0
    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()