Пример #1
0
    def update_flow_table(self, flows, device):
        """
        Update the flow table on the OLT.  If an existing flow is not in the list, it needs
        to be removed from the device.

        :param flows: List of flows that should be installed upon completion of this function
        :param device: A voltha.Device object, with possible device-type
                       specific extensions.
        """
        self.log.debug('bulk-flow-update',
                       num_flows=len(flows),
                       device_id=device.id,
                       flows=flows)

        valid_flows = []

        for flow in flows:
            try:
                # Try to create an EVC.
                #
                # The first result is the flow entry that was created. This could be a match to an
                # existing flow since it is a bulk update.  None is returned only if no match to
                # an existing entry is found and decode failed (unsupported field)
                #
                # The second result is the EVC this flow should be added to. This could be an
                # existing flow (so your adding another EVC-MAP) or a brand new EVC (no existing
                # EVC-MAPs).  None is returned if there are not a valid EVC that can be created YET.

                valid_flow, evc = FlowEntry.create(flow, self)

                if valid_flow is not None:
                    valid_flows.append(valid_flow.flow_id)

                if evc is not None:
                    try:
                        evc.schedule_install()
                        self.add_evc(evc)

                    except Exception as e:
                        evc.status = 'EVC Install Exception: {}'.format(
                            e.message)
                        self.log.exception('EVC-install', e=e)

            except Exception as e:
                self.log.exception('bulk-flow-update-add', e=e)

        # Now drop all flows from this device that were not in this bulk update
        try:
            FlowEntry.drop_missing_flows(device.id, valid_flows)

        except Exception as e:
            self.log.exception('bulk-flow-update-remove', e=e)
Пример #2
0
    def update_flow_table(self, flows, device):
        """
        Update the flow table on the OLT.  If an existing flow is not in the list, it needs
        to be removed from the device.

        :param flows: List of flows that should be installed upon completion of this function
        :param device: A voltha.Device object, with possible device-type
                       specific extensions.
        """
        self.log.debug('bulk-flow-update', num_flows=len(flows),
                       device_id=device.id, flows=flows)

        valid_flows = []

        for flow in flows:
            try:
                # Try to create an EVC.
                #
                # The first result is the flow entry that was created. This could be a match to an
                # existing flow since it is a bulk update.  None is returned only if no match to
                # an existing entry is found and decode failed (unsupported field)
                #
                # The second result is the EVC this flow should be added to. This could be an
                # existing flow (so your adding another EVC-MAP) or a brand new EVC (no existing
                # EVC-MAPs).  None is returned if there are not a valid EVC that can be created YET.

                valid_flow, evc = FlowEntry.create(flow, self)

                if valid_flow is not None:
                    valid_flows.append(valid_flow.flow_id)

                if evc is not None:
                    try:
                        evc.schedule_install()
                        self.add_evc(evc)

                    except Exception as e:
                        evc.status = 'EVC Install Exception: {}'.format(e.message)
                        self.log.exception('EVC-install', e=e)

            except Exception as e:
                self.log.exception('bulk-flow-update-add', e=e)

        # Now drop all flows from this device that were not in this bulk update
        try:
            yield FlowEntry.drop_missing_flows(device.id, valid_flows)

        except Exception as e:
            self.log.exception('bulk-flow-update-remove', e=e)
Пример #3
0
    def add_gem_port(self, gem_port, add_always=False):
        """
        Add a GEM Port to this ONU

        :param gem_port: (GemPort) GEM Port to add
        :param add_always: (boolean) If true, force add (used during h/w resync)
        :return: (deferred)
        """
        if not self._valid:
            returnValue(succeed('Deleting'))

        if not add_always and gem_port.gem_id in self._gem_ports:
            returnValue(succeed('already created'))

        try:
            results = yield gem_port.add_to_hardware(self.olt.rest_client,
                                                     self._pon_id, self.onu_id)
            self._gem_ports[gem_port.gem_id] = gem_port

            # May need to update flow tables/evc-maps
            if gem_port.alloc_id in self._tconts:
                # GEM-IDs are a sorted list (ascending). First gemport handles downstream traffic
                from flow.flow_entry import FlowEntry
                evc_maps = FlowEntry.find_evc_map_flows(
                    self._device_id, self._pon_id, self._onu_id)
                pass

        except Exception as e:
            self.log.exception('gem-port', e=e)
            raise

        returnValue(results)
Пример #4
0
    def remove_gem_id(self, gem_id):
        gem_port = self._gem_ports.get(gem_id)

        if gem_port is None:
            returnValue(succeed('nop'))

        del self._gem_ports[gem_id]
        # self._resync_flows = True

        try:
            from flow.flow_entry import FlowEntry

            if gem_port.alloc_id in self._tconts:
                # May need to update flow tables/evc-maps
                # GEM-IDs are a sorted list (ascending). First gemport handles downstream traffic
                pass

            results = yield gem_port.remove_from_hardware(
                self.olt.rest_client, self._pon_id, self.onu_id)
            evc_maps = FlowEntry.find_evc_map_flows(self)

            for evc_map in evc_maps:
                evc_map.remove_gem_port(gem_port)

        except Exception as e:
            self.log.exception('delete', e=e)
            raise

        returnValue(succeed(results))
