Пример #1
0
    def flow_timer(self, dpid):
	
	request['dpid'] = str("0x") + str(longlong_to_octstr(dpid)[6:].replace(':',''))
	addr_switch = str(longlong_to_octstr(dpid)[6:].replace(':',''))
	#print "\nRequisicao das Flows do DataPath: ", longlong_to_octstr(dpid)[6:].replace(':','') 
	self.get_flows(request, addr_switch)
	self.post_callback(FLOW_COLLECTION_PERIOD, lambda : self.flow_timer(dpid)) 
Пример #2
0
    def port_status_change(self, dp, reason, port):
        '''Update LLDP packets on port status changes

        Add to the list of LLDP packets if a port is added.
        Delete from the list of LLDP packets if a port is removed.

        Keyword arguments:
        dp -- Datapath ID of port
        reason -- what event occured
        port -- port
        '''
        # Only process 'sane' ports
        if port[PORT_NO] <= openflow.OFPP_MAX:
            if reason == openflow.OFPPR_ADD:
                if port[STATE]== openflow.OFPPS_STP_BLOCK:
                    lg.warn('Port '+ str(port[PORT_NO]) + ' on DPID ' + longlong_to_octstr(dp) +' is blocked')
                else:
                    self.lldp_packets[dp][port[PORT_NO]] = create_discovery_packet(dp, port[HW_ADDR], port[PORT_NO], LLDP_TTL);
            elif reason == openflow.OFPPR_DELETE:
                del self.lldp_packets[dp][port[PORT_NO]]
            elif reason == openflow.OFPPR_MODIFY:
                if port[STATE] == openflow.OFPPS_STP_BLOCK:
                    lg.warn('Port '+ str(port[PORT_NO]) + ' on DPID ' + longlong_to_octstr(dp) +' is blocked')
                    try:
                        del self.lldp_packets[dp][port[PORT_NO]]
                    except KeyError,e:
                        pass
                else:
                    self.lldp_packets[dp][port[PORT_NO]] = create_discovery_packet(dp, port[HW_ADDR], port[PORT_NO], LLDP_TTL);
Пример #3
0
    def port_status_change(self, dp, reason, port):
        '''Update LLDP packets on port status changes

        Add to the list of LLDP packets if a port is added.
        Delete from the list of LLDP packets if a port is removed.

        Keyword arguments:
        dp -- Datapath ID of port
        reason -- what event occured
        port -- port
        '''
        # Only process 'sane' ports
        if port[PORT_NO] <= openflow.OFPP_MAX:
            if reason == openflow.OFPPR_ADD:
                if port[STATE] == openflow.OFPPS_STP_BLOCK:
                    lg.warn('Port ' + str(port[PORT_NO]) + ' on DPID ' +
                            longlong_to_octstr(dp) + ' is blocked')
                else:
                    self.lldp_packets[dp][
                        port[PORT_NO]] = create_discovery_packet(
                            dp, port[HW_ADDR], port[PORT_NO], LLDP_TTL)
            elif reason == openflow.OFPPR_DELETE:
                del self.lldp_packets[dp][port[PORT_NO]]
            elif reason == openflow.OFPPR_MODIFY:
                if port[STATE] == openflow.OFPPS_STP_BLOCK:
                    lg.warn('Port ' + str(port[PORT_NO]) + ' on DPID ' +
                            longlong_to_octstr(dp) + ' is blocked')
                    try:
                        del self.lldp_packets[dp][port[PORT_NO]]
                    except KeyError, e:
                        pass
                else:
                    self.lldp_packets[dp][
                        port[PORT_NO]] = create_discovery_packet(
                            dp, port[HW_ADDR], port[PORT_NO], LLDP_TTL)
