예제 #1
0
    def _handle_caps_response(self, caps):
        """Handle an incoming cap response message.

        Args:
            caps, a CAP_RESPONSE message

        Returns:
            None
        """

        dpid = DPID(caps['dpid'])

        if dpid not in RUNTIME.datapaths:
            RUNTIME.datapaths[dpid] = Datapath(dpid)

        self.cpp.datapath = RUNTIME.datapaths[dpid]

        for port_id, port in caps['ports'].items():

            if int(port_id) not in self.cpp.datapath.network_ports:

                network_port = NetworkPort(dp=self.cpp.datapath,
                                           port_id=int(port['port_id']),
                                           hwaddr=EtherAddress(port['hwaddr']),
                                           iface=port['iface'])

                self.cpp.datapath.network_ports[int(port_id)] = network_port

        # set state to online
        self.cpp.set_online()

        # fetch active lvnfs
        self.send_lvnf_status_request()
예제 #2
0
    def _handle_caps(self, wtp, caps):
        """Handle an incoming CAPS message.
        Args:
            caps, a CAPS message
        Returns:
            None
        """

        LOG.info("Received caps from %s", wtp.addr)

        for block in caps.blocks:
            hwaddr = EtherAddress(block[0])
            r_block = ResourceBlock(wtp, hwaddr, block[1], block[2])
            wtp.supports.add(r_block)

        for port in caps.ports:

            iface = port[2].decode("utf-8").strip('\0')

            network_port = NetworkPort(dpid=wtp.addr,
                                       hwaddr=EtherAddress(port[0]),
                                       port_id=int(port[1]),
                                       iface=iface)

            wtp.ports[network_port.port_id] = network_port

        # WTP can be considered as available once the empower0 port has been
        # added to the OVS
        if wtp.port():
            self.send_register_message_to_self()
예제 #3
0
    def _handle_caps(cls, caps):
        """Handle an incoming CAPS message.
        Args:
            caps, a CAPS message
        Returns:
            None
        """

        wtp_addr = EtherAddress(caps.wtp)

        try:
            wtp = RUNTIME.wtps[wtp_addr]
        except KeyError:
            LOG.info("Caps response from unknown WTP (%s)", wtp_addr)
            return

        LOG.info("Received caps response from %s", wtp_addr)

        for block in caps.blocks:

            hwaddr = EtherAddress(block[0])

            r_block = ResourceBlock(wtp, hwaddr, block[1], block[2])
            wtp.supports.add(r_block)

        for port in caps.ports:

            iface = port[2].decode("utf-8").strip('\0')

            network_port = NetworkPort(dpid=wtp.addr,
                                       hwaddr=EtherAddress(port[0]),
                                       port_id=int(port[1]),
                                       iface=iface)

            wtp.ports[network_port.port_id] = network_port
    def _handle_new_datapath(self, of_datapath):

        dpid = DPID(of_datapath['dpid'])

        if dpid not in RUNTIME.datapaths:
            RUNTIME.datapaths[dpid] = Datapath(dpid)

        datapath = RUNTIME.datapaths[dpid]
        datapath.ip_addr = of_datapath['ip_addr']

        for port in of_datapath['ports']:

            port_id = port['port_no']

            if port_id not in datapath.network_ports:

                network_port = NetworkPort(dp=datapath,
                                           port_id=port['port_no'],
                                           hwaddr=port['hw_addr'],
                                           iface=port['name'])

                datapath.network_ports[port_id] = network_port

        if dpid not in self.of_dpid:
            self.of_dpid.append(dpid)

        self._of_dp_join(datapath)
예제 #5
0
    def _handle_caps(self, caps):
        """Handle an incoming cap response message.

        Args:
            caps, a CAP_RESPONSE message

        Returns:
            None
        """

        cpp_addr = EtherAddress(caps['addr'])

        try:
            cpp = RUNTIME.cpps[cpp_addr]
        except KeyError:
            LOG.info("Caps from unknown CPP (%s)", cpp_addr)
            raise KeyError("Hello from unknown CPP (%s)", cpp_addr)

        cpp.ports = {}

        for port in caps['ports'].values():

            network_port = NetworkPort(dpid=cpp.addr,
                                       port_id=port['port_id'],
                                       iface=port['iface'],
                                       hwaddr=EtherAddress(port['hwaddr']))

            cpp.ports[network_port.port_id] = network_port

        # set state to online
        cpp.set_online()
