예제 #1
0
    def link_loop(self):
        while self.is_active:
            self.link_event.clear()

            now = time.time()
            deleted = []
            inter_deleted = []
            for (link, timestamp) in self.links.items():
                # LOG.debug('%s timestamp %d (now %d)', link, timestamp, now)
                if timestamp + self.LINK_TIMEOUT < now:
                    src = link.src
                    if src in self.ports:
                        port_data = self.ports.get_port(src)
                        # LOG.debug('port_data %s', port_data)
                        if port_data.lldp_dropped() > self.LINK_LLDP_DROP:
                            deleted.append(link)

            for (link, timestamp) in self.inter_links.items():
                # LOG.debug('%s timestamp %d (now %d)', link, timestamp, now)
                if timestamp + self.LINK_TIMEOUT < now:
                    src = link.dst
                    if src in self.ports:
                        port_data = self.ports.get_port(src)
                        # LOG.debug('port_data %s', port_data)
                        if port_data.lldp_dropped() > self.LINK_LLDP_DROP:
                            inter_deleted.append(link)
                #'''
                for host in self.hosts.values():
                    host_port = host.port
                    dst_port = link.dst
                    if host_port.dpid == dst_port.dpid and host_port.port_no == dst_port.port_no:
                        del self.hosts[host.mac]
                        ev = event.EventHostDelete(host)
                        self.send_event_to_observers(ev)
                #'''
            for link in inter_deleted:
                self.inter_links.link_down(link)
                # LOG.debug('delete %s', link)
                self.send_event_to_observers(event.EventLinkDelete(link))

            for link in deleted:
                self.links.link_down(link)
                # LOG.debug('delete %s', link)
                self.send_event_to_observers(event.EventLinkDelete(link))

                dst = link.dst
                rev_link = Link(dst, link.src)
                if rev_link not in deleted:
                    # It is very likely that the reverse link is also
                    # disconnected. Check it early.
                    expire = now - self.LINK_TIMEOUT
                    self.links.rev_link_set_timestamp(rev_link, expire)
                    if dst in self.ports:
                        self.ports.move_front(dst)
                        self.lldp_event.set()

            self.link_event.wait(timeout=self.TIMEOUT_CHECK_PERIOD)
예제 #2
0
 def _link_down(self, port):
     try:
         dst, rev_link_dst = self.links.port_deleted(port)
     except KeyError:
         # LOG.debug('key error. src=%s, dst=%s',
         #           port, self.links.get_peer(port))
         return
     link = Link(port, dst)
     self.send_event_to_observers(event.EventLinkDelete(link))
     if rev_link_dst:
         rev_link = Link(dst, rev_link_dst)
         self.send_event_to_observers(event.EventLinkDelete(rev_link))
     self.ports.move_front(dst)
예제 #3
0
    def link_loop(self):
        while self.is_active:
            self.link_event.clear()

            now = time.time()
            deleted = []
            for (link, timestamp) in self.links.items():
                # LOG.debug('%s timestamp %d (now %d)', link, timestamp, now)
                if timestamp + self.LINK_TIMEOUT < now:
                    deleted.append(link)

            for link in deleted:
                self.links.link_down(link)
                # LOG.debug('delete %s', link)
                self.send_event_to_observers(event.EventLinkDelete(link))

                dst = link.dst
                rev_link = Link(dst, link.src)
                if rev_link not in deleted:
                    # It is very likely that the reverse link is also
                    # disconnected. Check it early.
                    expire = now - self.LINK_TIMEOUT
                    self.links.rev_link_set_timestamp(rev_link, expire)
                    if dst in self.ports:
                        self.ports.move_front(dst)
                        self.lldp_event.set()

            self.link_event.wait(timeout=self.TIMEOUT_CHECK_PERIOD)
예제 #4
0
 def _inter_link_down(self, port):
     for inter_link in self.inter_links:
         dst = inter_link.dst
         if dst.dpid == port.dpid and dst.port_no == port.port_no:
             print "inter link down :find port"
             print inter_link
             del self.inter_links[inter_link.src]
             self.send_event_to_observers(event.EventLinkDelete(inter_link))
