def _packet_in_handler(self, ev):
        msg = ev.msg
        pkt = packet.Packet(msg.data)

        pkt_ethernet = pkt.get_protocols(ethernet.ethernet)[0]
        datapath = msg.datapath
        port = msg.match['in_port']

        # Checking if it's the probe packet for RTT estimation
        if pkt_ethernet.ethertype == self.PROBE_ETHERTYPE:
            self.probe_packet_handler(pkt)
            return

        # Ignoring LLDP Packets
        try:
            LLDPPacket.lldp_parse(msg.data)
            self.logger.debug('Received LLDP Packet')
            return
        except:
            pass

        self.logger.debug('EventOFPPacketIn %s' % pkt)

        # Handling ARP
        pkt_arp = pkt.get_protocol(arp.arp)
        if pkt_arp:
            self._handle_arp(msg, datapath, port, pkt, pkt_arp)
            return

        pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
        pkt_icmp = pkt.get_protocol(icmp.icmp)

        # Handling ICMPv4
        if pkt_icmp:
            self._handle_icmpv4(
                msg, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp)
            return

        # Handing IPv4
        if pkt_ipv4:
            self._handle_ipv4(datapath, port, pkt_ethernet, pkt_ipv4)
            return

        pkt_ipv6 = pkt.get_protocol(ipv6.ipv6)
        pkt_icmp = pkt.get_protocol(icmpv6.icmpv6)

        # Handling ICMPv6
        if pkt_icmp:
            self._handle_icmpv6(
                datapath, port, pkt_ethernet, pkt_ipv6, pkt_icmp)
            return

        # Handing IPv6
        if pkt_ipv4:
            self._handle_ipv6(datapath, port, pkt_ethernet, pkt_ipv4)
            return

        # Unhandled
        self.logger.debug('Unknown packet %s' % str(pkt))
Ejemplo n.º 2
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        pkt = packet.Packet(msg.data)

        pkt_ethernet = pkt.get_protocols(ethernet.ethernet)[0]
        datapath = msg.datapath
        port = msg.match['in_port']

        # Checking if it's the probe packet for RTT estimation
        if pkt_ethernet.ethertype == self.PROBE_ETHERTYPE:
            self.probe_packet_handler(pkt)
            return

        # Ignoring LLDP Packets
        try:
            LLDPPacket.lldp_parse(msg.data)
            self.logger.debug('Received LLDP Packet')
            return
        except:
            pass

        self.logger.debug('EventOFPPacketIn %s' % pkt)

        # Handling ARP
        pkt_arp = pkt.get_protocol(arp.arp)
        if pkt_arp:
            self._handle_arp(msg, datapath, port, pkt, pkt_arp)
            return

        pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
        pkt_icmp = pkt.get_protocol(icmp.icmp)

        # Handling ICMPv4
        if pkt_icmp:
            self._handle_icmpv4(msg, datapath, port, pkt_ethernet, pkt_ipv4,
                                pkt_icmp)
            return

        # Handing IPv4
        if pkt_ipv4:
            self._handle_ipv4(datapath, port, pkt_ethernet, pkt_ipv4)
            return

        pkt_ipv6 = pkt.get_protocol(ipv6.ipv6)
        pkt_icmp = pkt.get_protocol(icmpv6.icmpv6)

        # Handling ICMPv6
        if pkt_icmp:
            self._handle_icmpv6(datapath, port, pkt_ethernet, pkt_ipv6,
                                pkt_icmp)
            return

        # Handing IPv6
        if pkt_ipv4:
            self._handle_ipv6(datapath, port, pkt_ethernet, pkt_ipv4)
            return

        # Unhandled
        self.logger.debug('Unknown packet %s' % str(pkt))
Ejemplo n.º 3
0
    def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg

        try:
            # ignore lldp packet
            LLDPPacket.lldp_parse(msg.data)
            return
        except LLDPPacket.LLDPUnknownFormat:
            pass
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        dst = eth.dst
        src = eth.src

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
            # verify if we have a valid buffer_id, if yes avoid to send both
            # flow_mod & packet_out
            if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                self.add_flow(datapath, 1, match, actions, msg.buffer_id)
                return
            else:
                self.add_flow(datapath, 1, match, actions)
        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
                                  in_port=in_port, actions=actions, data=data)
        datapath.send_msg(out)
