def test_deny_rule_install(self): """ Adds a policy to a subscriber. Verifies that flows are properly installed in enforcement and enforcement stats. Assert: Policy classification flows installed in enforcement Policy match flows installed in enforcement_stats """ fake_controller_setup(self.enforcement_controller, self.enforcement_stats_controller) imsi = 'IMSI001010000000014' sub_ip = '192.16.15.7' num_pkt_unmatched = 4096 flow_list = [ FlowDescription(match=FlowMatch( ip_dst=convert_ipv4_str_to_ip_proto('1.1.0.0/24'), direction=FlowMatch.UPLINK), action=FlowDescription.DENY) ] policy = PolicyRule(id='rule1', priority=3, flow_list=flow_list) self.service_manager.session_rule_version_mapper.update_version( imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1') """ Setup subscriber, setup table_isolation to fwd pkts """ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._main_tbl_num, self.enforcement_stats_controller).add_dynamic_rule(policy) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber( sub_context.cfg).build_requests(), self.testing_controller) pkt_sender = ScapyPacketInjector(self.IFACE) packet = IPPacketBuilder() \ .set_ip_layer('45.10.0.0/20', sub_ip) \ .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00") \ .build() # =========================== Verification =========================== # Verifies that 1 flow is installed in enforcement and 2 flows are # installed in enforcement stats, one for uplink and one for downlink. snapshot_verifier = SnapshotVerifier(self, self.BRIDGE, self.service_manager) with isolator, sub_context, snapshot_verifier: pkt_sender.send(packet) enf_stat_name = imsi + '|' + self.DEFAULT_DROP_FLOW_NAME + '|' + sub_ip wait_for_enforcement_stats(self.enforcement_stats_controller, [enf_stat_name]) stats = get_enforcement_stats( self.enforcement_stats_controller._report_usage.call_args_list) self.assertEqual(stats[enf_stat_name].sid, imsi) self.assertEqual(stats[enf_stat_name].rule_id, self.DEFAULT_DROP_FLOW_NAME) self.assertEqual(stats[enf_stat_name].dropped_rx, 0) self.assertEqual(stats[enf_stat_name].dropped_tx, num_pkt_unmatched * len(packet))
def activate_flows(client, args): request = ActivateFlowsRequest( sid=SIDUtils.to_pb(args.imsi), ip_addr=args.ipv4, policies=[ VersionedPolicy( rule=PolicyRule( id=args.rule_id, priority=args.priority, hard_timeout=args.hard_timeout, flow_list=[ FlowDescription( match=FlowMatch( ip_dst=convert_ipv4_str_to_ip_proto(args.ipv4_dst), direction=FlowMatch.UPLINK, ), ), FlowDescription( match=FlowMatch( ip_src=convert_ipv4_str_to_ip_proto(args.ipv4_dst), direction=FlowMatch.DOWNLINK, ), ), ], ), version=1, ), ], request_origin=RequestOriginType(type=RequestOriginType.GX), shard_id=args.shard_id, ) response = client.ActivateFlows(request) _print_rule_mod_results(response.policy_results)
def add_rule(args): rule_id = args.rule_id policy_dict = PolicyRuleDict() arg_list = { 'ip_proto': args.ip_proto, 'ip_dst': IPAddress(version=IPAddress.IPV4, address=args.ipv4_dst.encode('utf-8')), 'ip_src': IPAddress(version=IPAddress.IPV4, address=args.ipv4_src.encode('utf-8')), 'tcp_dst': args.tcp_dst, 'tcp_src': args.tcp_src, 'udp_dst': args.udp_dst, 'udp_src': args.udp_src, 'direction': args.direction } match = FlowMatch(**arg_list) flow = FlowDescription(match=match, action=args.action) rule = policy_dict.get(rule_id) if not rule or args.overwrite: action = 'add' rule = PolicyRule(id=rule_id, flow_list=[flow]) else: action = 'edit' rule.flow_list.extend([flow]) policy_dict[rule_id] = rule print("Rule '%s' successfully %sed!" % (rule_id, action))
def create_uplink_rule(id, rating_group, ip_dest, m_key=None, priority=10, tracking=PolicyRule.ONLY_OCS, action=FlowDescription.PERMIT): """ Create a rule with a single uplink IP flow, useful for testing Args: id (string): rule id rating_group (int): charging key ip_dest (string): IP destination for rule flow m_key (optional string): monitoring key, if the rule is tracked by PCRF priority (int): priority of flow, the greater the higher the priority tracking (PolicyRule.TrackingType): enum to dictate whether OCS or PCRF or both is tracking the credit action: permit or deny Returns: PolicyRule with single uplink IP flow """ return PolicyRule( id=id, priority=priority, flow_list=[ FlowDescription(match=FlowMatch(ipv4_dst=ip_dest, direction=FlowMatch.UPLINK), action=action) ], tracking_type=tracking, rating_group=rating_group, monitoring_key=m_key, )
def test_invalid_subscriber(self): """ Try to apply an invalid policy to a subscriber, should log and error Assert: Only 1 flow gets added to the table (drop flow) """ fake_controller_setup(self.enforcement_controller) imsi = 'IMSI000000000000001' sub_ip = '192.168.128.45' flow_list = [ FlowDescription(match=FlowMatch( ip_src=convert_ipv4_str_to_ip_proto('9999.0.0.0/24')), action=FlowDescription.DENY) ] policy = PolicyRule(id='invalid', priority=2, flow_list=flow_list) invalid_sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._tbl_num).add_dynamic_rule(policy) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber( invalid_sub_context.cfg).build_requests(), self.testing_controller) flow_query = FlowQuery(self._tbl_num, self.testing_controller) num_flows_start = len(flow_query.lookup()) snapshot_verifier = SnapshotVerifier(self, self.BRIDGE, self.service_manager) with isolator, invalid_sub_context, snapshot_verifier: wait_after_send(self.testing_controller) num_flows_final = len(flow_query.lookup()) self.assertEqual(num_flows_final - num_flows_start, 0)
def test_rule_install(self): """ Adds a policy to a subscriber. Verifies that flows are properly installed in enforcement and enforcement stats. Assert: Policy classification flows installed in enforcement Policy match flows installed in enforcement_stats """ fake_controller_setup(self.enforcement_controller, self.enforcement_stats_controller) imsi = 'IMSI001010000000013' sub_ip = '192.168.128.74' flow_list = [ FlowDescription(match=FlowMatch(ipv4_dst='45.10.0.0/25', direction=FlowMatch.UPLINK), action=FlowDescription.PERMIT) ] policy = PolicyRule(id='rule1', priority=3, flow_list=flow_list) self.service_manager.session_rule_version_mapper.update_version( imsi, 'rule1') version = \ self.service_manager.session_rule_version_mapper.get_version( imsi, 'rule1') """ Setup subscriber, setup table_isolation to fwd pkts """ self._static_rule_dict[policy.id] = policy sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._main_tbl_num, self.enforcement_stats_controller).add_static_rule(policy.id) # =========================== Verification =========================== rule_num = self.enforcement_stats_controller._rule_mapper \ .get_or_create_rule_num(policy.id) enf_query = FlowQuery(self._main_tbl_num, self.testing_controller, match=flow_match_to_magma_match( FlowMatch(ipv4_dst='45.10.0.0/25', direction=FlowMatch.UPLINK)), cookie=rule_num) es_query = FlowQuery(self._scratch_tbl_num, self.testing_controller, match=MagmaMatch(imsi=encode_imsi(imsi), reg2=rule_num, rule_version=version), cookie=rule_num) # Verifies that 1 flow is installed in enforcement and 2 flows are # installed in enforcement stats, one for uplink and one for downlink. flow_verifier = FlowVerifier([ FlowTest(enf_query, 0, flow_count=1), FlowTest(es_query, 0, flow_count=2), ], lambda: None) snapshot_verifier = SnapshotVerifier(self, self.BRIDGE, self.service_manager) with sub_context, flow_verifier, snapshot_verifier: pass flow_verifier.verify()
def create_bearer(self, imsi, lbi): """ Sends a CreateBearer Request to SPGW service """ print('Sending CreateBearer request to spgw service') req = CreateBearerRequest( sid=SIDUtils.to_pb(imsi), link_bearer_id=lbi, policy_rules=[ PolicyRule( qos=FlowQos( qci=1, gbr_ul=10000000, gbr_dl=10000000, max_req_bw_ul=10000000, max_req_bw_dl=10000000, arp=QosArp( priority_level=1, pre_capability=1, pre_vulnerability=0, ) ) ) ] ) self._stub.CreateBearer(req)
def test_redirect_policy(self): """ Add a redirect policy, verifies that EnforcementStatsController reports correct stats to sessiond Assert: 1 Packet is matched and reported """ fake_controller_setup(self.enforcement_controller, self.enforcement_stats_controller) redirect_ips = ["185.128.101.5", "185.128.121.4"] self.enforcement_controller._redirect_manager._dns_cache.get( "about.sha.ddih.org", lambda: redirect_ips, max_age=42) imsi = 'IMSI010000000088888' sub_ip = '192.168.128.74' flow_list = [FlowDescription(match=FlowMatch())] policy = PolicyRule(id='redir_test', priority=3, flow_list=flow_list, redirect=RedirectInformation( support=1, address_type=2, server_address="http://about.sha.ddih.org/")) stat_name = imsi + '|redir_test' + '|' + sub_ip self.service_manager.session_rule_version_mapper.update_version( imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'redir_test') """ Setup subscriber, setup table_isolation to fwd pkts """ self._static_rule_dict[policy.id] = policy sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._main_tbl_num, self.enforcement_stats_controller).add_dynamic_rule(policy) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber( sub_context.cfg).build_requests(), self.testing_controller) pkt_sender = ScapyPacketInjector(self.IFACE) packet = TCPPacketBuilder() \ .set_tcp_layer(42132, 80, 321) \ .set_tcp_flags("S") \ .set_ip_layer('151.42.41.122', sub_ip) \ .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00") \ .build() # =========================== Verification =========================== snapshot_verifier = SnapshotVerifier(self, self.BRIDGE, self.service_manager) """ Send packet, wait until pkts are received by ovs and enf stats """ with isolator, sub_context, snapshot_verifier: self.enforcement_stats_controller._report_usage.reset_mock() pkt_sender.send(packet) wait_for_enforcement_stats(self.enforcement_stats_controller, [stat_name]) """ Send packets, wait until pkts are received by ovs and enf stats """ stats = get_enforcement_stats( self.enforcement_stats_controller._report_usage.call_args_list) self.assertEqual(stats[stat_name].sid, imsi) self.assertEqual(stats[stat_name].rule_id, "redir_test") self.assertEqual(stats[stat_name].bytes_rx, 0) self.assertEqual(stats[stat_name].bytes_tx, len(packet))
def test_subscriber_restrict_policy(self): """ Add restrict policy to subscriber, send 4096 packets Assert: Packets are properly matched with the 'restrict_match' policy Send /20 (4096) packets, match /16 (256) packets """ fake_controller_setup(self.gy_controller) imsi = 'IMSI010000000088888' sub_ip = '192.168.128.74' flow_list1 = [ FlowDescription(match=FlowMatch( ip_dst=convert_ipv4_str_to_ip_proto('8.8.8.0/24'), direction=FlowMatch.UPLINK), action=FlowDescription.PERMIT) ] policies = [ VersionedPolicy( rule=PolicyRule(id='restrict_match', priority=2, flow_list=flow_list1), version=1, ) ] pkts_matched = 256 pkts_sent = 4096 # ============================ Subscriber ============================ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.gy_controller, self._tbl_num).add_policy(policies[0]) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber( sub_context.cfg).build_requests(), self.testing_controller) pkt_sender = ScapyPacketInjector(self.IFACE) packet = IPPacketBuilder()\ .set_ip_layer('8.8.8.8', sub_ip)\ .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\ .build() flow_query = FlowQuery(self._tbl_num, self.testing_controller, match=flow_match_to_magma_match( flow_list1[0].match)) # =========================== Verification =========================== # Verify aggregate table stats, subscriber 1 'simple_match' pkt count flow_verifier = FlowVerifier([ FlowTest(FlowQuery(self._tbl_num, self.testing_controller), pkts_sent), FlowTest(flow_query, pkts_matched) ], lambda: wait_after_send(self.testing_controller)) snapshot_verifier = SnapshotVerifier(self, self.BRIDGE, self.service_manager, include_stats=False) with isolator, sub_context, flow_verifier, snapshot_verifier: pkt_sender.send(packet)
def test_cookie_poll(self): """ Add a subscriber policy, verify flows are properly installed Assert: Query with RULE_NUM 1 returns proper values """ original = self.enforcement_stats_controller._poll_stats self.enforcement_stats_controller._poll_stats = MagicMock() self.enforcement_stats_controller.init_finished = False self.enforcement_controller.init_finished = True imsi = 'IMSI001010000000013' sub_ip = '192.168.128.74' flow_list = [ FlowDescription( match=FlowMatch( ip_dst=convert_ipv4_str_to_ip_proto('45.10.0.0/25'), direction=FlowMatch.UPLINK, ), action=FlowDescription.PERMIT, ), ] policy = VersionedPolicy( rule=PolicyRule(id='rule1', priority=3, flow_list=flow_list), version=1, ) enf_stat_name = imsi + '|' + 'rule1' + '|' + sub_ip + '|' + "1" """ Setup subscriber, setup table_isolation to fwd pkts """ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._main_tbl_num, self.enforcement_stats_controller, ).add_policy(policy) snapshot_verifier = SnapshotVerifier( self, self.BRIDGE, self.service_manager, ) self.enforcement_stats_controller._report_usage.reset_mock() with sub_context, snapshot_verifier: self.enforcement_stats_controller.init_finished = True flows.send_stats_request( self.enforcement_stats_controller._datapath, self.enforcement_stats_controller.tbl_num, 0, flows.OVS_COOKIE_MATCH_ALL, ) wait_for_enforcement_stats( self.enforcement_stats_controller, [enf_stat_name], ) stats = get_enforcement_stats( self.enforcement_stats_controller._report_usage.call_args_list, ) self.assertEqual(stats[enf_stat_name].rule_id, 'rule1') self.enforcement_stats_controller._poll_stats = original self.assertEqual(len(stats), 2)
def test_subscriber_ipv6_policy(self): """ Add policy to subscriber, send 4096 packets Assert: Packets are properly matched with the 'simple_match' policy Send /20 (4096) packets, match /16 (256) packets """ fake_controller_setup(self.enforcement_controller) imsi = 'IMSI010000000088888' sub_ip = 'de34:431d:1bc::' flow_list1 = [ FlowDescription( match=FlowMatch( ip_dst=convert_ipv6_bytes_to_ip_proto( 'f333:432::dbca'.encode('utf-8'), ), direction=FlowMatch.UPLINK, ), action=FlowDescription.PERMIT, ), ] policies = [ VersionedPolicy( rule=PolicyRule(id='simple_match', priority=2, flow_list=flow_list1), version=1, ), ] # ============================ Subscriber ============================ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._tbl_num, ).add_policy(policies[0]) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber( sub_context.cfg).build_requests(), self.testing_controller, ) pkt_sender = ScapyPacketInjector(self.IFACE) packet = IPv6PacketBuilder() \ .set_ip_layer('f333:432::dbca', sub_ip) \ .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00") \ .build() # =========================== Verification =========================== snapshot_verifier = SnapshotVerifier( self, self.BRIDGE, self.service_manager, ) with isolator, sub_context, snapshot_verifier: pkt_sender.send(packet)
def test_poll(self): """ Unit test to help verify stats polling using cookie and cookie_mask """ fake_controller_setup( self.enforcement_controller, self.enforcement_stats_controller, ) imsi = 'IMSI001010000000013' sub_ip = '192.168.128.74' flow_list = [ FlowDescription( match=FlowMatch( ip_dst=convert_ipv4_str_to_ip_proto('45.10.0.0/25'), direction=FlowMatch.UPLINK, ), action=FlowDescription.PERMIT, ), ] policy = VersionedPolicy( rule=PolicyRule(id='rule1', priority=3, flow_list=flow_list), version=1, ) self.service_manager.session_rule_version_mapper.save_version( imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1', 1, ) """ Setup subscriber, setup table_isolation to fwd pkts """ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._main_tbl_num, self.enforcement_stats_controller, ).add_policy(policy) snapshot_verifier = SnapshotVerifier( self, self.BRIDGE, self.service_manager, ) with sub_context, snapshot_verifier: rule_map = self.enforcement_stats_controller.get_stats() if (rule_map.records[0].rule_id == self.DEFAULT_DROP_FLOW_NAME): rule_record = rule_map.records[1] else: rule_record = rule_map.records[0] self.assertEqual(rule_record.sid, imsi) self.assertEqual(rule_record.rule_id, "rule1") self.assertEqual(rule_record.bytes_tx, 0) self.assertEqual(rule_record.bytes_rx, 0) rule_map_cookie = self.enforcement_stats_controller.get_stats(1, 0) if (rule_map_cookie.records[0].rule_id == self.DEFAULT_DROP_FLOW_NAME): rule_record_cookie = rule_map_cookie.records[1] else: rule_record_cookie = rule_map_cookie.records[0] self.assertEqual(rule_record_cookie.sid, imsi) self.assertEqual(rule_record_cookie.rule_id, "rule1") self.assertEqual(rule_record_cookie.bytes_tx, 0) self.assertEqual(rule_record_cookie.bytes_rx, 0)
def CreateAddQERinPDR( qos_enforce_rule: QoSEnforceRuleEntry, ue_ip_addr: str, apn_ambr: AggregatedMaximumBitrate, ) -> ActivateFlowsRequest: if qos_enforce_rule.allow == 'YES': allow = FlowDescription.PERMIT else: allow = FlowDescription.DENY ip_dst = None ip_src = None if qos_enforce_rule.ipv4_dst: ip_dst = convert_ipv4_str_to_ip_proto(qos_enforce_rule.ipv4_dst) ip_src = convert_ipv4_str_to_ip_proto(qos_enforce_rule.ipv4_dst) if qos_enforce_rule.direction == FlowMatch.UPLINK: flow_list = [ FlowDescription( match=FlowMatch( ip_dst=ip_dst, direction=qos_enforce_rule.direction, ), action=allow, ), ] else: flow_list = [ FlowDescription( match=FlowMatch( ip_src=ip_src, direction=qos_enforce_rule.direction, ), action=allow, ), ] qos_enforce_rule = ActivateFlowsRequest( sid=SIDUtils.to_pb(qos_enforce_rule.imsi), ip_addr=ue_ip_addr, policies=[ VersionedPolicy( rule=PolicyRule( id=qos_enforce_rule.rule_id, priority=qos_enforce_rule.priority, hard_timeout=qos_enforce_rule.hard_timeout, flow_list=flow_list, ), version=1, ), ], request_origin=RequestOriginType(type=RequestOriginType.N4), apn_ambr=apn_ambr, ) return qos_enforce_rule
def test_rule_install(self): """ Adds a policy to a subscriber. Verifies that flows are properly installed in enforcement and enforcement stats. Assert: Policy classification flows installed in enforcement Policy match flows installed in enforcement_stats """ fake_controller_setup( self.enforcement_controller, self.enforcement_stats_controller, ) imsi = 'IMSI001010000000013' sub_ip = '192.168.128.74' flow_list = [ FlowDescription( match=FlowMatch( ip_dst=convert_ipv4_str_to_ip_proto('45.10.0.0/25'), direction=FlowMatch.UPLINK, ), action=FlowDescription.PERMIT, ), ] policy = VersionedPolicy( rule=PolicyRule(id='rule1', priority=3, flow_list=flow_list), version=1, ) self.service_manager.session_rule_version_mapper.save_version( imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1', 1, ) """ Setup subscriber, setup table_isolation to fwd pkts """ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._main_tbl_num, self.enforcement_stats_controller, ).add_policy(policy) # =========================== Verification =========================== # Verifies that 1 flow is installed in enforcement and 2 flows are # installed in enforcement stats, one for uplink and one for downlink. snapshot_verifier = SnapshotVerifier( self, self.BRIDGE, self.service_manager, ) with sub_context, snapshot_verifier: pass
def test_ipv6_rule_install(self): """ Adds a ipv6 policy to a subscriber. Verifies that flows are properly installed in enforcement and enforcement stats. Assert: Policy classification flows installed in enforcement Policy match flows installed in enforcement_stats """ fake_controller_setup( self.enforcement_controller, self.enforcement_stats_controller, ) imsi = 'IMSI001010000000013' sub_ip = 'de34:431d:1bc::' flow_list = [ FlowDescription( match=FlowMatch( ip_dst=convert_ipv6_bytes_to_ip_proto( 'f333:432::dbca'.encode('utf-8'), ), direction=FlowMatch.UPLINK, ), action=FlowDescription.PERMIT, ), ] policy = VersionedPolicy( rule=PolicyRule(id='rule1', priority=3, flow_list=flow_list), version=1, ) self.service_manager.session_rule_version_mapper.save_version( imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1', 1, ) """ Setup subscriber, setup table_isolation to fwd pkts """ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._main_tbl_num, self.enforcement_stats_controller, ).add_policy(policy) # =========================== Verification =========================== snapshot_verifier = SnapshotVerifier( self, self.BRIDGE, self.service_manager, ) with sub_context, snapshot_verifier: pass
def test_activate_flows_req(self): rule = PolicyRule(id="rule1", priority=100, flow_list=[]) policies = [VersionedPolicy(rule=rule, version=1)] req = ActivateFlowsRequest( sid=SubscriberID(id="imsi12345"), ip_addr="1.2.3.4", msisdn=b'magma', uplink_tunnel=0x1, downlink_tunnel=0x2, policies=policies, ) ip_addr = IPAddress( version=IPAddress.IPV4, address=req.ip_addr.encode('utf-8'), ) self.pipelined_srv.ActivateFlows(req, MagicMock()) # Not using assert_called_with because protos comparison assert self._enforcement_stats.activate_rules.call_args.args[ 0] == req.sid.id assert self._enforcement_stats.activate_rules.call_args.args[ 1] == req.msisdn assert self._enforcement_stats.activate_rules.call_args.args[ 2] == req.uplink_tunnel assert self._enforcement_stats.activate_rules.call_args.args[ 3].version == ip_addr.version assert self._enforcement_stats.activate_rules.call_args.args[ 3].address == ip_addr.address assert self._enforcement_stats.activate_rules.call_args.args[ 4] == req.apn_ambr assert self._enforcement_stats.activate_rules.call_args.args[5][ 0].version == policies[0].version assert self._enforcement_stats.activate_rules.call_args.args[ 6] == req.shard_id assert self._enforcement_stats.activate_rules.call_args.args[7] == 0 assert self._enforcer_app.activate_rules.call_args.args[ 0] == req.sid.id assert self._enforcer_app.activate_rules.call_args.args[ 1] == req.msisdn assert self._enforcer_app.activate_rules.call_args.args[ 2] == req.uplink_tunnel assert self._enforcer_app.activate_rules.call_args.args[ 3].version == ip_addr.version assert self._enforcer_app.activate_rules.call_args.args[ 3].address == ip_addr.address assert self._enforcer_app.activate_rules.call_args.args[ 4] == req.apn_ambr assert self._enforcer_app.activate_rules.call_args.args[5][ 0].version == policies[0].version assert self._enforcer_app.activate_rules.call_args.args[ 6] == req.shard_id assert self._enforcer_app.activate_rules.call_args.args[7] == 0
def _get_redirect_policies(self): """ Policy to redirect traffic to the captive portal """ redirect_info = RedirectInformation( support=RedirectInformation.ENABLED, address_type=RedirectInformation.URL, server_address=self._captive_portal_address) return [ PolicyRule(id='redirect', priority=self.REDIRECT_PRIORITY, redirect=redirect_info) ]
def test_subscriber_policy(self): """ Add policy to subscriber, send 4096 packets Assert: Packets are properly matched with the 'simple_match' policy Send /20 (4096) packets, match /16 (256) packets """ imsi = 'IMSI010000000088888' sub_ip = '192.168.128.74' flow_list1 = [FlowDescription( match=FlowMatch( ipv4_dst='45.10.0.0/24', direction=FlowMatch.UPLINK), action=FlowDescription.PERMIT) ] policies = [ PolicyRule(id='simple_match', priority=2, flow_list=flow_list1) ] pkts_matched = 256 pkts_sent = 4096 self._static_rule_dict[policies[0].id] = policies[0] # ============================ Subscriber ============================ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._tbl_num ).add_static_rule(policies[0].id) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg) .build_requests(), self.testing_controller ) pkt_sender = ScapyPacketInjector(self.IFACE) packet = IPPacketBuilder()\ .set_ip_layer('45.10.0.0/20', sub_ip)\ .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\ .build() flow_query = FlowQuery( self._tbl_num, self.testing_controller, match=flow_match_to_magma_match(flow_list1[0].match) ) # =========================== Verification =========================== # Verify aggregate table stats, subscriber 1 'simple_match' pkt count flow_verifier = FlowVerifier([ FlowTest(FlowQuery(self._tbl_num, self.testing_controller), pkts_sent), FlowTest(flow_query, pkts_matched) ], lambda: wait_after_send(self.testing_controller)) with isolator, sub_context, flow_verifier: pkt_sender.send(packet) flow_verifier.verify()
def test_subscriber_redirect_policy(self): """ Add redirect policy to subscriber, send 4096 packets Assert: Packets are properly matched with the 'simple_match' policy Send /20 (4096) packets, match /16 (256) packets """ fake_controller_setup(self.gy_controller) imsi = 'IMSI010000000088888' sub_ip = '192.168.128.74' redirect_ips = ["185.128.101.5", "185.128.121.4"] self.gy_controller._redirect_manager._dns_cache.get( "about.sha.ddih.org", lambda: redirect_ips, max_age=42, ) flow_list = [FlowDescription(match=FlowMatch())] policy = VersionedPolicy( rule=PolicyRule( id='redir_test', priority=3, flow_list=flow_list, redirect=RedirectInformation( support=1, address_type=2, server_address="http://about.sha.ddih.org/", ), ), version=1, ) # ============================ Subscriber ============================ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.gy_controller, self._tbl_num, ).add_policy(policy) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg) .build_requests(), self.testing_controller, ) pkt_sender = ScapyPacketInjector(self.IFACE) packet = TCPPacketBuilder()\ .set_tcp_layer(42132, 80, 2)\ .set_tcp_flags("S")\ .set_ip_layer('151.42.41.122', sub_ip)\ .set_ether_layer(self.MAC_DEST, "01:20:10:20:aa:bb")\ .build() snapshot_verifier = SnapshotVerifier( self, self.BRIDGE, self.service_manager, include_stats=False, ) with isolator, sub_context, snapshot_verifier: pkt_sender.send(packet)
def test_enforcemnet_rules(self): """ Add QOS policy to enforcement table into OVS. """ fake_controller_setup(self.enforcement_controller) imsi = 'IMSI001010000000013' sub_ip = '192.168.128.30' flow_list1 = [ FlowDescription( match=FlowMatch(direction=FlowMatch.UPLINK, ), action=FlowDescription.PERMIT, ), FlowDescription( match=FlowMatch( ip_dst=convert_ipv4_str_to_ip_proto("192.168.0.0/24"), direction=FlowMatch.DOWNLINK, ), action=FlowDescription.PERMIT, ), ] self.service_manager.session_rule_version_mapper.save_version( imsi, convert_ipv4_str_to_ip_proto(sub_ip), "rule1", 1, ) self.enforcement_controller.activate_rules( imsi, None, 0, convert_ipv4_str_to_ip_proto(sub_ip), None, policies=[ VersionedPolicy( rule=PolicyRule(id='rule1', priority=65530, flow_list=flow_list1), version=1, ), ], shard_id=0, local_f_teid_ng=100, ) snapshot_verifier = SnapshotVerifier( self, self.BRIDGE, self.service_manager, ) with snapshot_verifier: pass
def test_subscriber_policy_with_he(self): """ Add policy to subscriber with HE config """ cls = self.__class__ fake_controller_setup(self.enforcement_controller) imsi = 'IMSI010000000088888' sub_ip = '192.168.128.74' flow_list1 = [ FlowDescription( match=FlowMatch( ip_dst=convert_ipv4_str_to_ip_proto('45.10.0.0/24'), direction=FlowMatch.UPLINK, ), action=FlowDescription.PERMIT, ), ] he = HeaderEnrichment(urls=['abc.com']) policies = [ VersionedPolicy( rule=PolicyRule(id='simple_match', priority=2, flow_list=flow_list1, he=he), version=1, ), ] # ============================ Subscriber ============================ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._tbl_num, ).add_policy(policies[0]) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber( sub_context.cfg).build_requests(), self.testing_controller, ) snapshot_verifier = SnapshotVerifier( self, self.BRIDGE, self.service_manager, ) with isolator, sub_context, snapshot_verifier: pass
def _get_allow_all_traffic_policies(self): """ Policy to allow all traffic to the internet """ return [ PolicyRule( id='allow_all_traffic', priority=self.ALLOW_ALL_PRIORITY, flow_list=[ FlowDescription(match=FlowMatch( direction=FlowMatch.UPLINK)), FlowDescription(match=FlowMatch( direction=FlowMatch.DOWNLINK)), ], ) ]
def activate_dynamic_rule(client, args): request = ActivateFlowsRequest( sid=SIDUtils.to_pb(args.imsi), dynamic_rules=[PolicyRule( id=args.rule_id, priority=args.priority, hard_timeout=args.hard_timeout, flow_list=[ FlowDescription(match=FlowMatch( ipv4_dst=args.ipv4_dst, direction=FlowMatch.UPLINK)), FlowDescription(match=FlowMatch( ipv4_src=args.ipv4_dst, direction=FlowMatch.DOWNLINK)), ], )]) client.ActivateFlows(request)
def process_update(self, stream_name, updates, resync): logging.info("Processing %d policy updates (resync=%s)", len(updates), resync) if resync: policy_ids = set() for update in updates: policy = PolicyRule() policy.ParseFromString(update.value) self._store_policy_rule(policy) policy_ids.add(policy.id) logging.debug("Resync with policies: %s", ','.join(policy_ids)) self._remove_old_policies(policy_ids) self._policy_dict.send_update_notification() else: pass
def _get_whitelist_policy_rule( self, policy_id: str, ip: str, port: int, ) -> PolicyRule: return PolicyRule( # Don't set the rating group # Don't set the monitoring key # Don't set the hard timeout id=policy_id, priority=100, qos=self._get_default_qos(), flow_list=self._get_whitelist_flows(ip, port), tracking_type=PolicyRule.TrackingType.Value("NO_TRACKING"), )
def activate_gy_redirect(client, args): request = ActivateFlowsRequest( sid=SIDUtils.to_pb(args.imsi), ip_addr=args.ipv4, dynamic_rules=[ PolicyRule(id=args.rule_id, priority=999, flow_list=[], redirect=RedirectInformation( support=1, address_type=2, server_address=args.redirect_addr)) ], request_origin=RequestOriginType(type=RequestOriginType.GY)) response = client.ActivateFlows(request) _print_rule_mod_results(response.dynamic_rule_results)
def create_bearer(client, args): req = CreateBearerRequest( sid=SIDUtils.to_pb(args.imsi), link_bearer_id=args.lbi, policy_rules=[ PolicyRule(qos=FlowQos(qci=args.qci, gbr_ul=args.gbr_ul, gbr_dl=args.gbr_dl, max_req_bw_ul=args.mbr_ul, max_req_bw_dl=args.mbr_dl, arp=QosArp(priority_level=args.priority, pre_capability=args.pre_cap, pre_vulnerability=args.pre_vul))) ]) print("Creating dedicated bearer for : ", args.imsi) client.CreateBearer(req)
def __init__(self): self._set_session = SetSMSessionContext( common_context=CommonSessionContext( sid=SubscriberID(id="IMSI12345"), ue_ipv4="192.168.128.11", apn=bytes("BLR", 'utf-8'), rat_type=RATType.Name(2), sm_session_state=SMSessionFSMState.Name(2), sm_session_version=1, ), rat_specific_context=RatSpecificContext( m5gsm_session_context=M5GSMSessionContext( pdu_session_id=1, request_type=RequestType.Name( 1, ), gnode_endpoint=TeidSet( teid=10000, end_ipv4_addr="192.168.60.141", ), pdu_session_type=PduSessionType.Name(0), ssc_mode=SscMode.Name(2), qos_policy=[ QosPolicy( policy_state=0, policy_action=1, version=2, qos=PolicyRule( id="ims-voice", priority=10, flow_list=[], qos=FlowQos( qci=int(5), max_req_bw_ul=100000, max_req_bw_dl=100000, arp=QosArp( priority_level=1, pre_capability=1, pre_vulnerability=0, ), ), ), ), ], ), ), )
def _get_allow_all_policy_rule( self, policy_id: str, ) -> PolicyRule: """ This builds a PolicyRule used as a default to allow traffic for an attached subscriber. """ return PolicyRule( # Don't set the rating group # Don't set the monitoring key # Don't set the hard timeout id=policy_id, priority=2, flow_list=self._get_allow_all_flows(), tracking_type=PolicyRule.TrackingType.Value("NO_TRACKING"), )
def _build_activate_flows_data(ue_dict, disable_qos): activate_flow_reqs = [] if disable_qos: print("QOS Disabled") apn_ambr = None else: print("QOS Enabled") apn_ambr = AggregatedMaximumBitrate( max_bandwidth_ul=1000000000, max_bandwidth_dl=1000000000, ) for ue in ue_dict: request = ActivateFlowsRequest( sid=SIDUtils.to_pb(ue.imsi_str), ip_addr=ue.ipv4_src, policies=[ VersionedPolicy( rule=PolicyRule( id=ue.rule_id, priority=10, flow_list=[ FlowDescription(match=FlowMatch( ip_dst=convert_ipv4_str_to_ip_proto( ue.ipv4_src), direction=FlowMatch.UPLINK, ), ), FlowDescription(match=FlowMatch( ip_src=convert_ipv4_str_to_ip_proto( ue.ipv4_dst), direction=FlowMatch.DOWNLINK, ), ), ], ), version=1, ), ], request_origin=RequestOriginType(type=RequestOriginType.GX), apn_ambr=apn_ambr, ) request_dict = json_format.MessageToDict(request) # Dumping ActivateFlows request into json activate_flow_reqs.append(request_dict) with open('activate_flows.json', 'w') as file: json.dump(activate_flow_reqs, file, separators=(',', ':'))