예제 #5
0
    def lldp_packet_in_handler(self, ev):
        if not self.link_discovery:
            return

        msg = ev.msg
        try:
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
        except LLDPPacket.LLDPUnknownFormat as e:
            # This handler can receive all the packtes which can be
            # not-LLDP packet. Ignore it silently
            return

        dst_dpid = msg.datapath.id
        if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
            dst_port_no = msg.in_port
        elif msg.datapath.ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION:
            dst_port_no = msg.match['in_port']
        else:
            LOG.error('cannot accept LLDP. unsupported version. %x',
                      msg.datapath.ofproto.OFP_VERSION)

        src = self._get_port(src_dpid, src_port_no)
        if not src or src.dpid == dst_dpid:
            return
        try:
            self.ports.lldp_received(src)
        except KeyError:
            # There are races between EventOFPPacketIn and
            # EventDPPortAdd. So packet-in event can happend before
            # port add event. In that case key error can happend.
            # LOG.debug('lldp_received: KeyError %s', e)
            pass

        dst = self._get_port(dst_dpid, dst_port_no)
        if not dst:
            return

        old_peer = self.links.get_peer(src)
        # LOG.debug("Packet-In")
        # LOG.debug("  src=%s", src)
        # LOG.debug("  dst=%s", dst)
        # LOG.debug("  old_peer=%s", old_peer)
        if old_peer and old_peer != dst:
            old_link = Link(src, old_peer)
            self.send_event_to_observers(event.EventLinkDelete(old_link))

        link = Link(src, dst)
        if link not in self.links:
            self.send_event_to_observers(event.EventLinkAdd(link))

        if not self.links.update_link(src, dst):
            # reverse link is not detected yet.
            # So schedule the check early because it's very likely it's up
            self.ports.move_front(dst)
            self.lldp_event.set()
        if self.explicit_drop:
            self._drop_packet(msg)
예제 #6
0
    def lldp_packet_in_handler(self, ev):
        if not self.link_discovery:
            return

        msg = ev.msg
        try:
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
        except LLDPPacket.LLDPUnknownFormat:
            # This handler can receive all the packets which can be
            # not-LLDP packet. Ignore it silently
            return

        dst_dpid = msg.datapath.id
        if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
            dst_port_no = msg.in_port
        elif msg.datapath.ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION:
            dst_port_no = msg.match['in_port']
        else:
            LOG.error('cannot accept LLDP. unsupported version. %x',
                      msg.datapath.ofproto.OFP_VERSION)

        src = self._get_port(src_dpid, src_port_no)
        if not src or src.dpid == dst_dpid:
            for links in self.interLinks:
                if src_dpid == int(links.split(',')[0]) and dst_dpid == int(
                        links.split(',')[1]):
                    self.sendCfgMessage()
            tmpStr = str(src_dpid) + ',' + str(dst_dpid) + ',' + str(
                src_port_no) + ',' + str(dst_port_no) + ',' + str(0) + '#'
            self.interLinks.append(tmpStr)
            return
        try:
            self.ports.lldp_received(src)
        except KeyError:
            # There are races between EventOFPPacketIn and
            # EventDPPortAdd. So packet-in event can happend before
            # port add event. In that case key error can happend.
            # LOG.debug('lldp_received error', exc_info=True)
            pass

        dst = self._get_port(dst_dpid, dst_port_no)
        if not dst:
            return

        old_peer = self.links.get_peer(src)
        # LOG.debug("Packet-In")
        # LOG.debug("  src=%s", src)
        # LOG.debug("  dst=%s", dst)
        # LOG.debug("  old_peer=%s", old_peer)
        if old_peer and old_peer != dst:
            old_link = Link(src, old_peer)
            del self.links[old_link]
            self.send_event_to_observers(event.EventLinkDelete(old_link))

        link = Link(src, dst)
        if link not in self.links:
            self.send_event_to_observers(event.EventLinkAdd(link))

            # remove hosts if it's not attached to edge port
            host_to_del = []
            for host in self.hosts.values():
                if not self._is_edge_port(host.port):
                    host_to_del.append(host.mac)

            for host_mac in host_to_del:
                del self.hosts[host_mac]

        if not self.links.update_link(src, dst):
            # reverse link is not detected yet.
            # So schedule the check early because it's very likely it's up
            self.ports.move_front(dst)
            self.lldp_event.set()
        if self.explicit_drop:
            self._drop_packet(msg)
