Пример #1
0
    def ActivateFlows(self, request, context):
        """
        Activate flows for a subscriber based on the pre-defined rules
        """
        self._log_grpc_payload(request)
        if not self._service_manager.is_app_enabled(
                EnforcementController.APP_NAME, ):
            context.set_code(grpc.StatusCode.UNAVAILABLE)
            context.set_details('Service not enabled!')
            return None

        for controller in [
                self._gy_app,
                self._enforcer_app,
                self._enforcement_stats,
        ]:
            if not controller.is_controller_ready():
                context.set_code(grpc.StatusCode.UNAVAILABLE)
                context.set_details('Enforcement service not initialized!')
                return ActivateFlowsResult()

        fut = Future()  # type: Future[ActivateFlowsResult]
        self._loop.call_soon_threadsafe(self._activate_flows, request, fut)
        try:
            return fut.result(timeout=self._call_timeout)
        except concurrent.futures.TimeoutError:
            logging.error("ActivateFlows request processing timed out")
            context.set_code(grpc.StatusCode.DEADLINE_EXCEEDED)
            context.set_details('ActivateFlows processing timed out')
            deactivate_req = get_deactivate_req(request)
            self._loop.call_soon_threadsafe(
                self._deactivate_flows,
                deactivate_req,
            )
            return ActivateFlowsResult()
Пример #2
0
    def activate_rules(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, policies):
        """
        Activate the flows for a subscriber based on the rules stored in Redis.
        During activation, a default flow may be installed for the subscriber.

        Args:
            imsi (string): subscriber id
            msisdn (bytes): subscriber MSISDN
            uplink_tunnel(int): Tunnel ID of the subscriber session.
            ip_addr (string): subscriber session ipv4 address
            policies (VersionedPolicies []): list of versioned policies to activate
        """
        if self._datapath is None:
            self.logger.error('Datapath not initialized for adding flows')
            return ActivateFlowsResult(
                policy_results=[RuleModResult(
                    rule_id=policy.rule.id,
                    version=policy.version,
                    result=RuleModResult.FAILURE,
                ) for policy in policies],
            )
        policy_results = []
        for policy in policies:
            res = self._install_flow_for_rule(imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, policy.rule, policy.version)
            policy_results.append(RuleModResult(rule_id=policy.rule.id, version=policy.version, result=res))

        # Install a base flow for when no rule is matched.
        self._install_default_flow_for_subscriber(imsi, ip_addr)
        return ActivateFlowsResult(
            policy_results=policy_results,
        )
Пример #3
0
    def activate_flows(self, imsi, ip_addr, static_rule_ids, dynamic_rules,
                       fut):
        """
        Activate the flows for a subscriber based on the rules stored in Redis.
        During activation, another low priority flow is installed for the
        subscriber in the event that all rules are out of credit.

        Args:
            imsi (string): subscriber id
            ip_addr (string): subscriber session ipv4 address
            static_rule_ids (string []): list of static rules to activate
            dynamic_rules (PolicyRule []): list of dynamic rules to activate
            fut (Future): future to wait on the results of flow activations
        """
        if self._datapath is None:
            self.logger.error('Datapath not initialized for adding flows')
            fut.set_result(
                ActivateFlowsResult(
                    static_rule_results=[
                        RuleModResult(
                            rule_id=rule_id,
                            result=RuleModResult.FAILURE,
                        ) for rule_id in static_rule_ids
                    ],
                    dynamic_rule_results=[
                        RuleModResult(
                            rule_id=rule.id,
                            result=RuleModResult.FAILURE,
                        ) for rule in dynamic_rules
                    ],
                ))
            return
        static_results = []
        for rule_id in static_rule_ids:
            res = self._install_flow_for_static_rule(imsi, ip_addr, rule_id)
            static_results.append(RuleModResult(rule_id=rule_id, result=res))
        dyn_results = []
        for rule in dynamic_rules:
            res = self._install_flow_for_rule(imsi, ip_addr, rule)
            dyn_results.append(RuleModResult(rule_id=rule.id, result=res))

        # No matter what, install base flow to drop packets when all other
        # flows have been deactivated
        self._install_drop_flow(imsi)
        fut.set_result(
            ActivateFlowsResult(
                static_rule_results=static_results,
                dynamic_rule_results=dyn_results,
            ))