예제 #6
0
    def _handle_caps(self, wtp, caps):
        """Handle an incoming CAPS message.
        Args:
            caps, a CAPS message
        Returns:
            None
        """

        dpid = DPID(caps['dpid'])

        if dpid not in RUNTIME.datapaths:
            RUNTIME.datapaths[dpid] = Datapath(dpid)

        wtp.datapath = RUNTIME.datapaths[dpid]

        for block in caps.blocks:
            hwaddr = EtherAddress(block[0])
            r_block = ResourceBlock(wtp, hwaddr, block[1], block[2])
            wtp.supports.add(r_block)

        for port in caps.ports:

            hwaddr = EtherAddress(port[0])
            port_id = int(port[1])
            iface = port[2].decode("utf-8").strip('\0')

            if port_id not in wtp.datapath.network_ports:

                network_port = NetworkPort(dp=wtp.datapath,
                                           port_id=port_id,
                                           hwaddr=hwaddr,
                                           iface=iface)

                wtp.datapath.network_ports[port_id] = network_port

        # set state to online
        wtp.set_online()

        # fetch active lvaps
        self.send_lvap_status_request()

        # fetch active vaps
        self.send_vap_status_request()

        # fetch active traffic rules
        self.send_slice_status_request()

        # fetch active tramission policies
        self.send_transmission_policy_status_request()

        # send vaps
        self.update_vaps()

        # send slices
        self.update_slices()
예제 #7
0
    def _handle_caps(self, wtp, caps):
        """Handle an incoming CAPS message.
        Args:
            caps, a CAPS message
        Returns:
            None
        """

        LOG.info("Received caps from %s", wtp.addr)

        for block in caps.blocks:
            hwaddr = EtherAddress(block[0])
            r_block = ResourceBlock(wtp, hwaddr, block[1], block[2])
            wtp.supports.add(r_block)

        for port in caps.ports:

            iface = port[2].decode("utf-8").strip('\0')

            network_port = NetworkPort(dpid=wtp.addr,
                                       hwaddr=EtherAddress(port[0]),
                                       port_id=int(port[1]),
                                       iface=iface)

            wtp.ports[network_port.port_id] = network_port

        # set state to online
        wtp.set_online()

        # fetch active lvaps
        self.send_lvap_status_request()

        # fetch active vaps
        self.send_vap_status_request()

        # fetch active traffic rules
        self.send_traffic_rule_status_request()

        # fetch active transmission rules
        self.send_port_status_request()

        # send vaps
        self.send_vaps()
예제 #8
0
    def _handle_caps_response(self, caps):
        """Handle an incoming cap response message.

        Args:
            caps, a CAP_RESPONSE message

        Returns:
            None
        """

        addr = EtherAddress(caps['addr'])
        pnfdev = self.server.pnfdevs[addr]
        pnfdev.ports = {}

        for port in caps['ports'].values():

            network_port = NetworkPort(dpid=pnfdev.addr,
                                       port_id=port['port_id'],
                                       iface=port['iface'],
                                       hwaddr=EtherAddress(port['hwaddr']))

            pnfdev.ports[network_port.port_id] = network_port