예제 #7
0
    def lldp_packet_in_handler_for_interlink(self, ev):
        LOG.debug("lldp_packet_in_handler_for_interlink")
        if not self.link_discovery:
            LOG.debug(
                "lldp_packet_in_handler_for_interlink:link_discovert flag is false,return"
            )
            return

        msg = ev.msg
        try:
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
        except LLDPPacket.LLDPUnknownFormat as e:
            # This handler can receive all the packets which can be
            # not-LLDP packet. Ignore it silently
            LOG.debug(
                "lldp_packet_in_handler_for_interlink: lldp_parse error:")
            LOG.debug(e)
            return

        dst_dpid = msg.datapath.id
        if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
            dst_port_no = msg.in_port
        elif msg.datapath.ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION:
            dst_port_no = msg.match['in_port']
        else:
            LOG.error('cannot accept LLDP. unsupported version. %x',
                      msg.datapath.ofproto.OFP_VERSION)
        LOG.debug("lldp_packet_in_handler_for_interlink:get dpid")
        src = self._get_port(src_dpid, src_port_no)
        #if src is local handle it in lldp_packet_in_handler
        if src:
            LOG.debug(
                "lldp_packet_in_handler_for_interlink: can find src port ,so its shouldn't be handled as interlink,return"
            )
            return
        dst = self._get_port(dst_dpid, dst_port_no)
        if not dst:
            LOG.debug(
                "lldp_packet_in_handler_for_interlink: can find dst port ,so why cant find dst port in local,fail and return"
            )
            return
        # so now ,src is None, create a src port instance
        #dst_json = json.dumps(dst, default=lambda obj: obj.__dict__)
        src = dst.copy()
        src.dpid = src_dpid
        src.port_no = src_port_no
        # change it to dst
        try:
            LOG.debug(
                "lldp_packet_in_handler_for_interlink: set dst port send count as zero"
            )
            self.ports.lldp_received(dst)
        except KeyError:
            # There are races between EventOFPPacketIn and
            # EventDPPortAdd. So packet-in event can happend before
            # port add event. In that case key error can happend.
            # LOG.debug('lldp_received: KeyError %s', e)
            pass

        old_peer = self.inter_links.get_peer(src)

        # LOG.debug("Packet-In")
        # LOG.debug("  src=%s", src)
        # LOG.debug("  dst=%s", dst)
        # LOG.debug("  old_peer=%s", old_peer)
        if old_peer and old_peer != dst:
            old_link = Link(src, old_peer)
            del self.inter_links[old_link]
            LOG.debug(
                "lldp_packet_in_handler_for_interlink:find a old peer, delete the old link"
            )
            self.send_event_to_observers(event.EventLinkDelete(old_link))
        # hanlde port form other domain,define port_no = dpid:port_no
        # TODO we assume that dpid is unique, if not we shuold extend LLDP to add with cid(controller id)
        LOG.debug("lldp_packet_in_handler_for_interlink:create interlink")
        inter_link = Link(src, dst)

        if inter_link not in self.inter_links:
            LOG.debug("discover inter_link:-----------------")
            LOG.debug(inter_link)
            LOG.debug(
                "lldp_packet_in_handler_for_interlink: send EventLinkAdd to observers"
            )
            self.send_event_to_observers(event.EventLinkAdd(inter_link))
            # remove hosts from edge port
            for host in self.hosts.values():
                if self._is_domain_edge_port(host.port):
                    del self.hosts[host.mac]
                    print "delete host"
                    print host
                    ev = event.EventHostDelete(host)
                    self.send_event_to_observers(ev)
        LOG.debug(
            "lldp_packet_in_handler_for_interlink: update link state time")
        self.inter_links.update_link(src, dst)
        if self.explicit_drop:
            self._drop_packet(msg)
