コード例 #1
0
ファイル: discovery_pof.py プロジェクト: voidcc/PCTRL
    def create_discovery_packet(self, dpid, port_num, port_addr):
        """
        Build discovery packet
        """

        chassis_id = pkt.chassis_id(subtype=pkt.chassis_id.SUB_LOCAL)
        chassis_id.id = bytes('dpid:' + hex(long(dpid))[2:-1])
        # Maybe this should be a MAC.  But a MAC of what?  Local port, maybe?

        port_id = pkt.port_id(subtype=pkt.port_id.SUB_PORT, id=str(port_num))

        ttl = pkt.ttl(ttl=self._ttl)

        sysdesc = pkt.system_description()
        sysdesc.payload = bytes('dpid:' + hex(long(dpid))[2:-1])

        discovery_packet = pkt.lldp()
        discovery_packet.tlvs.append(chassis_id)
        discovery_packet.tlvs.append(port_id)
        discovery_packet.tlvs.append(ttl)
        discovery_packet.tlvs.append(sysdesc)
        discovery_packet.tlvs.append(pkt.end_tlv())

        eth = pkt.ethernet(type=pkt.ethernet.LLDP_TYPE)
        eth.src = port_addr
        eth.dst = pkt.ETHERNET.NDP_MULTICAST
        eth.payload = discovery_packet

        po = of.ofp_packet_out(action=of.ofp_action_output(port=port_num))
        po.data = eth.pack()
        return po.pack()
コード例 #2
0
ファイル: discovery_pof.py プロジェクト: voidcc/PCTRL
 def create_discovery_packet (self, dpid, port_num, port_addr):
     """
     Build discovery packet
     """
 
     chassis_id = pkt.chassis_id(subtype=pkt.chassis_id.SUB_LOCAL)
     chassis_id.id = bytes('dpid:' + hex(long(dpid))[2:-1])
     # Maybe this should be a MAC.  But a MAC of what?  Local port, maybe?
 
     port_id = pkt.port_id(subtype=pkt.port_id.SUB_PORT, id=str(port_num))
 
     ttl = pkt.ttl(ttl = self._ttl)
 
     sysdesc = pkt.system_description()
     sysdesc.payload = bytes('dpid:' + hex(long(dpid))[2:-1])
 
     discovery_packet = pkt.lldp()
     discovery_packet.tlvs.append(chassis_id)
     discovery_packet.tlvs.append(port_id)
     discovery_packet.tlvs.append(ttl)
     discovery_packet.tlvs.append(sysdesc)
     discovery_packet.tlvs.append(pkt.end_tlv())
 
     eth = pkt.ethernet(type=pkt.ethernet.LLDP_TYPE)
     eth.src = port_addr
     eth.dst = pkt.ETHERNET.NDP_MULTICAST
     eth.payload = discovery_packet
 
     po = of.ofp_packet_out(action = of.ofp_action_output(port=port_num))
     po.data = eth.pack()
     return po.pack()
