예제 #1
0
    def DisableStaticRules(
        self,
        request: DisableStaticRuleRequest,
        context,
    ) -> Void:
        """
        Unassociate the static rules with the specified subscriber.
        Also send a RAR to sessiond to uninstall the specified rules for the
        subscriber.
        """
        try:
            self._subscriberdb_stub.DisableStaticRules(request)
        except grpc.RpcError:
            logging.error('Unable to disable rules for subscriber %s. ',
                          request.imsi)
            context.set_code(grpc.StatusCode.NOT_FOUND)
            context.set_details('Failed to update rule assignments in orc8r')
            return Void()

        rar = PolicyReAuthRequest(
            # Leave session id empty, re-auth for all sessions
            imsi=request.imsi,
            rules_to_remove=self._get_rules(request.rule_ids,
                                            request.base_names)
        )

        success = self._reauth_handler.handle_policy_re_auth(rar)
        if not success:
            context.set_code(grpc.StatusCode.UNKNOWN)
            context.set_details('Failed to enable all static rules for '
                                'subscriber. Partial update may have succeeded')
        return Void()
예제 #2
0
    def test_SuccessfulUpdate(self):
        """
        Test the happy path where updates come in for added rules, and sessiond
        accepts the RAR without issue.
        """
        install_dict = {}
        handler = ReAuthHandler(
            install_dict,
            MockSessionProxyResponderStub(),
        )

        rar = PolicyReAuthRequest(
            imsi='s1',
            rules_to_install=[
                StaticRuleInstall(rule_id=rule_id) for rule_id in ['p1', 'p2']
            ],
        )
        handler.handle_policy_re_auth(rar)
        s1_policies = install_dict['s1'].installed_policies
        expected = 2
        self.assertEqual(
            len(s1_policies),
            expected,
            'There should be 2 installed policies for s1',
        )
        self.assertTrue(
            'p1' in s1_policies,
            'Policy p1 should be marked installed for p1',
        )

        rar = PolicyReAuthRequest(
            imsi='s1',
            rules_to_install=[StaticRuleInstall(rule_id='p3')],
        )
        handler.handle_policy_re_auth(rar)
        s1_policies = install_dict['s1'].installed_policies
        expected = 3
        self.assertEqual(
            len(s1_policies),
            expected,
            'There should be 3 installed policies for s1',
        )
        self.assertTrue(
            'p3' in s1_policies,
            'Policy p1 should be marked installed for p1',
        )
예제 #3
0
 def _generate_rar(
     self,
     subscriber_id: str,
     added_rules: List[str],
     removed_rules: List[str],
 ) -> PolicyReAuthRequest:
     rules_to_install = [
         StaticRuleInstall(rule_id=rule_id) for rule_id in added_rules
     ]
     return PolicyReAuthRequest(
         # Skip the session ID, so apply to all sessions of the subscriber
         imsi=subscriber_id,
         rules_to_install=rules_to_install,
         rules_to_remove=removed_rules,
         # No changes to dynamic rules
         # No event triggers
         # No additional usage monitoring credits
         # No QoS info
     )
예제 #4
0
    def create_ReAuthRequest(self, imsi, policy_id, flow_list, qos):
        """
        Sends Policy RAR message to session manager
        """
        print("Sending Policy RAR message to session manager")
        flow_match_list = []
        res = None
        self.get_flow_match(flow_list, flow_match_list)

        policy_qos = FlowQos(
            qci=qos["qci"],
            max_req_bw_ul=qos["max_req_bw_ul"],
            max_req_bw_dl=qos["max_req_bw_dl"],
            gbr_ul=qos["gbr_ul"],
            gbr_dl=qos["gbr_dl"],
            arp=QosArp(
                priority_level=qos["arp_prio"],
                pre_capability=qos["pre_cap"],
                pre_vulnerability=qos["pre_vul"],
            ),
        )

        policy_rule = PolicyRule(
            id=policy_id,
            priority=qos["priority"],
            flow_list=flow_match_list,
            tracking_type=PolicyRule.NO_TRACKING,
            rating_group=1,
            monitoring_key=None,
            qos=policy_qos,
        )

        qos = QoSInformation(qci=qos["qci"])

        # Get sessionid
        req = GetDirectoryFieldRequest(id=imsi, field_key="session_id")
        try:
            res = self._directorydstub.GetDirectoryField(
                req, DEFAULT_GRPC_TIMEOUT)
        except grpc.RpcError as err:
            logging.error(
                "GetDirectoryFieldRequest error for id: %s! [%s] %s",
                imsi,
                err.code(),
                err.details(),
            )

        self._session_stub.PolicyReAuth(
            PolicyReAuthRequest(
                session_id=res.value,
                imsi=imsi,
                rules_to_remove=[],
                rules_to_install=[],
                dynamic_rules_to_install=[
                    DynamicRuleInstall(policy_rule=policy_rule)
                ],
                event_triggers=[],
                revalidation_time=None,
                usage_monitoring_credits=[],
                qos_info=qos,
            ))
