def _handle_new_link(self, of_link):

        of_port_src = of_link['src']
        src_dpid = DPID(of_port_src['dpid'])
        src_port_id = of_port_src['port_no']

        src_datapath = RUNTIME.datapaths[src_dpid]
        src_port = src_datapath.network_ports[src_port_id]

        of_port_dst = of_link['dst']
        dst_dpid = DPID(of_port_dst['dpid'])
        dst_port_id = of_port_dst['port_no']

        dst_datapath = RUNTIME.datapaths[dst_dpid]
        dst_port = dst_datapath.network_ports[dst_port_id]

        # links are unidirectional
        src_port.neighbour = dst_port
Exemplo n.º 2
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()
Exemplo n.º 3
0
    def post(self, *args):
        """Add a new Endpoint.

        Args:
            tenant_id: network name of a tenant
            endpoint_id: the endpoint id

        Request:
            version: protocol version (1.0)
            endpoint_name: the endpoint name
            dpid: the datapath id
            ports: a dictionary of VirtualPorts, where each key is a vport_id
                port_id: the port number on the datapath id
                properties: a dictionary of additional information
                    dont_learn: list of hardware addresses bounded to this port

        Example URLs:

            POST /api/v1/tenants/52313ecb-9d00-4b7d-b873-b55d3d9ada26/eps
            POST /api/v1/tenants/52313ecb-9d00-4b7d-b873-b55d3d9ada26/
                eps/49313ecb-9d00-4a7c-b873-b55d3d9ada34
        """

        try:

            if len(args) > 2 or len(args) < 1:
                raise ValueError("Invalid url")

            request = tornado.escape.json_decode(self.request.body)

            if "version" not in request:
                raise ValueError("missing version element")

            if "endpoint_name" not in request:
                raise ValueError("missing endpoint_name element")

            if "dpid" not in request:
                raise ValueError("missing dpid element")

            if "ports" not in request:
                raise ValueError("missing ports element")

            if not isinstance(request["ports"], dict):
                raise ValueError("ports is not a dictionary")

            for port in request["ports"].values():

                if "port_id" not in port:
                    raise ValueError("missing port_id element")

            tenant_id = UUID(args[0])

            if tenant_id not in RUNTIME.tenants:
                raise KeyError(tenant_id)

            tenant = RUNTIME.tenants[tenant_id]

            if len(args) == 1:
                endpoint_id = uuid4()
            else:
                endpoint_id = UUID(args[1])

            dpid = DPID(request["dpid"])
            datapath = RUNTIME.datapaths[dpid]

            tenant.add_endpoint(endpoint_id=endpoint_id,
                                endpoint_name=request["endpoint_name"],
                                datapath=datapath,
                                ports=request["ports"])

            url = "/api/v1/tenants/%s/eps/%s" % (tenant_id, endpoint_id)
            self.set_header("Location", url)

        except ValueError as ex:
            self.send_error(400, message=ex)

        except RuntimeError as ex:
            self.send_error(400, message=ex)

        except KeyError as ex:
            self.send_error(404, message=ex)

        self.set_status(201, None)
Exemplo n.º 4
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)
Exemplo n.º 5
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