コード例 #1
0
ファイル: switches.py プロジェクト: ruicao93/ryu-cluster
    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
ファイル: dhcps.py プロジェクト: xixi2/ryu_sdn
 def host_check(self):
     # while self.is_active:
     #     self.check_event.clear()
     for m in list(self.ip_pool.keys()):
         if time.perf_counter() - self.ip_pool[m][1] > 30:
             #print(time.perf_counter(), self.ip_pool[m][2])
             id = int(self.ip_pool[m][0].split('.')[-1])
             #print(m, str(self.mac_port[m][0])+":"+str(self.mac_port[m][1]))
             h = switches.Host(
                 m,
                 str(self.mac_port[m][0]) + ":" + str(self.mac_port[m][1]))
             h.ipv4.append(self.ip_pool[m][0])
             self.send_event_to_observers(event.EventHostDelete(h))
             del self.ip_pool[m]
             del self.mac_port[m]
             self.usable_id.append(id)
コード例 #3
0
ファイル: switches.py プロジェクト: uozbek/OpenADM
    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 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:
            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)
            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 from edge port
            for host in self.hosts.values():
                if not self._is_edge_port(host.port):
                    ev = event.EventHostDelete(host)
                    self.send_event_to_observers(ev)
                    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)
コード例 #4
0
ファイル: switches.py プロジェクト: uozbek/OpenADM
    def port_status_handler(self, ev):
        msg = ev.msg
        reason = msg.reason
        dp = msg.datapath
        ofpport = msg.desc

        if reason == dp.ofproto.OFPPR_ADD:
            # LOG.debug('A port was added.' +
            #           '(datapath id = %s, port number = %s)',
            #           dp.id, ofpport.port_no)
            self.port_state[dp.id].add(ofpport.port_no, ofpport)
            self.send_event_to_observers(
                event.EventPortAdd(Port(dp.id, dp.ofproto, ofpport)))

            if not self.link_discovery:
                return

            port = self._get_port(dp.id, ofpport.port_no)
            if port and not port.is_reserved():
                self._port_added(port)
                self.lldp_event.set()

        elif reason == dp.ofproto.OFPPR_DELETE:
            # LOG.debug('A port was deleted.' +
            #           '(datapath id = %s, port number = %s)',
            #           dp.id, ofpport.port_no)
            self.port_state[dp.id].remove(ofpport.port_no)
            self.send_event_to_observers(
                event.EventPortDelete(Port(dp.id, dp.ofproto, ofpport)))

            if not self.link_discovery:
                return

            port = self._get_port(dp.id, ofpport.port_no)
            if port and not port.is_reserved():
                # if port delete
                # then delete host on it
                for host in self.hosts.values():
                    if port.__eq__(host.port):
                        ev = event.EventHostDelete(host)
                        self.send_event_to_observers(ev)
                        del self.hosts[host.mac]
                        break
                self.ports.del_port(port)
                self._link_down(port)
                self.lldp_event.set()

        else:
            assert reason == dp.ofproto.OFPPR_MODIFY
            # LOG.debug('A port was modified.' +
            #           '(datapath id = %s, port number = %s)',
            #           dp.id, ofpport.port_no)
            self.port_state[dp.id].modify(ofpport.port_no, ofpport)
            self.send_event_to_observers(
                event.EventPortModify(Port(dp.id, dp.ofproto, ofpport)))

            if not self.link_discovery:
                return

            port = self._get_port(dp.id, ofpport.port_no)
            if port and not port.is_reserved():
                if self.ports.set_down(port):
                    # if port down
                    # then delete host on it
                    for host in self.hosts.values():
                        if port.__eq__(host.port):
                            ev = event.EventHostDelete(host)
                            self.send_event_to_observers(ev)
                            del self.hosts[host.mac]
                            break
                    self._link_down(port)
                self.lldp_event.set()