Пример #4
0
    def activate_rules(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr,
                       apn_ambr, static_rule_ids, dynamic_rules):
        """
        Activate the flows for a subscriber based on the rules stored in Redis.
        During activation, a default flow may be installed for the subscriber.

        Args:
            imsi (string): subscriber id
            msisdn (bytes): subscriber MSISDN
            uplink_tunnel(int): Tunnel ID of the subscriber session.
            ip_addr (string): subscriber session ipv4 address
            static_rule_ids (string []): list of static rules to activate
            dynamic_rules (PolicyRule []): list of dynamic rules to activate
        """
        if self._datapath is None:
            self.logger.error('Datapath not initialized for adding flows')
            return ActivateFlowsResult(
                static_rule_results=[
                    RuleModResult(
                        rule_id=rule_id,
                        result=RuleModResult.FAILURE,
                    ) for rule_id in static_rule_ids
                ],
                dynamic_rule_results=[
                    RuleModResult(
                        rule_id=rule.id,
                        result=RuleModResult.FAILURE,
                    ) for rule in dynamic_rules
                ],
            )
        static_results = []
        for rule_id in static_rule_ids:
            res = self._install_flow_for_static_rule(imsi, msisdn,
                                                     uplink_tunnel, ip_addr,
                                                     apn_ambr, rule_id)
            static_results.append(RuleModResult(rule_id=rule_id, result=res))
        dyn_results = []
        for rule in dynamic_rules:
            res = self._install_flow_for_rule(imsi, msisdn, uplink_tunnel,
                                              ip_addr, apn_ambr, rule)
            dyn_results.append(RuleModResult(rule_id=rule.id, result=res))

        # Install a base flow for when no rule is matched.
        self._install_default_flow_for_subscriber(imsi, ip_addr)
        return ActivateFlowsResult(
            static_rule_results=static_results,
            dynamic_rule_results=dyn_results,
        )
Пример #5
0
    def _activate_flows(
        self, request: ActivateFlowsRequest,
        fut: 'Future[ActivateFlowsResult]',
    ) -> None:
        """
        Activate flows for ipv4 / ipv6 or both

        CWF won't have an ip_addr passed
        """
        ret = ActivateFlowsResult()
        if self._service_config['setup_type'] == 'CWF' or request.ip_addr:
            ipv4 = convert_ipv4_str_to_ip_proto(request.ip_addr)
            if request.request_origin.type == RequestOriginType.GX:
                self._update_version(request, ipv4)
                ret_ipv4 = self._install_flows_gx(request, ipv4)
            else:
                ret_ipv4 = self._install_flows_gy(request, ipv4)
            ret.policy_results.extend(ret_ipv4.policy_results)
        if request.ipv6_addr:
            ipv6 = convert_ipv6_bytes_to_ip_proto(request.ipv6_addr)
            self._update_ipv6_prefix_store(request.ipv6_addr)
            if request.request_origin.type == RequestOriginType.GX:
                self._update_version(request, ipv6)
                ret_ipv6 = self._install_flows_gx(request, ipv6)
            else:
                ret_ipv6 = self._install_flows_gy(request, ipv6)
            ret.policy_results.extend(ret_ipv6.policy_results)

        fut.set_result(ret)
Пример #6
0
    def _activate_rules_in_enforcement_stats(
        self,
        imsi: str,
        msisdn: bytes,
        uplink_tunnel: int,
        ip_addr: IPAddress,
        apn_ambr: AggregatedMaximumBitrate,
        policies: List[VersionedPolicy],
        shard_id: int,
        local_f_teid_ng: int = 0,
    ) -> ActivateFlowsResult:
        if not self._service_manager.is_app_enabled(
                EnforcementStatsController.APP_NAME, ):
            return ActivateFlowsResult()

        enforcement_stats_res = self._enforcement_stats.activate_rules(
            imsi,
            msisdn,
            uplink_tunnel,
            ip_addr,
            apn_ambr,
            policies,
            shard_id,
            local_f_teid_ng,
        )
        _report_enforcement_stats_failures(enforcement_stats_res, imsi)
        return enforcement_stats_res