Пример #5
0
    def remove_gem_id(self, gem_id):
        from flow.flow_entry import FlowEntry

        gem_port = self._gem_ports.get(gem_id)

        if gem_port is None:
            returnValue('nop')

        del self._gem_ports[gem_id]
        try:

            if gem_port.alloc_id in self._tconts:
                # May need to update flow tables/evc-maps
                # GEM-IDs are a sorted list (ascending). First gemport handles downstream traffic
                evc_maps = FlowEntry.find_evc_map_flows(self)
                for evc_map in evc_maps:
                    evc_map.remove_gem_port(gem_port)

            results = yield gem_port.remove_from_hardware(
                self.olt.rest_client, self._pon_id, self.onu_id)
        except RestInvalidResponseCode as e:
            if e.code != 404:
                self.log.exception('onu-delete', e=e)

        except Exception as ex:
            self.log.exception('gem-port-delete', e=ex)
            raise

        for evc_map in FlowEntry.find_evc_map_flows(self):
            try:
                evc_map.remove_gem_port(gem_port)

            except Exception as ex:
                self.log.exception('evc-map-gem-remove', e=ex)

        returnValue('done')
Пример #6
0
    def add_gem_port(self, gem_port, reflow=False):
        """
        Add a GEM Port to this ONU

        :param gem_port: (GemPort) GEM Port to add
        :param reflow: (boolean) If true, force add (used during h/w resync)
        :return: (deferred)
        """
        if not self._valid:
            returnValue('Deleting')

        if not reflow and gem_port.gem_id in self._gem_ports:
            returnValue('nop')

        gem_port.pon_id = self.pon_id
        gem_port.onu_id = self.onu_id if self.onu_id is not None else -1
        gem_port.intf_id = self.intf_id

        # TODO: Currently only support a single UNI. Need to support multiple and track their GEM Ports
        #       Probably best done by having a UNI-Port class (keep it simple)
        self.log.info('add', gem_port=gem_port, reflow=reflow)
        self._gem_ports[gem_port.gem_id] = gem_port

        try:
            results = yield gem_port.add_to_hardware(self.olt.rest_client)
            # May need to update flow tables/evc-maps
            if gem_port.alloc_id in self._tconts:
                from flow.flow_entry import FlowEntry
                # GEM-IDs are a sorted list (ascending). First gemport handles downstream traffic
                # from flow.flow_entry import FlowEntry
                evc_maps = FlowEntry.find_evc_map_flows(self)

                for evc_map in evc_maps:
                    evc_map.add_gem_port(gem_port, reflow=reflow)

        except Exception as e:
            self.log.exception('gem-port',
                               gem_port=gem_port,
                               reflow=reflow,
                               e=e)
            # This can happen with xPON if the ONU has been provisioned, but the PON Discovery
            # has not occurred for the ONU. Rely on hw sync to recover
            results = 'resync needed'

        returnValue(results)
Пример #7
0
    def add_gem_port(self, gem_port, reflow=False):
        """
        Add a GEM Port to this ONU

        :param gem_port: (GemPort) GEM Port to add
        :param reflow: (boolean) If true, force add (used during h/w resync)
        :return: (deferred)
        """
        if not self._valid:
            returnValue(succeed('Deleting'))

        if not reflow and gem_port.gem_id in self._gem_ports:
            returnValue(succeed)

        self._gem_ports[gem_port.gem_id] = gem_port

        try:
            results = yield gem_port.add_to_hardware(self.olt.rest_client,
                                                     self._pon_id, self.onu_id)
            # self._resync_flows = True

            # May need to update flow tables/evc-maps
            if gem_port.alloc_id in self._tconts:
                from flow.flow_entry import FlowEntry
                # GEM-IDs are a sorted list (ascending). First gemport handles downstream traffic
                # from flow.flow_entry import FlowEntry
                evc_maps = FlowEntry.find_evc_map_flows(self)

                for evc_map in evc_maps:
                    evc_map.add_gem_port(gem_port, reflow=reflow)

        except Exception as e:
            self.log.exception('gem-port',
                               gem_port=gem_port,
                               reflow=reflow,
                               e=e)
            # This can happen with xPON if the ONU has been provisioned, but the PON Discovery
            # has not occurred for the ONU. Rely on hw sync to recover
            results = 'resync needed'

        returnValue(results)
Пример #8
0
        def sync_flows():
            from flow.flow_entry import FlowEntry

            reflow, self._resync_flows = self._resync_flows, False
            return FlowEntry.sync_flows_by_onu(self, reflow=reflow)