예제 #9
0
    def _handle_lvnf_status_response(self, response):
        """Handle an incoming LVNF_STATUS_RESPONSE message.

        Args:
            status_lvnf, a LVNF_STATUS_RESPONSE message

        Returns:
            None
        """

        # update dpid
        dpid = DPID(response['dpid'])

        if dpid not in RUNTIME.datapaths:
            RUNTIME.datapaths[dpid] = Datapath(dpid)

        self.cpp.datapath = RUNTIME.datapaths[dpid]

        # update network ports
        for port in response['ports'].values():

            if port['ovs_port_id'] not in self.cpp.datapath.network_ports:

                network_port = NetworkPort(dp=self.cpp.datapath,
                                           port_id=port['ovs_port_id'],
                                           hwaddr=EtherAddress(port['hwaddr']),
                                           iface=port['iface'])

                self.cpp.datapath.network_ports[port['ovs_port_id']] = \
                    network_port

        # update lvnf
        tenant_id = uuid.UUID(response['tenant_id'])
        lvnf_id = uuid.UUID(response['lvnf_id'])

        if tenant_id not in RUNTIME.tenants:
            LOG.warning("Tenant %s not found, ignoring LVNF %s", tenant_id,
                        lvnf_id)
            return

        tenant = RUNTIME.tenants[tenant_id]

        # Add lvnf to tenant if not present
        if lvnf_id not in tenant.lvnfs:

            LOG.warning("LVNF %s not found, adding.", lvnf_id)

            img_dict = response['image']

            image = Image(nb_ports=img_dict['nb_ports'],
                          vnf=img_dict['vnf'],
                          state_handlers=img_dict['state_handlers'],
                          handlers=img_dict['handlers'])

            tenant.lvnfs[lvnf_id] = LVNF(lvnf_id, tenant, image,
                                         PROCESS_RUNNING)

            tenant.lvnfs[lvnf_id]._cpp = self.cpp
            tenant.lvnfs[lvnf_id].datapath = self.cpp.datapath

        lvnf = tenant.lvnfs[lvnf_id]

        # update virtual ports
        for port in response['ports'].values():

            network_port = self.cpp.datapath.network_ports[port['ovs_port_id']]
            virtual_port_id = port['virtual_port_id']

            virtual_port = VirtualPort(endpoint=lvnf,
                                       network_port=network_port,
                                       virtual_port_id=virtual_port_id)

            lvnf.ports[virtual_port.virtual_port_id] = virtual_port

        LOG.info("LVNF Status: %s", lvnf)
예제 #10
0
    def _handle_add_lvnf_response(self, response):
        """Handle an incoming ADD_LVNF_RESPONSE message.

        Args:
            response, a ADD_LVNF_RESPONSE message

        Returns:
            None
        """

        if response['returncode'] is not None:

            LOG.error("Unable to start LVNF %s, returncode %u",
                      response['lvnf_id'], response['returncode'])

            tenant_id = uuid.UUID(response['tenant_id'])
            lvnf_id = uuid.UUID(response['lvnf_id'])

            if tenant_id not in RUNTIME.tenants:
                LOG.warning("Tenant %s not found, ignoring LVNF %s", tenant_id,
                            lvnf_id)
                return

            tenant = RUNTIME.tenants[tenant_id]

            if lvnf_id not in tenant.lvnfs:
                LOG.warning("LVNF %s not found, ignoring", lvnf_id)
                return

            del tenant.lvnfs[lvnf_id]

            return

        # update dpid
        dpid = DPID(response['dpid'])

        if dpid not in RUNTIME.datapaths:
            RUNTIME.datapaths[dpid] = Datapath(dpid)

        self.cpp.datapath = RUNTIME.datapaths[dpid]

        # update network ports
        for port in response['ports'].values():

            if port['ovs_port_id'] not in self.cpp.datapath.network_ports:

                network_port = NetworkPort(dp=self.cpp.datapath,
                                           port_id=port['ovs_port_id'],
                                           hwaddr=EtherAddress(port['hwaddr']),
                                           iface=port['iface'])

                self.cpp.datapath.network_ports[port['ovs_port_id']] = \
                    network_port

        # update lvnf
        tenant_id = uuid.UUID(response['tenant_id'])
        lvnf_id = uuid.UUID(response['lvnf_id'])

        if tenant_id not in RUNTIME.tenants:
            LOG.warning("Tenant %s not found, ignoring LVNF %s", tenant_id,
                        lvnf_id)
            return

        tenant = RUNTIME.tenants[tenant_id]

        if lvnf_id not in tenant.lvnfs:
            LOG.warning("LVNF %s not found, ignoring", lvnf_id)
            return

        lvnf = tenant.lvnfs[lvnf_id]

        lvnf.handle_add_lvnf_response(response['xid'])

        # update virtual ports
        for port in response['ports'].values():

            network_port = self.cpp.datapath.network_ports[port['ovs_port_id']]
            virtual_port_id = port['virtual_port_id']

            virtual_port = VirtualPort(endpoint=lvnf,
                                       network_port=network_port,
                                       virtual_port_id=virtual_port_id)

            lvnf.ports[virtual_port.virtual_port_id] = virtual_port
