Exemple #1
0
 def _handle_LinkEvent(self, event):
     l = event.link
     sw1 = switches[l.dpid1]
     sw2 = switches[l.dpid2]
     clear = of.ofp_flow_mod(command=of.OFPFC_DELETE)
     for sw in switches.itervalues():
         if sw.connection is None: continue
         sw.connection.send(clear)
     if event.removed:
         if sw2 in adjacency[sw1]: del adjacency[sw1][sw2]
         if sw1 in adjacency[sw2]: del adjacency[sw2][sw1]
         for ll in core.openflow_discovery.adjacency:
             if ll.dpid1 == l.dpid1 and ll.dpid2 == l.dpid2:
                 if Discovery.Link(
                         ll[2], ll[3], ll[0],
                         ll[1]) in core.openflow_discovery.adjacency:
                     adjacency[sw1][sw2] = ll.port1
                     adjacency[sw2][sw1] = ll.port2
                     break
     else:
         if adjacency[sw1][sw2] is None:
             if Discovery.Link(l[2], l[3], l[0],
                               l[1]) in core.openflow_discovery.adjacency:
                 adjacency[sw1][sw2] = l.port1
                 adjacency[sw2][sw1] = l.port2
         bad_macs = set()
         for mac, (sw, port) in mac_map.iteritems():
             if (sw is sw1 and port == l.port1) or (sw is sw2
                                                    and port == l.port2):
                 bad_macs.add(mac)
Exemple #2
0
   def flip(link):
       """
 .
 :param link: Lista de links
 :return: Instância de objeto Link.
 """
       return Discovery.Link(link[2], link[3], link[0], link[1])
Exemple #3
0
 def flip (link):
   return Discovery.Link(link[2], link[3],link[0],link[1])
Exemple #4
0
    def handle_lldp(self, packet, event):
        import pox.lib.packet as pkt
        from pox.openflow.discovery import Discovery, LinkEvent
        import time

        lldph = packet.find(pkt.lldp)
        if lldph is None or not lldph.parsed:
            return
        if len(lldph.tlvs) < 3:
            return
        if lldph.tlvs[0].tlv_type != pkt.lldp.CHASSIS_ID_TLV:
            return
        if lldph.tlvs[1].tlv_type != pkt.lldp.PORT_ID_TLV:
            return
        if lldph.tlvs[2].tlv_type != pkt.lldp.TTL_TLV:
            return

        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:
            return

        if originatorDPID not in core.openflow.connections:
            return

        # Get port number from port TLV
        if lldph.tlvs[1].subtype != pkt.port_id.SUB_PORT:
            return
        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:
            return

        if (event.dpid, event.port) == (originatorDPID, originatorPort):
            return

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

        if link not in self.adjacency:
            self.adjacency[link] = time.time()
            self.raiseEventNoErrors(LinkEvent, True, link)
        else:
            # Just update timestamp
            self.adjacency[link] = time.time()

        self.send_to_pyretic(
            ['link', originatorDPID, originatorPort, event.dpid, event.port])
        return  # Probably nobody else needs this event
Exemple #5
0
def flip (link):
return Discovery.Link(link[2],link[3], link[0],link[1])
l = event.link
sw1 = switches[l.dpid1]
sw2 = switches[l.dpid2]
# Invalidate all flows and path info.
# For link adds, this makes sure that if a new link leads to an
# improved path, we use it.
# For link removals, this makes sure that we don't use a
# path that may have been broken.
#NOTE: This could be radically improved! (e.g., not *ALL* paths break)
clear = of.ofp_flow_mod(command=of.OFPFC_DELETE)
for sw in switches.itervalues():
if sw.connection is None: continue
sw.connection.send(clear)
path_map.clear()
if event.removed:
# This link no longer okay
if sw2 in adjacency[sw1]: del adjacency[sw1][sw2]
if sw1 in adjacency[sw2]: del adjacency[sw2][sw1]
# But maybe there's another way to connect these...
for ll in core.openflow_discovery.adjacency:
if ll.dpid1 == l.dpid1 and ll.dpid2 == l.dpid2:
if flip(ll) in core.openflow_discovery.adjacency:
# Yup, link goes both ways
adjacency[sw1][sw2] = ll.port1
adjacency[sw2][sw1] = ll.port2
# Fixed -- new link chosen to connect these
break
else:
# If we already consider these nodes connected, we can
# ignore this link up.
# Otherwise, we might be interested...
if adjacency[sw1][sw2] is None:
# These previously weren't connected. If the link
# exists in both directions, we consider them connected now.
if flip(l) in core.openflow_discovery.adjacency:
# Yup, link goes both ways -- connected!
adjacency[sw1][sw2] = l.port1
adjacency[sw2][sw1] = l.port2
# If we have learned a MAC on this port which we now know to
# be connected to a switch, unlearn it.
bad_macs = set()
for mac,(sw,port) in mac_map.iteritems():
#print sw,sw1,port,l.port1
if sw is sw1 and port == l.port1:
if mac not in bad_macs:
log.debug("Unlearned %s", mac)
bad_macs.add(mac)
if sw is sw2 and port == l.port2:
if mac not in bad_macs:
log.debug("Unlearned %s", mac)
bad_macs.add(mac)
for mac in bad_macs:
del mac_map[mac]
def _handle_ConnectionUp (self, event):
sw = switches.get(event.dpid)
if sw is None:
# New switch
sw = Switch()
switches[event.dpid] = sw
sw.connect(event.connection)
else:
sw.connect(event.connection)
def _handle_BarrierIn (self, event):
wp = waiting_paths.pop((event.dpid,event.xid), None)
if not wp:
#log.info("No waiting packet %s,%s", event.dpid, event.xid)
return
#log.debug("Notify waiting packet %s,%s", event.dpid,event.xid)
wp.notify(event)
def launch ():
core.registerNew(l2_multi)
core.registerNew(Cleanswitch)
core.Cleanswitch._do_sleep()
timeout = min(max(PATH_SETUP_TIME, 5) * 2, 15)
Timer(timeout, WaitingPath.expire_waiting_paths, recurring=True)
print "will go to execute the timer for sent_sw"
#we will call the cleaning_sent_sw function in the switch class to erase the list of the switches that have been already polled for statistics. As long as the switches are in the sent_sw list no statistics request will be sent to them.
Timer(10, Switch.cleaning_sent_sw, recurring=True)
core.openflow.addListenerByName("FlowStatsReceived",
Switch()._handle_flowstats_received)
Exemple #6
0
def launch():
    discovery = Discovery()
    rete = Rete(discovery)