예제 #5
0
    def test_reauth(self):
        """
        Send a Gx reauth request which installs one new static rule, one new
        dynamic rule, and removes one static and one dynamic rule.
        """
        dynamic_rule1 = create_uplink_rule('dynamic1',
                                           1,
                                           '46.10.10.1',
                                           tracking=PolicyRule.NO_TRACKING)
        dynamic_rule2 = create_uplink_rule('dynamic2',
                                           1,
                                           '46.10.10.2',
                                           tracking=PolicyRule.NO_TRACKING)

        # Initialize sub with 1 static and 1 dynamic rule
        sub = SubContextConfig('IMSI001010000088888', '192.168.128.74',
                               default_ambr_config, 4)
        self.test_util.controller.mock_create_session = Mock(
            return_value=CreateSessionResponse(
                credits=[create_update_response(sub.imsi, 1, 1024)],
                static_rules=[
                    session_manager_pb2.StaticRuleInstall(rule_id='policy1')
                ],
                dynamic_rules=[
                    session_manager_pb2.DynamicRuleInstall(
                        policy_rule=dynamic_rule1)
                ],
                usage_monitors=[],
            ), )
        self.test_util.controller.mock_terminate_session = Mock(
            return_value=SessionTerminateResponse(), )
        self.test_util.sessiond.CreateSession(
            LocalCreateSessionRequest(
                sid=SubscriberID(id=sub.imsi),
                ue_ipv4=sub.ip,
            ))
        self.assertEqual(
            self.test_util.controller.mock_create_session.call_count,
            1,
        )

        # first, send some packets so we know that the uplink rules are
        # accepting traffic
        self._assert_rules(
            sub,
            [
                session_manager_pb2.DynamicRuleInstall(
                    policy_rule=self.test_util.static_rules['policy1']),
                session_manager_pb2.DynamicRuleInstall(
                    policy_rule=dynamic_rule1)
            ],
        )

        # Now via reauth, remove the old rules and install new uplink rules
        # Verify the new uplink rules allow traffic
        reauth_result = self.test_util.proxy_responder.PolicyReAuth(
            PolicyReAuthRequest(
                imsi=sub.imsi,
                rules_to_remove=['dynamic1', 'policy1'],
                rules_to_install=[
                    session_manager_pb2.StaticRuleInstall(rule_id='policy2')
                ],
                dynamic_rules_to_install=[
                    session_manager_pb2.DynamicRuleInstall(
                        policy_rule=dynamic_rule2)
                ],
            ))
        self.assertEqual(
            reauth_result.result,
            session_manager_pb2.UPDATE_INITIATED,
        )
        self.assertEqual(len(reauth_result.failed_rules), 0)
        self._assert_rules(
            sub,
            [
                session_manager_pb2.DynamicRuleInstall(
                    policy_rule=self.test_util.static_rules['policy2']),
                session_manager_pb2.DynamicRuleInstall(
                    policy_rule=dynamic_rule2)
            ],
        )

        # Verify the old rules no longer allow traffic (uninstalled)
        self._assert_rules(
            sub,
            [
                session_manager_pb2.DynamicRuleInstall(
                    policy_rule=self.test_util.static_rules['policy1']),
                session_manager_pb2.DynamicRuleInstall(
                    policy_rule=dynamic_rule1)
            ],
            expected=0,
        )
예제 #6
0
    def create_ReAuthRequest(self, imsi, policy_id, flow_list, qos):
        """
        Sends Policy RAR message to session manager
        """
        print("Sending Policy RAR message to session manager")
        flow_match_list = []
        res = None
        self.get_flow_match(flow_list, flow_match_list)

        policy_qos = FlowQos(
            qci=qos["qci"],
            max_req_bw_ul=qos["max_req_bw_ul"],
            max_req_bw_dl=qos["max_req_bw_dl"],
            gbr_ul=qos["gbr_ul"],
            gbr_dl=qos["gbr_dl"],
            arp=QosArp(
                priority_level=qos["arp_prio"],
                pre_capability=qos["pre_cap"],
                pre_vulnerability=qos["pre_vul"],
            ),
        )

        policy_rule = PolicyRule(
            id=policy_id,
            priority=qos["priority"],
            flow_list=flow_match_list,
            tracking_type=PolicyRule.NO_TRACKING,
            rating_group=1,
            monitoring_key=None,
            qos=policy_qos,
        )

        qos = QoSInformation(qci=qos["qci"])

        # Get sessionid
        #TODO: remove retries
        i = 0
        MAX = 3
        res = None
        while i < MAX:
            req = GetDirectoryFieldRequest(id=imsi, field_key="session_id")
            try:
                res = self._directorydstub.GetDirectoryField(
                    req, DEFAULT_GRPC_TIMEOUT)
            except grpc.RpcError as err:
                print(
                    "error: GetDirectoryFieldRequest error for id: %s! [%s] %s",
                    imsi,
                    err.code(),
                    err.details(),
                )
            if req != None:
                i = MAX
            else:
                i += 1
                print(
                    "warning: directoryd failed to return sessionId for %s. Retrying",
                    imsi)
                time.sleep(3)

        if res == None:
            print("error: Couldnt find sessionid. Directoryd content:")
            allRecordsResponse = self._directorydstub.GetAllDirectoryRecords(
                Void(), DEFAULT_GRPC_TIMEOUT)
            for record in allRecordsResponse.recordsResponse:
                print("%s", str(record))

        self._session_stub.PolicyReAuth(
            PolicyReAuthRequest(
                session_id=res.value,
                imsi=imsi,
                rules_to_remove=[],
                rules_to_install=[],
                dynamic_rules_to_install=[
                    DynamicRuleInstall(policy_rule=policy_rule)
                ],
                event_triggers=[],
                revalidation_time=None,
                usage_monitoring_credits=[],
                qos_info=qos,
            ))