예제 #11
0
    def _handle_status_lvnf(self, status_lvnf):
        """Handle an incoming STATUS_LVNF message.

        Args:
            status_lvnf, a STATUS_LVNF message

        Returns:
            None
        """

        addr = EtherAddress(status_lvnf['addr'])
        cpp = RUNTIME.cpps[addr]

        tenant_id = uuid.UUID(status_lvnf['tenant_id'])
        lvnf_id = uuid.UUID(status_lvnf['lvnf_id'])

        tenant = RUNTIME.tenants[tenant_id]

        LOG.info("LVNF %s status update", lvnf_id)

        # Add lvnf to tenant if not present
        if lvnf_id not in tenant.lvnfs:

            LOG.warning("LVNF %s not found, adding.", lvnf_id)

            img_dict = status_lvnf['image']

            image = Image(nb_ports=img_dict['nb_ports'],
                          vnf=img_dict['vnf'],
                          state_handlers=img_dict['state_handlers'],
                          handlers=img_dict['handlers'])

            tenant.lvnfs[lvnf_id] = LVNF(lvnf_id, tenant_id, image, cpp)

        lvnf = tenant.lvnfs[lvnf_id]

        if lvnf.state in (None, PROCESS_RUNNING, PROCESS_SPAWNING,
                          PROCESS_MIGRATING_START):

            if status_lvnf['returncode']:

                # Raise LVNF leave event
                if lvnf.state:
                    LOG.info("LVNF LEAVE %s", lvnf_id)
                    handlers = self.server.pt_types_handlers[PT_LVNF_LEAVE]
                    for handler in handlers:
                        handler(lvnf)

                lvnf.returncode = status_lvnf['returncode']
                lvnf.contex = status_lvnf['context']

                lvnf.state = PROCESS_STOPPED

                return

            # Configure ports
            for port in status_lvnf['ports'].values():

                virtual_port_id = port['virtual_port_id']

                if port['hwaddr']:
                    hwaddr = EtherAddress(port['hwaddr'])
                else:
                    hwaddr = None

                if port['ovs_port_id']:
                    ovs_port_id = int(port['ovs_port_id'])
                else:
                    ovs_port_id = None

                iface = port['iface']

                phy_port = \
                    NetworkPort(lvnf.cpp.addr, ovs_port_id, hwaddr, iface)

                virtual_port = VirtualPortLvnf(virtual_port_id=virtual_port_id,
                                               phy_port=phy_port)

                lvnf.ports[virtual_port.virtual_port_id] = virtual_port

            lvnf.returncode = status_lvnf['returncode']
            lvnf.contex = status_lvnf['context']

            lvnf.state = PROCESS_RUNNING

            # Raise LVNF join event
            if lvnf.state == PROCESS_RUNNING:
                LOG.info("LVNF JOIN %s", lvnf.lvnf_id)
                handlers = self.server.pt_types_handlers[PT_LVNF_JOIN]
                for handler in handlers:
                    handler(lvnf)

        elif lvnf.state == PROCESS_STOPPING:

            if status_lvnf['returncode']:

                # Raise LVNF leave event
                if lvnf.state:
                    LOG.info("LVNF LEAVE %s", lvnf_id)
                    handlers = self.server.pt_types_handlers[PT_LVNF_LEAVE]
                    for handler in handlers:
                        handler(lvnf)

                lvnf.returncode = status_lvnf['returncode']
                lvnf.contex = status_lvnf['context']

                lvnf.state = PROCESS_STOPPED

                # remove lvnf
                del tenant.lvnfs[lvnf_id]

                return

            IOError("No return code on stopping LVNF")

        elif lvnf.state == PROCESS_MIGRATING_STOP:

            if status_lvnf['returncode']:

                lvnf.returncode = status_lvnf['returncode']
                lvnf.context = status_lvnf['context']

                lvnf.state = PROCESS_MIGRATING_START

                return

            IOError("No returncode on migrating LVNF")

        else:

            raise IOError("Invalid transistion")