Пример #4
0
    def manage_lldp_packet_from_host(self, dp_id, inport, lldph, chassid):
        #lg.debug('New lldp packet from host arrived')
        
        for i in lldph.tlvs:
            if i.type == lldp.MANAGEMENT_ADDR:
                mng_addr = i.mng_addr_int
            if i.type == lldp.SYSTEM_NAME_TLV:
                sys_name = i.system_name
            
        #print sys_name
        #print mng_addr
        #print type(lldph)

        dl_addr = ethernetaddr(chassid)
        nw_addr = mng_addr
        
        hosttuple =(dp_id, inport, dl_addr, nw_addr, sys_name)
        if hosttuple not in self.adjacency_hosts:
            lg.debug('Recieved LLDP packet from unconnected host')
            
            self.post_host_event(hosttuple, 'ADD')
            
            lg.debug('New Host detected (' + longlong_to_octstr(hosttuple[0]) +' p: ' \
                        +str(hosttuple[1]) + ' -> ' + \
                        sys_name + ' p: ' + longlong_to_octstr(chassid))
        
        # add to adjaceny list or update timestamp
        self.adjacency_hosts[(dp_id, inport, dl_addr, nw_addr, sys_name)] = time.time()
Пример #5
0
    def flow_timer(self, dpid):

        request['dpid'] = str("0x") + str(
            longlong_to_octstr(dpid)[6:].replace(':', ''))
        addr_switch = str(longlong_to_octstr(dpid)[6:].replace(':', ''))
        #print "\nRequisicao das Flows do DataPath: ", longlong_to_octstr(dpid)[6:].replace(':','')
        self.get_flows(request, addr_switch)
        self.post_callback(FLOW_COLLECTION_PERIOD,
                           lambda: self.flow_timer(dpid))
    def timeout_links(self):

      curtime = time.time()
      self.post_callback(TIMEOUT_CHECK_PERIOD, lambda : discovery.timeout_links(self))

      deleteme = []
      for linktuple in self.adjacency_list:
          if (curtime - self.adjacency_list[linktuple]) > LINK_TIMEOUT:
              deleteme.append(linktuple)
              lg.warn('link timeout ('+longlong_to_octstr(linktuple[0])+" p:"\
                         +str(linktuple[1]) +' -> '+\
                         longlong_to_octstr(linktuple[2])+\
                         'p:'+str(linktuple[3])+')')

      self.delete_links(deleteme)
Пример #7
0
    def timeout_links(self):

      curtime = time.time()
      self.post_callback(TIMEOUT_CHECK_PERIOD, lambda : discovery.timeout_links(self))

      deleteme = []
      for linktuple in self.adjacency_list:
          if (curtime - self.adjacency_list[linktuple]) > LINK_TIMEOUT:
              deleteme.append(linktuple)
              lg.warn('link timeout ('+longlong_to_octstr(linktuple[0])+" p:"\
                         +str(linktuple[1]) +' -> '+\
                         longlong_to_octstr(linktuple[2])+\
                         'p:'+str(linktuple[3])+')')

      self.delete_links(deleteme)
Пример #8
0
    def verify_bidir_links(self, links):
        '''Verify that all links are bi-directional

        Delete unidirectional links and disable ports
        '''
        srcs_to_delete = []
        for src_dpid in links.keys():
            dsts_to_delete = []
            for dst_dpid in links[src_dpid].keys():
                # Work out which ports need deleting
                ports_to_delete = []
                for (src_port, dst_port) in links[src_dpid][dst_dpid]:
                    ok = True
                    try:
                        if (dst_port, src_port) not in links[dst_dpid][src_dpid]:
                            ok = False
                    except KeyError:
                        ok = False

                    if not ok:
                        self.debugPrint("WARNING: Unidirectional link detected between %s -- %d   <-->   %s -- %d"%
                                (longlong_to_octstr(src_dpid)[6:], src_port,
                                 longlong_to_octstr(dst_dpid)[6:], dst_port))
                        ports_to_delete.append((src_port, dst_port))
                        try:
                            if (src_dpid <= dst_dpid):
                                self.datapaths[dst_dpid][dst_port]['enable'] = False
                            else:
                                self.datapaths[src_dpid][src_port]['enable'] = False
                        except KeyError:
                            self.datapaths[src_dpid][src_port]['enable'] = False


                # Delete the ports and work out if we need to delete the dst_dpid
                for ports in ports_to_delete:
                    links[src_dpid][dst_dpid].discard(ports)
                    if len(links[src_dpid][dst_dpid]) == 0:
                        dsts_to_delete.append(dst_dpid)

            # Delete the dst_dpids and identify whether to delete the src_dpid
            for dst_dpid in dsts_to_delete:
                del links[src_dpid][dst_dpid]
                if len(links[src_dpid]) == 0:
                    srcs_to_delete.append(src_dpid)

        # Delete the src_dpids
        for src_dpid in srcs_to_delete:
            del links[src_dpid]