Пример #7
0
    def _activate_flows(self, request: ActivateFlowsRequest,
                        fut: 'Future[ActivateFlowsResult]') -> None:
        """
        Activate flows for ipv4 / ipv6 or both

        CWF won't have an ip_addr passed
        """
        ret = ActivateFlowsResult()
        if self._service_config['setup_type'] == 'CWF' or request.ip_addr:
            ipv4 = convert_ipv4_str_to_ip_proto(request.ip_addr)
            if request.request_origin.type == RequestOriginType.GX:
                ret_ipv4 = self._install_flows_gx(request, ipv4)
            else:
                ret_ipv4 = self._install_flows_gy(request, ipv4)
            ret.static_rule_results.extend(ret_ipv4.static_rule_results)
            ret.dynamic_rule_results.extend(ret_ipv4.dynamic_rule_results)
        if request.ipv6_addr:
            ipv6 = convert_ipv6_bytes_to_ip_proto(request.ipv6_addr)
            self._update_ipv6_prefix_store(request.ipv6_addr)
            if request.request_origin.type == RequestOriginType.GX:
                ret_ipv6 = self._install_flows_gx(request, ipv6)
            else:
                ret_ipv6 = self._install_flows_gy(request, ipv6)
            ret.static_rule_results.extend(ret_ipv6.static_rule_results)
            ret.dynamic_rule_results.extend(ret_ipv6.dynamic_rule_results)
        if request.uplink_tunnel and request.downlink_tunnel:
            self._update_tunnel_map_store(request.uplink_tunnel,
                                          request.downlink_tunnel)

        fut.set_result(ret)
Пример #8
0
    def _activate_rules_in_enforcement_stats(
            self, imsi: str, ip_addr: str, static_rule_ids: List[str],
            dynamic_rules: List[PolicyRule]) -> ActivateFlowsResult:
        if not self._service_manager.is_app_enabled(
                EnforcementStatsController.APP_NAME):
            return ActivateFlowsResult()

        enforcement_stats_res = self._enforcement_stats.activate_rules(
            imsi, ip_addr, static_rule_ids, dynamic_rules)
        _report_enforcement_stats_failures(enforcement_stats_res, imsi)
        return enforcement_stats_res
Пример #9
0
    def activate_rules(self, imsi, ip_addr, static_rule_ids, dynamic_rules,
                       fut):
        """
        Activate the flows for a subscriber based on the rules stored in Redis.
        During activation, a default flow may be installed for the subscriber.

        Args:
            imsi (string): subscriber id
            ip_addr (string): subscriber session ipv4 address
            static_rule_ids (string []): list of static rules to activate
            dynamic_rules (PolicyRule []): list of dynamic rules to activate
            fut (Future): future to wait on the results of flow activations
        """
        if self._datapath is None:
            self.logger.error('Datapath not initialized for adding flows')
            fut.set_result(ActivateFlowsResult(
                static_rule_results=[RuleModResult(
                    rule_id=rule_id,
                    result=RuleModResult.FAILURE,
                ) for rule_id in static_rule_ids],
                dynamic_rule_results=[RuleModResult(
                    rule_id=rule.id,
                    result=RuleModResult.FAILURE,
                ) for rule in dynamic_rules],
            ))
            return
        static_results = []
        for rule_id in static_rule_ids:
            res = self._install_flow_for_static_rule(imsi, ip_addr, rule_id)
            static_results.append(RuleModResult(rule_id=rule_id, result=res))
        dyn_results = []
        for rule in dynamic_rules:
            res = self._install_flow_for_rule(imsi, ip_addr, rule)
            dyn_results.append(RuleModResult(rule_id=rule.id, result=res))

        # Install a base flow for when no rule is matched.
        self._install_default_flow_for_subscriber(imsi)
        fut.set_result(ActivateFlowsResult(
            static_rule_results=static_results,
            dynamic_rule_results=dyn_results,
        ))
Пример #10
0
    def _activate_rules_in_enforcement_stats(
            self, imsi: str, msisdn: bytes, uplink_tunnel: int,
            ip_addr: IPAddress, apn_ambr: AggregatedMaximumBitrate,
            static_rule_ids: List[str],
            dynamic_rules: List[PolicyRule]) -> ActivateFlowsResult:
        if not self._service_manager.is_app_enabled(
                EnforcementStatsController.APP_NAME):
            return ActivateFlowsResult()

        enforcement_stats_res = self._enforcement_stats.activate_rules(
            imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, static_rule_ids,
            dynamic_rules)
        _report_enforcement_stats_failures(enforcement_stats_res, imsi)
        return enforcement_stats_res