Ejemplo n.º 4
0
    def packet_in_handler(self, ev):

        """

            Parsing LLDP packet and get the delay of link.

        """

        msg = ev.msg

        try:

            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)

            dpid = msg.datapath.id

            if self.sw_module is None:

                self.sw_module = lookup_service_brick('switches')



            for port in self.sw_module.ports.keys():

                if src_dpid == port.dpid and src_port_no == port.port_no:

                    delay = self.sw_module.ports[port].delay

                    self._save_lldp_delay(src=src_dpid, dst=dpid,

                                          lldpdelay=delay)

        except LLDPPacket.LLDPUnknownFormat as e:

            return
Ejemplo n.º 5
0
Archivo: c.py Proyecto: yyzhou94/Ryu
    def packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath

        try:
            #LLDP handler
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
            dst_dpid, dst_port_no = datapath.id, msg.match['in_port']
            self.add_topo(src_dpid, dst_dpid, src_port_no, dst_port_no)
            link = api.get_link(self)
            print self.topo
            for i in link:
                src = i.src
                dst = i.dst
                self.topo[(src.dpid, dst.dpid)] = (src.port_no, dst.port_no)

        except LLDPPacket.LLDPUnknownFormat:
            ofproto = datapath.ofproto
            parser = datapath.ofproto_parser
            pkt = packet.Packet(msg.data)
            eth = pkt.get_protocols(ethernet.ethernet)[0]
            mac = eth.src
            dpid, port = datapath.id, msg.match['in_port']
            actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)]
            data = None
            if msg.buffer_id == ofproto.OFP_NO_BUFFER:
                data = msg.data
            out = parser.OFPPacketOut(datapath=datapath,
                                      buffer_id=msg.buffer_id,
                                      in_port=port,
                                      actions=actions,
                                      data=data)
            datapath.send_msg(out)
Ejemplo n.º 6
0
    def packet_in_handler(self, ev):
        """
                      Controller
                    |        /|\    
                   \|/         |
                Switch----->Switch
        """
        msg = ev.msg
        try:
            src_dpid, src_outport = LLDPPacket.lldp_parse(msg.data)
            dst_dpid = msg.datapath.id
            dst_inport = msg.match['in_port']
            if self.switches is None:
                self.switches = lookup_service_brick("switches")

            for port in self.switches.ports.keys():
                if src_dpid == port.dpid and src_outport == port.port_no:
                    port_data = self.switches.ports[port]
                    timestamp = port_data.timestamp
                    if timestamp:
                        delay = time.time() - timestamp
                        self._save_delay_data(src=src_dpid,
                                              dst=dst_dpid,
                                              src_port=src_outport,
                                              lldpdealy=delay)
        except:
            return
Ejemplo n.º 7
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        try:
            # ignore lldp packet
            LLDPPacket.lldp_parse(msg.data)
            return
        except LLDPPacket.LLDPUnknownFormat:
            pass
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match["in_port"]

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        dst = eth.dst
        src = eth.src

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
            self.add_flow(datapath, 1, match, actions)

        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(
            datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data
        )
        datapath.send_msg(out)
Ejemplo n.º 8
0
    def _packet_in_handler(self, ev):
        """Handle packet_in events."""
        if not self.link_discovery:
            return
        msg = ev.msg
        in_port = msg.match['in_port']
        packet = Packet(msg.data)
        efm = packet.get_protocol(ethernet.ethernet)
        if efm.ethertype == ether.ETH_TYPE_ARP:
            self.send_event_to_observers(event.EventArpReceived(ev))

        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
        else:
            dst_dpid = msg.datapath.id
            dst_port_no = in_port

            src = self._get_port(src_dpid, src_port_no)
            if not src or src.dpid == dst_dpid:
                return

            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 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
                try:
                    self.ports.lldp_received(dst)
                except KeyError as e:
                    # 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
                else:
                    self.ports.move_front(dst)
                    self.lldp_event.set()
Ejemplo n.º 9
0
    def _packet_in_handler(self, ev):
        """Handle packet_in events."""
        if not self.link_discovery:
            return
        msg = ev.msg
        in_port = msg.match['in_port']
        packet = Packet(msg.data)
        efm = packet.next()
        if efm.ethertype == ether.ETH_TYPE_ARP:
            self.send_event_to_observers(event.EventArpReceived(ev))

        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
        else:
            dst_dpid = msg.datapath.id
            dst_port_no = in_port

            src = self._get_port(src_dpid, src_port_no)
            if not src or src.dpid == dst_dpid:
                return

            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 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
                try:
                    self.ports.lldp_received(dst)
                except KeyError as e:
                    # 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
                else:
                    self.ports.move_front(dst)
                    self.lldp_event.set()