예제 #8
0
    def packet_in_handler(self, ev):
        if not self.link_discovery:
            return

        msg = ev.msg
        dp = msg.datapath
        pkt = packet.Packet(array.array('B', msg.data))
        for p in pkt:
            try:
                p.protocol_name
                #ipv6 bug... TODO
            except:
                return
            if p.protocol_name == 'lldp':
                try:
                    src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
                except LLDPPacket.LLDPUnknownFormat as e:
                    print('lldp miss')
                    # This handler can receive all the packtes which can be
                    # not-LLDP packet. Ignore it silently
                    return
                dst_dpid = msg.datapath.id
                dst_port_no = msg.in_port

                src = self._get_port(src_dpid, src_port_no)
                if not src or src.dpid == dst_dpid:
                    return
                try:
                    self.ports.lldp_received(src)
                except KeyError:
                    # There are races between EventOFPPacketIn and
                    # EventDPPortAdd. So packet-in event can happend before
                    # port add event. In that case key error can happend.
                    # LOG.debug('lldp_received: KeyError %s', e)
                    pass

                self.create_graph_map()
                dst = self._get_port(dst_dpid, dst_port_no)
                if not dst:
                    return
                #graph for spf
                old_peer = self.links.get_peer(src)
                # LOG.debug("Packet-In")
                # LOG.debug("  src=%s", src)
                # LOG.debug("  dst=%s", dst)
                # LOG.debug("  old_peer=%s", old_peer)
                if old_peer and old_peer != dst:
                    old_link = Link(src, old_peer)
                    self.send_event_to_observers(
                        event.EventLinkDelete(old_link))

                link = Link(src, dst)
                if not link in self.links:
                    self.send_event_to_observers(event.EventLinkAdd(link))
                if not self.links.update_link(src, dst):
                    # reverse link is not detected yet.
                    # So schedule the check early because it's very likely it's up
                    self.ports.move_front(dst)
                    self.lldp_event.set()
                if self.explicit_drop:
                    self._drop_packet(msg)
            if p.protocol_name == 'arp':
                #dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)
                dst, src, _eth_type = of_utils.unpack_ethernet(msg.data)
                src_ip_addr = p.src_ip
                dst_ip_addr = p.dst_ip
                src_mac_addr = src
                host_dpid = dp.id
                host_port = msg.in_port
                if (not src_ip_addr in self.arp_table
                        or self.arp_table[src_ip_addr] !=
                    (host_dpid, host_port, src_mac_addr)):
                    self.arp_table[src_ip_addr] = (host_dpid, host_port,
                                                   src_mac_addr)
                    rdb.set('arp_table', json.dumps(self.arp_table))
                    rdb.set('arp_table_pickled', pickle.dumps(self.arp_table))
                if (not src_mac_addr in self.mac_table
                        or self.mac_table[src_mac_addr] !=
                    (host_dpid, host_port)):
                    self.mac_table[src_mac_addr] = (host_dpid, host_port)
                    rdb.set('mac_table', json.dumps(self.mac_table))
                    rdb.set('mac_table_pickled', pickle.dumps(self.mac_table))
                if (dst_ip_addr in self.arp_table):
                    print('response')
                    arp_pkt = self.create_arp_response(src_ip_addr,
                                                       src_mac_addr,
                                                       dst_ip_addr)
                    actions = [dp.ofproto_parser.OFPActionOutput(host_port)]
                    dp.send_packet_out(actions=actions, data=arp_pkt)

                self._drop_packet(msg)
                return
            #testing, everything thru the contoller
            if p.protocol_name == 'ipv4':
                if p.dst in self.arp_table:
                    dip = of_utils.unpack_ipv4(msg.data, of_utils.IPV4_DIP)
                    proto = p.proto
                    dmac = self.arp_table[p.dst][2]
                    sport = msg.in_port
                    if self.arp_table[p.dst][0] == dp.id:
                        print('same sw')
                        dport = self.arp_table[p.dst][1]
                        self.install_flow_dmac(dp, sport, dport, dmac)
                        #self._drop_packet(msg)
                        self.controller_send(dp, dport, msg.data)
                        return
                    dst_dpid = self.arp_table[p.dst][0]
                    dst_dp = self.dps[dst_dpid]
                    dst_port = self.arp_table[p.dst][1]
                    met, topo, topo_ecmp = NetGraph.SrcDst_SPF_ECMP(
                        self.graph_map, dp.id, dst_dpid)
                    print(topo)
                    print(topo_ecmp)
                    cntr = len(topo)
                    prev_node = dp
                    while cntr >= 1:
                        dport = self.graph_ports[prev_node.id][topo[cntr]]
                        #                        self.install_flow_dmac(prev_node,sport,dport,dmac)
                        self.install_flow_dip(prev_node, sport, dport, dip)
                        sport = self.graph_ports[topo[cntr]][prev_node.id]
                        prev_node = self.dps[topo[cntr]]
                        cntr -= 1
                    #self.install_flow_dmac(prev_node,sport,self.mac_table[dmac][1],dmac)
                    self.install_flow_dip(prev_node, sport,
                                          self.arp_table[p.dst][1], dip)
                    print(p)
                    #self._drop_packet(msg)
                    self.controller_send(dst_dp, dst_port, msg.data)
                self._drop_packet(msg)
                return
            if (p.protocol_name != 'arp' and p.protocol_name != 'lldp'
                    and p.protocol_name != 'ethernet'):
                print(p)