예제 #7
0
def send_policy_rar(client, args):
    sessiond_chan = ServiceRegistry.get_rpc_channel("sessiond", ServiceRegistry.LOCAL)
    sessiond_client = SessionProxyResponderStub(sessiond_chan)
    flow_list_str = args.flow_rules.split(";")
    flow_match_list = []
    for i, flow_str in enumerate(flow_list_str):
        print("%d: %s" % (i, flow_str))
        flow_fields = flow_str.split(",")
        if flow_fields[0] == "UL":
            flow_direction = FlowMatch.UPLINK
        elif flow_fields[0] == "DL":
            flow_direction = FlowMatch.DOWNLINK
        else:
            print("%s is not valid" % flow_fields[0])
            raise ValueError(
                "UL or DL are the only valid"
                " values for first parameter of flow match"
            )
        ip_protocol = int(flow_fields[1])
        if flow_fields[1] == FlowMatch.IPPROTO_TCP:
            udp_src_port = 0
            udp_dst_port = 0
            if flow_fields[3]:
                tcp_src_port = int(flow_fields[3])
            else:
                tcp_src_port = 0
            if flow_fields[5]:
                tcp_dst_port = int(flow_fields[5])
            else:
                tcp_dst_port = 0
        elif flow_fields[1] == FlowMatch.IPPROTO_UDP:
            tcp_src_port = 0
            tcp_dst_port = 0
            if flow_fields[3]:
                udp_src_port = int(flow_fields[3])
            else:
                udp_src_port = 0
            if flow_fields[5]:
                udp_dst_port = int(flow_fields[5])
            else:
                udp_dst_port = 0
        else:
            udp_src_port = 0
            udp_dst_port = 0
            tcp_src_port = 0
            tcp_dst_port = 0

        flow_match_list.append(
            FlowDescription(
                match=FlowMatch(
                    direction=flow_direction,
                    ip_proto=ip_protocol,
                    ipv4_src=flow_fields[2],
                    ipv4_dst=flow_fields[4],
                    tcp_src=tcp_src_port,
                    tcp_dst=tcp_dst_port,
                    udp_src=udp_src_port,
                    udp_dst=udp_dst_port,
                ),
                action=FlowDescription.PERMIT,
            )
        )

    qos_parameter_list = args.qos.split(",")
    if len(qos_parameter_list) == 7:
        # utilize user passed arguments
        policy_qos = FlowQos(
            qci=int(args.qci),
            max_req_bw_ul=int(qos_parameter_list[0]),
            max_req_bw_dl=int(qos_parameter_list[1]),
            gbr_ul=int(qos_parameter_list[2]),
            gbr_dl=int(qos_parameter_list[3]),
            arp=QosArp(
                priority_level=int(qos_parameter_list[4]),
                pre_capability=int(qos_parameter_list[5]),
                pre_vulnerability=int(qos_parameter_list[6]),
            ),
        )
    else:
        # parameter missing, use default values
        policy_qos = FlowQos(
            qci=int(args.qci),
            max_req_bw_ul=100000,
            max_req_bw_dl=100000,
            arp=QosArp(priority_level=1, pre_capability=1, pre_vulnerability=0),
        )

    policy_rule = PolicyRule(
        id=args.policy_id,
        priority=int(args.priority),
        flow_list=flow_match_list,
        tracking_type=PolicyRule.NO_TRACKING,
        rating_group=1,
        monitoring_key=None,
        qos=policy_qos,
    )

    qos = QoSInformation(qci=int(args.qci))

    reauth_result = sessiond_client.PolicyReAuth(
        PolicyReAuthRequest(
            session_id=args.session_id,
            imsi=args.imsi,
            rules_to_remove=[],
            rules_to_install=[],
            dynamic_rules_to_install=[DynamicRuleInstall(policy_rule=policy_rule)],
            event_triggers=[],
            revalidation_time=None,
            usage_monitoring_credits=[],
            qos_info=qos,
        )
    )
    print(reauth_result)