Ejemplo n.º 10
0
    def _packet_in_handler(self, ev):
        try:
            msg = ev.msg
            LLDPPacket.lldp_parse(msg.data)
            return
        except LLDPPacket.LLDPUnknownFormat:
            # it's host
            dpid = msg.datapath.id
            port = -1

            if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
                port = msg.in_port
            elif msg.datapath.ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION:
                port = msg.match['in_port']

            if port >= 1024:
                # hack: ignore some strange port
                return

            # ignore global host
            for link in self.cross_domain_links:

                if link['src']['dpid'] == dpid and \
                   link['src']['port'] == port:
                    return

            # TODO, check again if host already in global port

            pkt = packet.Packet(msg.data)
            eth = pkt.get_protocols(ethernet.ethernet)[0]
            mac = eth.src

            if mac not in self.hosts and port != -1 and \
                not self._host_exist_in_port(dpid, port) and \
                    not self._is_switch_port_to_port(dpid, port):
                LOG.debug('Add host %s to %d:%d', mac, dpid, port)
                self.hosts[mac] = (dpid, port)
                self.response_host(mac)
                ev = EventHostDiscovery(dpid, port, mac)
                self.send_event_to_observers(ev)
Ejemplo n.º 11
0
    def _packet_in_handler(self, ev):
        try:
            msg = ev.msg
            LLDPPacket.lldp_parse(msg.data)
            return
        except LLDPPacket.LLDPUnknownFormat:
            # it's host
            dpid = msg.datapath.id
            port = -1

            if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
                port = msg.in_port
            elif msg.datapath.ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION:
                port = msg.match['in_port']

            if port >= 1024:
                # hack: ignore some strange port
                return

            # ignore global host
            for link in self.cross_domain_links:

                if link['src']['dpid'] == dpid and \
                    link['src']['port'] == port:
                    return

            # TODO, check again if host already in global port

            pkt = packet.Packet(msg.data)
            eth = pkt.get_protocols(ethernet.ethernet)[0]
            mac = eth.src

            if mac not in self.hosts and port != -1 and \
                not self._host_exist_in_port(dpid, port) and \
                not self._is_switch_port_to_port(dpid, port):
                LOG.debug('Add host %s to %d:%d', mac, dpid, port)
                self.hosts[mac] = (dpid, port)
                self.response_host(mac)
                ev = EventHostDiscovery(dpid, port, mac)
                self.send_event_to_observers(ev)
Ejemplo n.º 12
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        # get Datapath ID to identify OpenFlow switches.
        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        # analyse the received packets using the packet library.
        pkt = packet.Packet(msg.data)
        eth_pkt = pkt.get_protocol(ethernet.ethernet)
        dst = eth_pkt.dst
        src = eth_pkt.src

        # get the received port number from packet_in message.
        in_port = msg.match['in_port']

        if eth_pkt.ethertype == ether_types.ETH_TYPE_LLDP:
            print LLDPPacket.lldp_parse(msg.data)
            self.logger.info("packet in %s %s %s %s %x", dpid, src, dst,
                             in_port, eth_pkt.ethertype)
Ejemplo n.º 13
0
    def handle_lldp_packet(self, ev):
        msg = ev.msg
        try:
            src_dpid, src_port_no, timestamp = LLDPPacket.lldp_parse(msg.data)
            dpid = msg.datapath.id
            if self.sw_module is None:
                self.sw_module = lookup_service_brick('switches')

            for port in self.sw_module.ports.keys():
                if src_dpid == port.dpid and src_port_no == port.port_no:
                    delay = self.sw_module.ports[port].delay
                    self.graph[src_dpid][dpid]['lldpdelay'] = delay

        except LLDPPacket.LLDPUnknownFormat as e:
            return
Ejemplo n.º 14
0
    def packet_in_hander(self, ev):
        msg = ev.msg
        dpid = msg.datapath.id
        try:
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)

            if self.switches is None:
                self.switches = lookup_service_brick('switches')

            for port in self.switches.ports.keys():
                if src_dpid == port.dpid and src_port_no == port.port_no:
                    self.lldp_delay[(src_dpid,
                                     dpid)] = self.switches.ports[port].delay
        except:
            return
Ejemplo n.º 15
0
    def packet_in_handler(self, ev):
        """
            Parsing LLDP packet and get the delay of link.
        """
        msg = ev.msg
        try:
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
            dpid = msg.datapath.id
            if self.sw_module is None:
                self.sw_module = lookup_service_brick('switches')

            for port in self.sw_module.ports.keys():
                if src_dpid == port.dpid and src_port_no == port.port_no:
                    delay = self.sw_module.ports[port].delay
                    self._save_lldp_delay(src=src_dpid, dst=dpid,
                                          lldpdelay=delay)
        except LLDPPacket.LLDPUnknownFormat as e:
            return