Пример #11
0
    def _activate_rules_in_enforcement_stats(
            self, imsi: str, ip_addr: str, static_rule_ids: List[str],
            dynamic_rules: List[PolicyRule]) -> ActivateFlowsResult:
        if not self._service_manager.is_app_enabled(
                EnforcementStatsController.APP_NAME):
            return ActivateFlowsResult()

        fut = Future()  # type: Future[ActivateFlowsResult]
        self._loop.call_soon_threadsafe(self._enforcement_stats.activate_rules,
                                        imsi, ip_addr, static_rule_ids,
                                        dynamic_rules, fut)
        enforcement_stats_res = fut.result()
        _report_enforcement_stats_failures(enforcement_stats_res, imsi)
        return enforcement_stats_res
Пример #12
0
    def ng_update_session_flows(
        self,
        request: SessionSet,
        fut: 'Future(UPFSessionContextState)',
    ) -> UPFSessionContextState:
        """
        Install PDR, FAR and QER flows for the 5G Session send by SMF
        """
        logging.debug(
            'Update 5G Session Flow for SessionID:%s, SessionVersion:%d',
            request.subscriber_id,
            request.session_version,
        )
        # Convert message containing PDR to Named Tuple Rules.
        process_pdr_rules = OrderedDict()
        response = self._ng_servicer_app.ng_session_message_handler(
            request,
            process_pdr_rules,
        )

        # Failure in message processing return failure
        if response.cause_info.cause_ie == CauseIE.REQUEST_ACCEPTED:
            for _, pdr_entries in process_pdr_rules.items():
                # Create the Tunnel
                ret = self._ng_tunnel_update(
                    pdr_entries,
                    request.subscriber_id,
                )
                if ret:
                    # Install the Rules
                    failed_policy_rule_results =\
                            self._ng_qer_update(request, pdr_entries)

                if (not ret or failed_policy_rule_results):
                    offending_ie = OffendingIE(
                        identifier=pdr_entries.pdr_id,
                        version=pdr_entries.pdr_version,
                        qos_enforce_rule_results=ActivateFlowsResult(\
                                               policy_results=[failed_policy_rule_results],
                        ),
                    )

                    # Session information is filled already
                    response.cause_info.cause_ie = CauseIE.RULE_CREATION_OR_MODIFICATION_FAILURE
                    response.failure_rule_id.pdr.extend([offending_ie])
                    break
        fut.set_result(response)
Пример #13
0
    def ActivateFlows(self, request, context):
        """
        Activate flows for a subscriber based on the pre-defined rules
        """
        self._log_grpc_payload(request)
        if not self._service_manager.is_app_enabled(
                EnforcementController.APP_NAME):
            context.set_code(grpc.StatusCode.UNAVAILABLE)
            context.set_details('Service not enabled!')
            return None

        fut = Future()  # type: Future[ActivateFlowsResult]
        self._loop.call_soon_threadsafe(self._activate_flows, request, fut)
        try:
            return fut.result(timeout=self._call_timeout)
        except concurrent.futures.TimeoutError:
            logging.error("ActivateFlows request processing timed out")
            return ActivateFlowsResult()
Пример #14
0
    def DeactivateFlows(self, request, context):
        """
        Deactivate flows for a subscriber
        """
        self._log_grpc_payload(request)
        if not self._service_manager.is_app_enabled(
                EnforcementController.APP_NAME):
            context.set_code(grpc.StatusCode.UNAVAILABLE)
            context.set_details('Service not enabled!')
            return None

        for controller in [self._gy_app, self._enforcer_app,
                           self._enforcement_stats]:
            if not controller.is_controller_ready():
                context.set_code(grpc.StatusCode.UNAVAILABLE)
                context.set_details('Enforcement service not initialized!')
                return ActivateFlowsResult()

        self._loop.call_soon_threadsafe(self._deactivate_flows, request)
        return DeactivateFlowsResult()