Пример #9
0
    def dp_join(self, dp, stats):
        self.debugPrint("Datapath join: "+longlong_to_octstr(dp)[6:])
        if (not self.datapaths.has_key(dp)):
            # Process the port information returned by the switch

            # Build a list of ports
            now = time.time()
            ports = {}
            for port in stats['ports']:
                ports[port[core.PORT_NO]] = port
                if port[core.PORT_NO] <= openflow.OFPP_MAX:
                    port['enable_time'] = now + FLOOD_WAIT_TIME
                    port['flood'] = False
                    hw_addr = "\0\0" + port[core.HW_ADDR]
                    hw_addr = struct.unpack("!q", hw_addr)[0]
                    self.ctxt.send_port_mod(dp, port[core.PORT_NO], ethernetaddr(hw_addr),
                            openflow.OFPPC_NO_FLOOD, openflow.OFPPC_NO_FLOOD)

            # Record the datapath
            self.datapaths[dp] = ports
            self.port_count += len(ports)

            # Update the LLDP send period
            self.update_lldp_send_period()
        return CONTINUE
Пример #10
0
    def dp_leave(self, dp):

        self.debugPrint("Datapath leave, "+longlong_to_octstr(dp)[6:])
        if (self.datapaths.has_key(dp)):
            # Decrement port count by # of ports in datapath that is leaving
            self.port_count -= len(self.datapaths[dp])
            del self.datapaths[dp]
        return CONTINUE
Пример #11
0
    def table_stats_in_handler(self, dpid, tables):
        # If RRD does't exist create
        rrd_file = '/home/'+USER+'/rrds/table_' + longlong_to_octstr(dpid)[6:]
        if os.path.exists(rrd_file):
            for item in tables:
	       print '\t',item['name'],':',item['active_count']
	else:  
            for item in tables:
               print '\t',item['name'],':',item['active_count']
Пример #12
0
   def dp_join(self, dp, stats): 
       self.dps[dp] = stats
 
       self.lldp_packets[dp]  = {}
       for port in stats[PORTS]:
           # ignore local port
           if port[PORT_NO] == OFPP_LOCAL:
               continue
           if port[STATE]== openflow.OFPPS_STP_BLOCK:
               lg.warn('Port '+ str(port[PORT_NO]) + ' on DPID ' + longlong_to_octstr(dp) +' is blocked')
           else:
               self.lldp_packets[dp][port[PORT_NO]] = create_discovery_packet(dp, port[HW_ADDR], port[PORT_NO], LLDP_TTL);
Пример #13
0
    def dp_join(self, dp, stats):
        self.dps[dp] = stats

        self.lldp_packets[dp] = {}
        for port in stats[PORTS]:
            # ignore local port
            if port[PORT_NO] == OFPP_LOCAL:
                continue
            if port[STATE] == openflow.OFPPS_STP_BLOCK:
                lg.warn('Port ' + str(port[PORT_NO]) + ' on DPID ' +
                        longlong_to_octstr(dp) + ' is blocked')
            else:
                self.lldp_packets[dp][port[PORT_NO]] = create_discovery_packet(
                    dp, port[HW_ADDR], port[PORT_NO], LLDP_TTL)
Пример #14
0
    def aggregate_stats_in_handler(self, dpid, stats):
        # If RRD does't exist create
        agg_rrd_file = '/home/'+USER+'/rrds/agg_' + longlong_to_octstr(dpid)[6:] + '.rrd'
	upd_time = int(time.time())
        print "Agg stat from ",longlong_to_octstr(dpid)[6:]
	if os.path.exists(agg_rrd_file):
		packet_count = str(stats['packet_count'])
		byte_count = str(stats['byte_count'])
		flow_count = str(stats['flow_count'])