コード例 #3
0
ファイル: discovery_pof.py プロジェクト: voidcc/PCTRL
    def _handle_openflow_PacketIn(self, event):
        """
        Receive and process LLDP packets
        """

        packet = event.parsed

        if (packet.effective_ethertype != pkt.ethernet.LLDP_TYPE
                or packet.dst != pkt.ETHERNET.NDP_MULTICAST):
            if not self._eat_early_packets: return
            if not event.connection.connect_time: return
            enable_time = time.time() - self.send_cycle_time - 1
            if event.connection.connect_time > enable_time:
                return EventHalt
            return

        if self._explicit_drop:
            if event.ofp.buffer_id is not None:
                log.debug("Dropping LLDP packet %i", event.ofp.buffer_id)
                msg = of.ofp_packet_out()
                msg.buffer_id = event.ofp.buffer_id
                msg.in_port = event.port
                event.connection.send(msg)

        lldph = packet.find(pkt.lldp)
        if lldph is None or not lldph.parsed:
            log.error("LLDP packet could not be parsed")
            return EventHalt
        if len(lldph.tlvs) < 3:
            log.error("LLDP packet without required three TLVs")
            return EventHalt
        if lldph.tlvs[0].tlv_type != pkt.lldp.CHASSIS_ID_TLV:
            log.error("LLDP packet TLV 1 not CHASSIS_ID")
            return EventHalt
        if lldph.tlvs[1].tlv_type != pkt.lldp.PORT_ID_TLV:
            log.error("LLDP packet TLV 2 not PORT_ID")
            return EventHalt
        if lldph.tlvs[2].tlv_type != pkt.lldp.TTL_TLV:
            log.error("LLDP packet TLV 3 not TTL")
            return EventHalt

        def lookInSysDesc():
            r = None
            for t in lldph.tlvs[3:]:
                if t.tlv_type == pkt.lldp.SYSTEM_DESC_TLV:
                    # This is our favored way...
                    for line in t.payload.split('\n'):
                        if line.startswith('dpid:'):
                            try:
                                return int(line[5:], 16)
                            except:
                                pass
                    if len(t.payload) == 8:
                        # Maybe it's a FlowVisor LLDP...
                        # Do these still exist?
                        try:
                            return struct.unpack("!Q", t.payload)[0]
                        except:
                            pass
                    return None

        originatorDPID = lookInSysDesc()

        if originatorDPID == None:
            # We'll look in the CHASSIS ID
            if lldph.tlvs[0].subtype == pkt.chassis_id.SUB_LOCAL:
                if lldph.tlvs[0].id.startswith('dpid:'):
                    # This is how NOX does it at the time of writing
                    try:
                        originatorDPID = int(lldph.tlvs[0].id[5:], 16)
                    except:
                        pass
            if originatorDPID == None:
                if lldph.tlvs[0].subtype == pkt.chassis_id.SUB_MAC:
                    # Last ditch effort -- we'll hope the DPID was small enough
                    # to fit into an ethernet address
                    if len(lldph.tlvs[0].id) == 6:
                        try:
                            s = lldph.tlvs[0].id
                            originatorDPID = struct.unpack(
                                "!Q", '\x00\x00' + s)[0]
                        except:
                            pass

        if originatorDPID == None:
            log.warning("Couldn't find a DPID in the LLDP packet")
            return EventHalt

        if originatorDPID not in core.openflow.connections:
            log.info('Received LLDP packet from unknown switch')
            return EventHalt

        # Get port number from port TLV
        if lldph.tlvs[1].subtype != pkt.port_id.SUB_PORT:
            log.warning(
                "Thought we found a DPID, but packet didn't have a port")
            return EventHalt
        originatorPort = None
        if lldph.tlvs[1].id.isdigit():
            # We expect it to be a decimal value
            originatorPort = int(lldph.tlvs[1].id)
        elif len(lldph.tlvs[1].id) == 2:
            # Maybe it's a 16 bit port number...
            try:
                originatorPort = struct.unpack("!H", lldph.tlvs[1].id)[0]
            except:
                pass
        if originatorPort is None:
            log.warning("Thought we found a DPID, but port number didn't " +
                        "make sense")
            return EventHalt

        if (event.dpid, event.port) == (originatorDPID, originatorPort):
            log.warning("Port received its own LLDP packet; ignoring")
            return EventHalt

        link = Discovery.Link(originatorDPID, originatorPort, event.dpid,
                              event.port)

        if link not in self.adjacency:
            self.adjacency[link] = time.time()
            log.info('link detected: %s', link)
            self.raiseEventNoErrors(LinkEvent, True, link)
        else:
            # Just update timestamp
            self.adjacency[link] = time.time()

        return EventHalt  # Probably nobody else needs this event