Ejemplo n.º 16
0
    def packet_in_handler(self, ev):
        self._logger.debug('Packet in')
        msg = ev.msg
        ofp = msg.datapath.ofproto
        pkt = packet.Packet(msg.data)
        headers = dict((p.protocol_name, p)
                       for p in pkt.protocols if type(p) != str)
        src_mac = headers[ETHERNET].src
        try:
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
        except LLDPPacket.LLDPUnknownFormat as e:
            self._logger.debug('LLDPUnknownFormat %s', e)
            return
        dst_port_no = self.ofctl.get_packet_in_inport(msg)
        dst = self._get_port(dst_port_no)
        self._logger.debug('LLDP from %d.%d -> %d',
                           src_dpid,
                           src_port_no,
                           dst_port_no)
        if not dst:
            self._logger.warning('Dst not found.')
            return
        self.ports.lldp_received(dst)
        src = Port(PortData(src_dpid, port_no=src_port_no, hw_addr=src_mac))
        old_peer = self.links.get_peer(dst)
        need_update = False
        if old_peer and old_peer != src:
            self._logger.info('Peer changed.')
            self._report_link_deleted(Link(old_peer, dst))
            need_update = True
        link = Link(src, dst)
        if link not in self.links:
            need_update = True
            self._report_link_added(Link(src, dst))
            self.lldp_event.set()

        # Always return false, since we don't have the reverse link information
        if need_update:
            self.links.update_link(src, dst)
            self._logger.info('Update link %d.%d -> %d.%d',
                              src.dpid,
                              src.port_no,
                              dst.dpid,
                              dst.port_no)
Ejemplo n.º 17
0
    def packet_in_handler(self, ev):
        msg = ev.msg
        try:
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
            dpid = msg.datapath.id
            in_port = msg.match['in_port']
            if self.sw_module is None:
                self.sw_module = lookup_service_brick('switches')

            for port in self.sw_module.ports.keys():
                if src_dpid == port.dpid and src_port_no == port.port_no:
                    port_data = self.sw_module.ports[port]
                    timestamp = port_data.timestamp
                    if timestamp:
                        delay = time.time() - timestamp
                        self._save_lldp_delay(src=src_dpid, dst=dpid,
                                              lldpdelay=delay)
        except LLDPPacket.LLDPUnknownFormat as e:
            return
Ejemplo n.º 18
0
    def packet_in_handler(self, ev):
        msg = ev.msg
        try:
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
            dpid = msg.datapath.id
            in_port = msg.match['in_port']
            if self.sw_module is None:
                self.sw_module = lookup_service_brick('switches')

            for port in self.sw_module.ports.keys():
                if src_dpid == port.dpid and src_port_no == port.port_no:
                    port_data = self.sw_module.ports[port]
                    timestamp = port_data.timestamp
                    if timestamp:
                        delay = time.time() - timestamp
                        self._save_lldp_delay(src=src_dpid,
                                              dst=dpid,
                                              lldpdelay=delay)
        except LLDPPacket.LLDPUnknownFormat as e:
            return