コード例 #5
0
ファイル: switches.py プロジェクト: uozbek/OpenADM
    def state_change_handler(self, ev):
        dp = ev.datapath
        assert dp is not None
        LOG.debug(dp)

        if ev.state == MAIN_DISPATCHER:
            dp_multiple_conns = False
            if dp.id in self.dps:
                LOG.warning('Multiple connections from %s', dpid_to_str(dp.id))
                dp_multiple_conns = True
                (self.dps[dp.id]).close()

            self._register(dp)
            switch = self._get_switch(dp.id)
            LOG.debug('register %s', switch)

            if not dp_multiple_conns:
                self.send_event_to_observers(event.EventSwitchEnter(switch))
            else:
                self.send_event_to_observers(
                    event.EventSwitchReconnected(switch))

            if not self.link_discovery:
                return

            if self.install_flow:
                ofproto = dp.ofproto
                ofproto_parser = dp.ofproto_parser

                # TODO:XXX need other versions
                if ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
                    rule = nx_match.ClsRule()
                    rule.set_dl_dst(
                        addrconv.mac.text_to_bin(lldp.LLDP_MAC_NEAREST_BRIDGE))
                    rule.set_dl_type(ETH_TYPE_LLDP)
                    actions = [
                        ofproto_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                                       self.LLDP_PACKET_LEN)
                    ]
                    dp.send_flow_mod(rule=rule,
                                     cookie=0,
                                     command=ofproto.OFPFC_ADD,
                                     idle_timeout=0,
                                     hard_timeout=0,
                                     actions=actions,
                                     priority=0xFFFF)
                elif ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION:
                    match = ofproto_parser.OFPMatch(
                        eth_type=ETH_TYPE_LLDP,
                        eth_dst=lldp.LLDP_MAC_NEAREST_BRIDGE)
                    # OFPCML_NO_BUFFER is set so that the LLDP is not
                    # buffered on switch
                    parser = ofproto_parser
                    actions = [
                        parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                               ofproto.OFPCML_NO_BUFFER)
                    ]
                    inst = [
                        parser.OFPInstructionActions(
                            ofproto.OFPIT_APPLY_ACTIONS, actions)
                    ]
                    mod = parser.OFPFlowMod(datapath=dp,
                                            match=match,
                                            idle_timeout=0,
                                            hard_timeout=0,
                                            instructions=inst,
                                            priority=0xFFFF)
                    dp.send_msg(mod)
                else:
                    LOG.error('cannot install flow. unsupported version. %x',
                              dp.ofproto.OFP_VERSION)

            # Do not add ports while dp has multiple connections to controller.
            if not dp_multiple_conns:
                for port in switch.ports:
                    if not port.is_reserved():
                        self._port_added(port)

            self.lldp_event.set()

        elif ev.state == DEAD_DISPATCHER:
            # dp.id is None when datapath dies before handshake
            if dp.id is None:
                return

            # if switch delete
            # then delete host on it
            hostlist = self.hosts.get_by_dpid(dp.id)
            for host in hostlist:
                ev = event.EventHostDelete(host)
                self.send_event_to_observers(ev)
                del self.hosts[host.mac]

            switch = self._get_switch(dp.id)
            if switch:
                if switch.dp is dp:
                    self._unregister(dp)
                    LOG.debug('unregister %s', switch)

                    self.send_event_to_observers(
                        event.EventSwitchLeave(switch))

                    if not self.link_discovery:
                        return

                    for port in switch.ports:
                        if not port.is_reserved():
                            self.ports.del_port(port)
                            self._link_down(port)
                    self.lldp_event.set()
コード例 #6
0
ファイル: switches.py プロジェクト: ruicao93/ryu-cluster
    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)
コード例 #7
0
ファイル: switches.py プロジェクト: ruicao93/ryu-cluster
    def host_discovery_packet_in_handler(self, ev):
        msg = ev.msg
        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        # ignore lldp packet
        if eth.ethertype == ETH_TYPE_LLDP:
            return

        datapath = msg.datapath
        dpid = datapath.id
        port_no = -1

        if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
            port_no = msg.in_port
        else:
            port_no = msg.match['in_port']

        port = self._get_port(dpid, port_no)
        host_mac = eth.src

        # can't find this port(ex: logic port)
        if not port:
            return
        # ignore switch-to-switch port
        if not self._is_edge_port(port):
            #print "host in edge: <%d,%d>" % (dpid,port_no)
            local_host = self.hosts.get(host_mac)
            if local_host:
                del self.hosts[host_mac]
                ev = event.EventHostDelete(local_host)
                self.send_event_to_observers(ev)
                print "delete host"
            return
        if self._is_domain_edge_port(port):
            #print "host in domain edge: <%d,%d>" % (dpid,port_no)
            local_host = self.hosts.get(host_mac)
            if local_host:
                del self.hosts[host_mac]
                ev = event.EventHostDelete(local_host)
                self.send_event_to_observers(ev)
                print "delete host"
            return

        host = Host(host_mac, port)

        if host_mac not in self.hosts:
            self.hosts.add(host)
            ev = event.EventHostAdd(host)
            self.send_event_to_observers(ev)

        # arp packet, update ip address
        if eth.ethertype == ether_types.ETH_TYPE_ARP:
            arp_pkt = pkt.get_protocols(arp.arp)[0]
            self.hosts.update_ip(host, ip_v4=arp_pkt.src_ip)
            update_host = self.hosts[host.mac]
            uev = event.EventHostAdd(update_host)
            self.send_event_to_observers(uev)

        # ipv4 packet, update ipv4 address
        elif eth.ethertype == ether_types.ETH_TYPE_IP:
            ipv4_pkt = pkt.get_protocols(ipv4.ipv4)[0]
            self.hosts.update_ip(host, ip_v4=ipv4_pkt.src)
            update_host = self.hosts[host.mac]
            uev = event.EventHostAdd(update_host)
            self.send_event_to_observers(uev)

        # ipv6 packet, update ipv6 addressE
        elif eth.ethertype == ether_types.ETH_TYPE_IPV6:
            # TODO: need to handle NDP
            ipv6_pkt = pkt.get_protocols(ipv6.ipv6)[0]
            self.hosts.update_ip(host, ip_v6=ipv6_pkt.src)
            update_host = self.hosts[host.mac]
            uev = event.EventHostAdd(update_host)
            self.send_event_to_observers(uev)