#                print 'agg stats:',packet_count,':',byte_count,':',flow_count
		print stats;

		rrdtool.update( agg_rrd_file,
			'N:' + packet_count + ':' + byte_count + ':' + flow_count )

        else:

	    # in real life data_sources would be populated in loop or something similar
 		rrdtool.create( agg_rrd_file,
                  	'DS:packet_count:COUNTER:60:U:U',
		  	'DS:byte_count:COUNTER:60:U:U',
                        'DS:flow_count:COUNTER:60:U:U', 
                 	'RRA:AVERAGE:0.5:1:525600',
                 	'RRA:AVERAGE:0.5:60:8760' )
Пример #15
0
    def port_stats_in_handler(self, dpid, ports):
        for item in ports:
	    # If RRD does't exist create
     
            port_no = str(item['port_no'])
	    port_rrd_file = '/home/'+USER+'/rrds/port_' + longlong_to_octstr(dpid)[6:] + '_' + port_no + '.rrd'
            if os.path.exists(port_rrd_file):
                tx_packets = str(item['tx_packets'])
                print 'port stats:',tx_packets
                if tx_packets != '-1' :
                	rrdtool.update( port_rrd_file,
                        'N:' + tx_packets )

            else:
                rrdtool.create( port_rrd_file,
                        'DS:tx_packets:COUNTER:60:U:U',
                        'RRA:AVERAGE:0.5:1:525600',
                        'RRA:AVERAGE:0.5:60:8760' )
Пример #16
0
 def aggregate_stats_in_handler(self, dpid, stats):
     print "Aggregate stats in from datapath", longlong_to_octstr(dpid)[6:]
     print '\t', stats