Ejemplo n.º 19
0
    def packet_in_handler(self, ev):
        msg = ev.msg
        dp = msg.datapath
        ofp = dp.ofproto
        ofp_parser = dp.ofproto_parser

        port = msg.match['in_port']

        ## parses the packet
        pkt = packet.Packet(data=msg.data)
        # ethernet
        pkt_ethernet = pkt.get_protocol(ethernet.ethernet)

        if not pkt_ethernet:
            return

        # 當為LLDP packet時,把lldpdelay資料取出來
        if pkt_ethernet.ethertype == 35020:
            try:
                src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
                dst_dpid = msg.datapath.id
                if self.switch_mod is None:
                    self.switch_mod = lookup_service_brick('switches')

                for port in self.switch_mod.ports.keys():
                    if src_dpid == port.dpid and src_port_no == port.port_no:
                        lldpdelay = self.switch_mod.ports[port].delay
                        self.net[src_dpid][dst_dpid]["lldpdelay"] = lldpdelay
            except LLDPPacket.LLDPUnknownFormat as e:
                return

        if msg.buffer_id == ofp.OFP_NO_BUFFER:
            data = msg.data

        # arp封包处理
        if pkt_ethernet.dst == 'ff:ff:ff:ff:ff:ff':
            if self.mac_learning(dp, pkt_ethernet.src,
                                 port) is False:  #判断是否会造成广播风暴,False代表為是會造成
                out_port = ofp.OFPPC_NO_RECV  #将封包丢掉
            else:
                out_port = ofp.OFPP_FLOOD  #做flooding
                if not self.net.has_node(
                        pkt_ethernet.src):  #若arp封包源沒有包含在圖裡面,則將它加入進圖中
                    self.net.add_node(pkt_ethernet.src)
                    self.net.add_edge(pkt_ethernet.src,
                                      dp.id,
                                      bw=0,
                                      delay=0,
                                      lldpdelay=0)  #添加雙向的邊
                    self.net.add_edge(dp.id,
                                      pkt_ethernet.src,
                                      port=port,
                                      bw=0,
                                      delay=0,
                                      lldpdelay=0)
                    self.idport_to_id.update({(dp.id, port): pkt_ethernet.src})
                    print(self.idport_to_id)
                    print(self.net.nodes())
                    print(self.net.edges())

            actions = [ofp_parser.OFPActionOutput(out_port)]
            #inst = [actions]
            out = ofp_parser.OFPPacketOut(datapath=dp,
                                          buffer_id=msg.buffer_id,
                                          in_port=port,
                                          actions=actions,
                                          data=data)
            dp.send_msg(out)
            return

        if pkt_ethernet.ethertype != 34525 and pkt_ethernet.ethertype != 35020:
            if not self.net.has_node(pkt_ethernet.src):  #如果不在图里则新增
                print("add %s in self.net" % pkt_ethernet.src)
                #print(pkt_ethernet.ethertype)
                self.net.add_node(pkt_ethernet.src)
                self.net.add_edge(pkt_ethernet.src,
                                  dp.id,
                                  bw=0,
                                  delay=0,
                                  lldpdelay=0)
                #self.net.add_edge(dp.id, pkt_ethernet.src, {'port':port})
                self.net.add_edge(dp.id,
                                  pkt_ethernet.src,
                                  port=port,
                                  bw=0,
                                  delay=0,
                                  lldpdelay=0)
                self.idport_to_id.update({(dp.id, port): pkt_ethernet.src})
                print(self.idport_to_id)
                print(self.net.nodes())
                print(self.net.edges.data())

        if self.net.has_node(pkt_ethernet.dst):
            print("%s in self.net" % pkt_ethernet.dst)
            path = nx.dijkstra_path(self.net,
                                    pkt_ethernet.src,
                                    pkt_ethernet.dst,
                                    weight='bw')  #以当前bw作最短路徑轉發
            next_match = ofp_parser.OFPMatch(eth_dst=pkt_ethernet.dst,
                                             eth_src=pkt_ethernet.src)
            back_match = ofp_parser.OFPMatch(eth_dst=pkt_ethernet.src,
                                             eth_src=pkt_ethernet.dst)
            print(path)
            #依照計算后算出的路徑下發流表
            for on_path_switch in range(1, len(path) - 1):
                now_switch = path[on_path_switch]  #这里需要知道現在,之前以及之後的switch
                next_switch = path[on_path_switch + 1]
                back_switch = path[on_path_switch - 1]
                next_port = self.net[now_switch][next_switch]['port']
                back_port = self.net[now_switch][back_switch]['port']
                action = ofp_parser.OFPInstructionActions(
                    ofp.OFPIT_APPLY_ACTIONS,
                    [ofp_parser.OFPActionOutput(next_port)])
                inst = [action]
                self.add_flow(dp=self.switch_map[now_switch],
                              match=next_match,
                              inst=inst,
                              table=0,
                              idle_timeout=5)

                action = ofp_parser.OFPInstructionActions(
                    ofp.OFPIT_APPLY_ACTIONS,
                    [ofp_parser.OFPActionOutput(back_port)])
                inst = [action]
                self.add_flow(dp=self.switch_map[now_switch],
                              match=back_match,
                              inst=inst,
                              table=0,
                              idle_timeout=5)
                print("now switch:%s" % now_switch)

            now_switch = path[1]
            next_switch = path[2]
            out_port = self.net[now_switch][next_switch]['port']
            actions = [ofp_parser.OFPActionOutput(out_port)]
            out = ofp_parser.OFPPacketOut(datapath=dp,
                                          buffer_id=msg.buffer_id,
                                          in_port=port,
                                          actions=actions,
                                          data=data)
            dp.send_msg(out)
        else:
            return