예제 #9
0
    def packet_in_handler(self, ev):
        if not self.link_discovery:
            return

        #print 123111111111
        msg = ev.msg
        #print 'msg: ',msg.__dict__
        try:
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
        except LLDPPacket.LLDPUnknownFormat as e:
            # This handler can receive all the packtes which can be
            # not-LLDP packet. Ignore it silently
            return

        dst_dpid = msg.datapath.id
        if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
            dst_port_no = msg.in_port
        elif msg.datapath.ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION:
            dst_port_no = msg.match['in_port']
        else:
            LOG.error('cannot accept LLDP. unsupported version. %x',
                      msg.datapath.ofproto.OFP_VERSION)

        src = self._get_port(src_dpid, src_port_no)
        # print 'src: ',src.__dict__
        # print 'type: ',type(src)

        #linshixiugai
        if not src:
            if self._get_port(517, 26):
                src = self._get_port(517, 26)
            if self._get_port(770, 8):
                src = self._get_port(770, 8)
            src.dpid = src_dpid
            src.port_no = src_port_no
            src.name = 'ge-1/1/' + str(src_port_no)

        #this need to be improved,because LLDP from another domain can only be parsered to
        #dpid and portNo ,other information ,such as name,can't be parsered.So we can only
        #made this port by ourselves,not by program.
        #print src.__dict__
        if src.dpid == dst_dpid:
            return

        # if src_dpid not in self.dps:
        #     src = Port(src_dpid, None, None)
        #     src.port_no = src_port_no
        # else:
        #     src = self._get_port(src_dpid, src_port_no)

        try:
            self.ports.lldp_received(src)
        except KeyError:
            # There are races between EventOFPPacketIn and
            # EventDPPortAdd. So packet-in event can happend before
            # port add event. In that case key error can happend.
            # LOG.debug('lldp_received: KeyError %s', e)
            pass

        dst = self._get_port(dst_dpid, dst_port_no)
        if not dst:
            return

        old_peer = self.links.get_peer(src)
        # LOG.debug("Packet-In")
        # LOG.debug("  src=%s", src)
        # LOG.debug("  dst=%s", dst)
        # LOG.debug("  old_peer=%s", old_peer)
        #print 'src,dst,old_peer: ',src,dst,old_peer
        if old_peer and old_peer != dst:
            old_link = Link(src, old_peer)
            #print 333333
            self.send_event_to_observers(event.EventLinkDelete(old_link))

        link = Link(src, dst)
        if link not in self.links:
            self.send_event_to_observers(event.EventLinkAdd(link))

        if not self.links.update_link(src, dst):
            # reverse link is not detected yet.
            # So schedule the check early because it's very likely it's up
            self.ports.move_front(dst)
            self.lldp_event.set()
        if self.explicit_drop:
            self._drop_packet(msg)