コード例 #4
0
ファイル: discovery_pof.py プロジェクト: voidcc/PCTRL
 def _handle_openflow_PacketIn (self, event):
     """
     Receive and process LLDP packets
     """
 
     packet = event.parsed
 
     if (packet.effective_ethertype != pkt.ethernet.LLDP_TYPE
         or packet.dst != pkt.ETHERNET.NDP_MULTICAST):
         if not self._eat_early_packets: return
         if not event.connection.connect_time: return
         enable_time = time.time() - self.send_cycle_time - 1
         if event.connection.connect_time > enable_time:
             return EventHalt
         return
 
     if self._explicit_drop:
         if event.ofp.buffer_id is not None:
             log.debug("Dropping LLDP packet %i", event.ofp.buffer_id)
             msg = of.ofp_packet_out()
             msg.buffer_id = event.ofp.buffer_id
             msg.in_port = event.port
             event.connection.send(msg)
 
     lldph = packet.find(pkt.lldp)
     if lldph is None or not lldph.parsed:
         log.error("LLDP packet could not be parsed")
         return EventHalt
     if len(lldph.tlvs) < 3:
         log.error("LLDP packet without required three TLVs")
         return EventHalt
     if lldph.tlvs[0].tlv_type != pkt.lldp.CHASSIS_ID_TLV:
         log.error("LLDP packet TLV 1 not CHASSIS_ID")
         return EventHalt
     if lldph.tlvs[1].tlv_type != pkt.lldp.PORT_ID_TLV:
         log.error("LLDP packet TLV 2 not PORT_ID")
         return EventHalt
     if lldph.tlvs[2].tlv_type != pkt.lldp.TTL_TLV:
         log.error("LLDP packet TLV 3 not TTL")
         return EventHalt
 
     def lookInSysDesc ():
         r = None
         for t in lldph.tlvs[3:]:
             if t.tlv_type == pkt.lldp.SYSTEM_DESC_TLV:
                 # This is our favored way...
                 for line in t.payload.split('\n'):
                     if line.startswith('dpid:'):
                         try:
                             return int(line[5:], 16)
                         except:
                             pass
                 if len(t.payload) == 8:
                     # Maybe it's a FlowVisor LLDP...
                     # Do these still exist?
                     try:
                         return struct.unpack("!Q", t.payload)[0]
                     except:
                         pass
                 return None
 
     originatorDPID = lookInSysDesc()
 
     if originatorDPID == None:
         # We'll look in the CHASSIS ID
         if lldph.tlvs[0].subtype == pkt.chassis_id.SUB_LOCAL:
             if lldph.tlvs[0].id.startswith('dpid:'):
                 # This is how NOX does it at the time of writing
                 try:
                     originatorDPID = int(lldph.tlvs[0].id[5:], 16)
                 except:
                     pass
         if originatorDPID == None:
             if lldph.tlvs[0].subtype == pkt.chassis_id.SUB_MAC:
                 # Last ditch effort -- we'll hope the DPID was small enough
                 # to fit into an ethernet address
                 if len(lldph.tlvs[0].id) == 6:
                     try:
                         s = lldph.tlvs[0].id
                         originatorDPID = struct.unpack("!Q",'\x00\x00' + s)[0]
                     except:
                         pass
 
     if originatorDPID == None:
         log.warning("Couldn't find a DPID in the LLDP packet")
         return EventHalt
 
     if originatorDPID not in core.openflow.connections:
         log.info('Received LLDP packet from unknown switch')
         return EventHalt
 
     # Get port number from port TLV
     if lldph.tlvs[1].subtype != pkt.port_id.SUB_PORT:
         log.warning("Thought we found a DPID, but packet didn't have a port")
         return EventHalt
     originatorPort = None
     if lldph.tlvs[1].id.isdigit():
         # We expect it to be a decimal value
         originatorPort = int(lldph.tlvs[1].id)
     elif len(lldph.tlvs[1].id) == 2:
         # Maybe it's a 16 bit port number...
         try:
             originatorPort  =  struct.unpack("!H", lldph.tlvs[1].id)[0]
         except:
             pass
     if originatorPort is None:
         log.warning("Thought we found a DPID, but port number didn't " +
                   "make sense")
         return EventHalt
 
     if (event.dpid, event.port) == (originatorDPID, originatorPort):
         log.warning("Port received its own LLDP packet; ignoring")
         return EventHalt
 
     link = Discovery.Link(originatorDPID, originatorPort, event.dpid,
                           event.port)
 
     if link not in self.adjacency:
         self.adjacency[link] = time.time()
         log.info('link detected: %s', link)
         self.raiseEventNoErrors(LinkEvent, True, link)
     else:
         # Just update timestamp
         self.adjacency[link] = time.time()
 
     return EventHalt # Probably nobody else needs this event