Ejemplo n.º 20
0
    def packet_in_handler(self, ev):
        msg = ev.msg
        dp = msg.datapath
        ofp = dp.ofproto
        parser = dp.ofproto_parser
        dpid = dp.id
        in_port = msg.match['in_port']
        pkt = packet.Packet(msg.data)

        eth_pkt = pkt.get_protocols(ethernet.ethernet)[0]
        dst_mac = eth_pkt.dst
        src_mac = eth_pkt.src

        if eth_pkt.ethertype == ether_types.ETH_TYPE_LLDP:
            try:
                src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
                if self.switches is None:
                    self.switches = lookup_service_brick('switches')
                for port in self.switches.ports.keys():
                    if src_dpid == port.dpid and src_port_no == port.port_no:
                        self.lldp_delay[(
                            src_dpid, dpid)] = self.switches.ports[port].delay
            except:
                return
            return
        if eth_pkt.ethertype == ether_types.ETH_TYPE_IPV6:
            return

        if src_mac not in self.graph:
            self.graph.add_node(src_mac)
            self.graph.add_edge(src_mac, dpid, weight=0)
            self.graph.add_edge(dpid, src_mac, weight=0, port=in_port)

        header_list = dict(
            (p.protocol_name, p) for p in pkt.protocols if type(p) != str)

        if dst_mac == ETHERNET_MULTICAST and ARP in header_list:
            arp_dst_ip = header_list[ARP].dst_ip
            if (dpid, src_mac, arp_dst_ip) in self.sw:
                if self.sw[(dpid, src_mac, arp_dst_ip)] != in_port:
                    out = parser.OFPPacketOut(datapath=dp,
                                              buffer_id=ofp.OFP_NO_BUFFER,
                                              in_port=in_port,
                                              actions=[],
                                              data=None)
                    dp.send_msg(out)
                    return
            else:
                self.sw[(dpid, src_mac, arp_dst_ip)] = in_port

        # mac learning
        self.mac_to_port.setdefault(dpid, {})
        self.paths.setdefault(src_mac, {})

        out_port = ofp.OFPP_FLOOD

        if dst_mac in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst_mac]
        else:
            if dst_mac in self.graph:
                if dst_mac not in self.paths[src_mac]:
                    try:
                        path = nx.shortest_path(self.graph,
                                                src_mac,
                                                dst_mac,
                                                weight="weight")
                        self.paths[src_mac][dst_mac] = path
                    except:
                        return
                path = self.paths[src_mac][dst_mac]
                next_hop = path[path.index(dpid) + 1]
                out_port = self.graph[dpid][next_hop]['port']
                self.mac_to_port[dpid][dst_mac] = out_port
                print path

        actions = [parser.OFPActionOutput(out_port)]

        if out_port != ofp.OFPP_FLOOD:
            match = parser.OFPMatch(in_port=in_port, eth_dst=dst_mac)
            self.add_flow(dp, 1, match, actions)

        data = None
        if msg.buffer_id == ofp.OFP_NO_BUFFER:
            data = msg.data
        out = parser.OFPPacketOut(datapath=dp,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        dp.send_msg(out)
Ejemplo n.º 21
0
    def packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath

        try:
            # src: from other switch
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
            # dst: this switch
            dst_dpid, dst_port_no = datapath.id, msg.match['in_port']

            if src_dpid > 1024 or dst_dpid > 1024:
                # hack: ignote illegal switch
                return
            
            switch = api.get_switch(self, src_dpid)

            # not this topology switch
            if len(switch) != 0:
                return

            # send cross domain link add
            self.local_lib.send_cross_domain_link(dst_dpid, dst_port_no, src_dpid, src_port_no)

            # add global port
            self.global_port.setdefault(dst_dpid, [])
            self.global_port[dst_dpid].append(dst_port_no)

            return
        except LLDPPacket.LLDPUnknownFormat:
            # This handler can receive all the packtes which can be
            # not-LLDP packet. Ignore it silently
            pass

        # non-LLDP
        # local routing
        dpid = datapath.id
        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        src = eth.src
        dst = eth.dst

        if dst not in self.local_lib.hosts:
            # can't find host in local topology
            # ask global and let this msg queued
            if dst in mDNS or dst in multicast_list:
                return

            if dst == 'ff:ff:ff:ff:ff:ff':
                self._flood_packet(msg)
                return
            self.route_list.append((dst, msg))
            self.local_lib.get_route(dst)
            return

        LOG.debug('Packet in, from %s, to %s', src, dst)
        # found in local, do local routing
        # two case:
        # 1. In same switch
        # 2. Not in same switch
        host = self.local_lib.hosts[dst]

        # host[0] -> dpid
        # host[1] -> port
        if host[0] == dpid:
            # same switch
            out_port = host[1]
            self._packet_out(msg, out_port)

        else:
            # not same switch
            # calculate path
            self._packet_out_to(msg, host[0], host[1])
Ejemplo n.º 22
0
    def packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath

        try:
            # src: from other switch
            src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
            # dst: this switch
            dst_dpid, dst_port_no = datapath.id, msg.match['in_port']

            if src_dpid > 1024 or dst_dpid > 1024:
                # hack: ignote illegal switch
                return

            switch = api.get_switch(self, src_dpid)

            # not this topology switch
            if len(switch) != 0:
                return

            # send cross domain link add
            self.local_lib.send_cross_domain_link(dst_dpid, dst_port_no,
                                                  src_dpid, src_port_no)

            # add global port
            self.global_port.setdefault(dst_dpid, [])
            self.global_port[dst_dpid].append(dst_port_no)

            return
        except LLDPPacket.LLDPUnknownFormat:
            # This handler can receive all the packtes which can be
            # not-LLDP packet. Ignore it silently
            pass

        # non-LLDP
        # local routing
        dpid = datapath.id
        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        src = eth.src
        dst = eth.dst

        if dst not in self.local_lib.hosts:
            # can't find host in local topology
            # ask global and let this msg queued
            if dst in mDNS or dst in multicast_list:
                return

            if dst == 'ff:ff:ff:ff:ff:ff':
                self._flood_packet(msg)
                return
            self.route_list.append((dst, msg))
            self.local_lib.get_route(dst)
            return

        LOG.debug('Packet in, from %s, to %s', src, dst)
        # found in local, do local routing
        # two case:
        # 1. In same switch
        # 2. Not in same switch
        host = self.local_lib.hosts[dst]

        # host[0] -> dpid
        # host[1] -> port
        if host[0] == dpid:
            # same switch
            out_port = host[1]
            self._packet_out(msg, out_port)

        else:
            # not same switch
            # calculate path
            self._packet_out_to(msg, host[0], host[1])
Ejemplo n.º 23
0
		def packet_in_handler(self, ev):
				
				AF3 = [104,112,120]
				EF = [184]
				
				msg= ev.msg
				dp = msg.datapath
				ofp = dp.ofproto
				ofp_parser = dp.ofproto_parser

				port = msg.match['in_port']
				
				## parses the packet
				pkt = packet.Packet(data=msg.data)
				# ethernet
				pkt_ethernet = pkt.get_protocol(ethernet.ethernet)
				

				if not pkt_ethernet:
						return

				# 當為LLDP packet時,把lldpdelay資料取出來
				if pkt_ethernet.ethertype == 35020:
					try:	
						src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data)
						dst_dpid = msg.datapath.id
						if self.switch_mod is None:
							self.switch_mod = lookup_service_brick('switches')

						for port in self.switch_mod.ports.keys(): 
							if src_dpid == port.dpid and src_port_no == port.port_no:
								lldpdelay = self.switch_mod.ports[port].delay
								self.net[src_dpid][dst_dpid]["lldpdelay"] = lldpdelay
					except LLDPPacket.LLDPUnknownFormat as e:
						return
				
				if msg.buffer_id == ofp.OFP_NO_BUFFER:
						data = msg.data

				if pkt_ethernet.ethertype != 34525 and pkt_ethernet.ethertype != 35020:
						if not self.net.has_node(pkt_ethernet.src): #如果不在图里则新增
								#print("add %s in self.net" % pkt_ethernet.src)
								#print(pkt_ethernet.ethertype)
								self.net.add_node(pkt_ethernet.src)
								self.net.add_edge(pkt_ethernet.src, dp.id, bw=0, delay=0, lldpdelay=0, load=0)
								self.net.add_edge(dp.id, pkt_ethernet.src, port=port, bw=0, delay=0, lldpdelay=0, load=0)
								self.idport_to_id.update({(dp.id,port):pkt_ethernet.src})
								#print(self.idport_to_id)
								#print(self.net.nodes())
								#print(self.net.edges.data())

				# arp封包处理
				arp_info = pkt.get_protocol(arp.arp)
				if arp_info != None: #代表是arp封包
					if pkt_ethernet.dst == 'ff:ff:ff:ff:ff:ff':
						if self.mac_learning(dp,pkt_ethernet.src,port) is False: #判断是否会造成广播风暴,False代表為是會造成
								out_port = ofp.OFPPC_NO_RECV #将封包丢掉
						else:
								out_port = ofp.OFPP_FLOOD #做flooding
								#更新mac_to_port 表,之后要用来作arp封包的处理
								self.mac_to_port.setdefault(dp.id, {})
								self.mac_to_port[dp.id][pkt_ethernet.src] = port
								if not self.net.has_node(pkt_ethernet.src): #若arp封包源沒有包含在圖裡面,則將它加入進圖中
										self.net.add_node(pkt_ethernet.src)
										self.net.add_edge(pkt_ethernet.src,dp.id,bw=0,delay=0, lldpdelay=0, load=0) #添加雙向的邊
										self.net.add_edge(dp.id,pkt_ethernet.src,port=port,bw=0, delay=0, lldpdelay=0, load=0)
										self.idport_to_id.update({(dp.id,port):pkt_ethernet.src})
										#print(self.idport_to_id)
										#print(self.net.nodes())
										#print(self.net.edges())

						actions = [ofp_parser.OFPActionOutput(out_port)]
						out = ofp_parser.OFPPacketOut(datapath=dp,buffer_id=msg.buffer_id,in_port=port,actions=actions,data=data)
						dp.send_msg(out)
						return
					else:
						if pkt_ethernet.dst in self.mac_to_port[dp.id]:
							out_port = self.mac_to_port[dp.id][pkt_ethernet.dst]
							actions = [ofp_parser.OFPActionOutput(out_port)]
							out = ofp_parser.OFPPacketOut(datapath=dp, buffer_id=msg.buffer_id, in_port=port, actions=actions, data=data)
							dp.send_msg(out)
						return


				
				if self.net.has_node(pkt_ethernet.dst):
						#print("%s in self.net" % pkt_ethernet.dst)
						ip_info = pkt.get_protocol(ipv4.ipv4)
						print(ip_info)
						if ip_info != None:
								path = [p for p in nx.all_shortest_paths(self.net, pkt_ethernet.src, pkt_ethernet.dst)]
								print("All shortest path")
								print(path)
								
								count = 0
								meter_id = None
								print("finding avaliable shortest path...")
								for i in range(len(path)):
										for j in range(len(path[i])-1):
												if (path[i][j], path[i][j+1]) not in self.busy_link:
														count = count + 1
										if count > 2:
												path = path[i]
												print("find shortest path!!")
												break
										count = 0

										if i == len(path) - 1:
												print("cant find avaliable shortest path, finding other path...")
												if ip_info.tos in AF3: 
														path = nx.dijkstra_path(self.net, pkt_ethernet.src, pkt_ethernet.dst, weight='bw') #以当前bw作最短路徑轉發
														meter_id = 3
														print("find min bandwidth path")
												elif ip_info.tos in EF:
														path = nx.dijkstra_path(self.net, pkt_ethernet.src, pkt_ethernet.dst, weight='delay')
														meter_id = 3
														print("find min delay path")
												else:
														path = path[i]
														#ip_info.tos = 0 #强制其tos段等于0
														meter_id = 3
														print("dont change path, tos=0")
								print(path)		
						next_match = ofp_parser.OFPMatch(eth_dst=pkt_ethernet.dst,eth_src=pkt_ethernet.src,eth_type=0x0800,ipv4_src=ip_info.src, ipv4_dst=ip_info.dst, ip_dscp=int(ip_info.tos/4))
						back_match = ofp_parser.OFPMatch(eth_dst=pkt_ethernet.src,eth_src=pkt_ethernet.dst,eth_type=0x0800,ipv4_src=ip_info.src, ipv4_dst=ip_info.dst, ip_dscp=int(ip_info.tos/4))
						#print(path)
						#依照計算后算出的路徑下發流表
						for on_path_switch in range(1, len(path)-1):
								now_switch = path[on_path_switch] #这里需要知道現在,之前以及之後的switch
								next_switch = path[on_path_switch+1]
								back_switch = path[on_path_switch-1]
								next_port = self.net[now_switch][next_switch]['port']
								back_port = self.net[now_switch][back_switch]['port']
								action = ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, [ofp_parser.OFPActionOutput(next_port)])
								hard_timeout = 0
								if meter_id == None:
										inst = [action]
								else:
										inst = [action, ofp_parser.OFPInstructionMeter(meter_id, ofp.OFPIT_METER)]
										hard_timeout = 10
								
								self.add_flow(dp=self.switch_map[now_switch], match=next_match, inst=inst, table=0, idle_timeout=50, hard_timeout=hard_timeout)
								
								action = ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, [ofp_parser.OFPActionOutput(back_port)])

								self.add_flow(dp=self.switch_map[now_switch], match=back_match, inst=inst, table=0, idle_timeout=50, hard_timeout=hard_timeout)
								#print("now switch:%s" % now_switch)
						
						now_switch = path[1]
						next_switch = path[2]
						out_port = self.net[now_switch][next_switch]['port']
						actions = [ofp_parser.OFPActionOutput(out_port)]
						out = ofp_parser.OFPPacketOut(datapath=dp,buffer_id=msg.buffer_id,in_port=port,actions=actions,data=data)
						dp.send_msg(out)
				else:
						return