Пример #17
0
    def update_spanning_tree_callback(self, links):
        '''Callback called by get_all_links to process the set of links.

        Currently:
         - updates the flood ports to build a spanning tree

        Note: each link probably appears twice (once for each direction)

        As a temporary hack to deal with the fact that we don't have
        spanning tree support in NOX we build a set of "flood-ports". Each
        datapath id representing a switch has a set of ports associated
        which represent links that don't contain other OpenFlow
        switches. This set of paths can be used safely for flooding to
        ensure that we don't circulate broadcast packets.

        @param links list link tuples (src_dpid, src_port, dst_dpid, dst_port)
        '''
        # Walk through the datapaths and mark all ports 
        # that are potentially enableable
        now = time.time()
        for dp in self.datapaths.iterkeys():
            for port_no, port in self.datapaths[dp].iteritems():
                if port_no > openflow.OFPP_MAX or now > port['enable_time']:
                    port['enable'] = True
                else:
                    port['enable'] = False
                port['keep'] = False


        # Walk through the links and create a dict based on source port
        my_links = self.build_link_dict(links)
        self.verify_bidir_links(my_links)

        # Now try to build the spanning tree
        seen = set()
        roots = set()

        # Get all sources in reversed sorted order
        srcs = self.datapaths.keys()
        srcs.sort()
        srcs = srcs[::-1]

        #kyr
        if len(srcs):
            self.root = srcs[len(srcs)-1]

        # Process all sources
        while len(srcs) > 0:
            src_dpid = srcs.pop()

            # Add the dpid to the list of roots if we haven't yet seen it
            # (it must the be root of a tree)
            if src_dpid not in seen:
                roots.add(src_dpid)

            # Record that we've seen this node
            seen.add(src_dpid)

            # Make sure we know the src_dpid
            # This is necessary occasionally during start-up
            if not my_links.has_key(src_dpid):
                self.debugPrint("Warning: cannot find src_dpid %s in my_links"%longlong_to_octstr(src_dpid)[6:])
                continue

            # Walk through all dests
            dsts = my_links[src_dpid].keys()
            dsts.sort()
            next_dpids = []
            for dst_dpid in dsts:
                if dst_dpid not in seen:
                    # Attempt to find the fastest link to the other switch
                    best_speed = -1
                    best_pair = (-1, -1)
                    for (src_port, dst_port) in my_links[src_dpid][dst_dpid]:
                        try:
                            speed = self.datapaths[src_dpid][src_port]['speed']
                            if speed > best_speed:
                                best_speed = speed
                                best_pair = (src_port, dst_port)
                        except KeyError:
                            pass

                    # Disable all links but the fastest
                    for (src_port, dst_port) in my_links[src_dpid][dst_dpid]:
                        try:
                            if (src_port, dst_port) != best_pair:
                                self.datapaths[dst_dpid][dst_port]['enable'] = False
                            else:
                                self.datapaths[src_dpid][src_port]['keep'] = True
                                self.datapaths[dst_dpid][dst_port]['keep'] = True
                        except KeyError:
                            pass

                    # Record that we've seen the dpid
                    seen.add(dst_dpid)
                    next_dpids.append(dst_dpid)

                # Already-seen DPIDs
                else:
                    # Disable the link to the already-seen DPIDs
                    if src_dpid <= dst_dpid:
                        (local_src_dpid, local_dst_dpid) = (src_dpid, dst_dpid)
                    else:
                        (local_src_dpid, local_dst_dpid) = (dst_dpid, src_dpid)

                    for (src_port, dst_port) in my_links[local_src_dpid][local_dst_dpid]:
                        # If the src/dst dpids are the same, sort the ports
                        if local_src_dpid == local_dst_dpid:
                            if (src_port > dst_port):
                                (src_port, dst_port) = (dst_port, src_port)

                        # Disable the ports
                        try:
                            if not self.datapaths[local_dst_dpid][dst_port]['keep']:
                                self.datapaths[local_dst_dpid][dst_port]['enable'] = False
                            if not self.datapaths[local_src_dpid][src_port]['keep']:
                                self.datapaths[local_src_dpid][src_port]['enable'] = False
                        except KeyError:
                            pass

            # Once we've processed all links from this source, update the
            # list of sources so that the DPIDs we've just linked to will
            # be processed next. This is achieved by placing them at the
            # end of the list.
            next_dpids = next_dpids[::-1]
            for dpid in next_dpids:
                try:
                    srcs.remove(dpid)
                except ValueError:
                    pass
            srcs.extend(next_dpids)

        # Update the list of roots
        self.roots = roots
        
        # Build dictionary to send to gui
        # Format { dp: [stp_ports] }
        stp_ports = {} 
        
        # Walk through links and enable/disable as appropriate
        for dp in self.datapaths.iterkeys():
            floodports = []
            nonfloodports = []
            for port_no, port in self.datapaths[dp].iteritems():
                if port_no <= openflow.OFPP_MAX:
                    if port['enable'] != port['flood']:
                        if port['flood']:
                            port['flood'] = False
                            msg = 'Disabling'
                            config = openflow.OFPPC_NO_FLOOD
                        else:
                            port['flood'] = True
                            msg = 'Enabling'
                            config = 0

                        self.debugPrint("%s port: %s--%d"%(msg, longlong_to_octstr(dp)[6:], port_no))
                        hw_addr = "\0\0" + port[core.HW_ADDR]
                        hw_addr = struct.unpack("!q", hw_addr)[0]
                        self.ctxt.send_port_mod(dp, port[core.PORT_NO], ethernetaddr(hw_addr),
                                openflow.OFPPC_NO_FLOOD, config)

                    if port['flood']:
                        floodports.append(port_no)
                    else:
                        nonfloodports.append(port_no)

            self.debugPrint("Ports for %s: Flood: %s   Non-flood: %s"%(longlong_to_octstr(dp)[6:], floodports, nonfloodports))
            dp = str(hex(dp))
            dp = dp[2:len(dp)-1]
            while len(dp)<12:
                dp = "0"+dp
            stp_ports[dp] = floodports#, nonfloodports)
        
        # If ST has changed, update and send new enabled ports to GUI
        if cmp(self.current_stp_ports, stp_ports) != 0:
            self.current_stp_ports = stp_ports
            root = str(self.root)
            while len(root)<12:
                root = "0"+root
            stp_ports['root'] = root 
            self.send_to_gui("stp_ports", self.current_stp_ports)
        else:
            self.debugPrint("SP has not changed")
