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()
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', )
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 )
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, ))
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, )
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, ))
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)