Пример #18
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:
            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

        elif lldph.tlvs[0].subtype == chassis_id.SUB_NETWORK:
            assert (len(lldph.tlvs[0].id) == 8)
            cid = lldph.tlvs[0].id

            # convert 48bit cid (in nbo) to longlong
            chassid = cid[7]       | cid[6] << 8  | \
                      cid[5] << 16 | cid[4] << 24 | \
                      cid[3] << 32 | cid[2] << 40 | \
                      cid[1] << 48 | cid[0] << 56

        else:
            lg.error("lldp chassis ID subtype is not recognized. ignoring")
            return

        # if chassid is from a switch we're not connected to, ignore
        if chassid not in self.dps:
            lg.debug('Recieved LLDP packet from unconnected switch'+\
                      longlong_to_octstr(chassid))
            return

        # 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

        if inport not in self.lldp_packets[dp_id]:
            lg.warn('Received LLDP on unavailable or STP-blocked port ' +
                    str(inport) + ' on DPID ' + longlong_to_octstr(dp_id))
            return

        # print 'LLDP packet in from',longlong_to_octstr(chassid),' port',str(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()
Пример #19
0
 def port_stats_in_handler(self, dpid, ports):
     print "Port stats in from datapath", longlong_to_octstr(dpid)[6:]
     for item in ports:
         print '\t',item['port_no'],':',item['tx_packets']
Пример #20
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:
            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

        elif lldph.tlvs[0].subtype == chassis_id.SUB_NETWORK:
            assert(len(lldph.tlvs[0].id) == 8)
            cid = lldph.tlvs[0].id

            # convert 48bit cid (in nbo) to longlong
            chassid = cid[7]       | cid[6] << 8  | \
                      cid[5] << 16 | cid[4] << 24 | \
                      cid[3] << 32 | cid[2] << 40 | \
                      cid[1] << 48 | cid[0] << 56

        else:
            lg.error("lldp chassis ID subtype is not recognized. ignoring")
            return

        # if chassid is from a switch we're not connected to, ignore
        if chassid not in self.dps:
            lg.debug('Recieved LLDP packet from unconnected switch'+\
                      longlong_to_octstr(chassid))
            return
    
        # 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

        if inport not in self.lldp_packets[dp_id]:
            lg.warn('Received LLDP on unavailable or STP-blocked port ' + str(inport) + ' on DPID ' + longlong_to_octstr(dp_id))
            return

        # print 'LLDP packet in from',longlong_to_octstr(chassid),' port',str(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()
Пример #21
0
 def table_stats_in_handler(self, dpid, tables):
     print "Table stats in from datapath", longlong_to_octstr(dpid)[6:]
     for item in tables:
         print '\t',item['name'],':',item['active_count']
Пример #22
0
 def aggregate_stats_in_handler(self, dpid, stats):
     print "Aggregate stats in from datapath", longlong_to_octstr(dpid)[6:]
     print '\t',stats
Пример #23
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_LOCAL:
            lg.error("lldp chassis ID subtype is not 'local', ignoring")
            return
        if not lldph.tlvs[0].id.tostring().startswith('dpid:'):
            lg.error("lldp chassis ID is not a dpid, ignoring")
            return
        try:
            chassid = int(lldph.tlvs[0].id.tostring()[5:], 16)
        except:
            lg.error("lldp chassis ID is not numeric', ignoring")
            return

        # if chassid is from a switch we're not connected to, ignore
        if chassid not in self.dps:
            lg.debug('Recieved LLDP packet from unconnected switch')
            return

        # 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 = (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()
    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_LOCAL:
            lg.error("lldp chassis ID subtype is not 'local', ignoring")
            return
        if not lldph.tlvs[0].id.tostring().startswith('dpid:'):
            lg.error("lldp chassis ID is not a dpid, ignoring")
            return
        try:
            chassid = int(lldph.tlvs[0].id.tostring()[5:], 16)
        except:
            lg.error("lldp chassis ID is not numeric', ignoring")
            return

        # if chassid is from a switch we're not connected to, ignore
        if chassid not in self.dps:
            lg.debug('Recieved LLDP packet from unconnected switch')
            return
    
        # 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 = (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()
Пример #25
0
 def table_stats_in_handler(self, dpid, tables):
     print "Table stats in from datapath", longlong_to_octstr(dpid)[6:]
     for item in tables:
         print '\t', item['name'], ':', item['active_count']
Пример #26
0
 def port_stats_in_handler(self, dpid, ports):
     print "Port stats in from datapath", longlong_to_octstr(dpid)[6:]
     for item in ports:
         print '\t', item['port_no'], ':', item['tx_packets']
Пример #27
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()