Ejemplo n.º 1
0
    def test_add_app_rules(self):
        """
        Test DPI classifier flows are properly added

        Assert:
            1 FLOW_CREATED -> no rule added as its not classified yet
            1 App not tracked -> no rule installed(`notanAPP`)
            3 App types are matched on:
                facebook other
                google_docs other
                viber audio
        """
        flow_match1 = FlowMatch(ip_proto=FlowMatch.IPPROTO_TCP,
                                ipv4_dst='45.10.0.8',
                                ipv4_src='1.2.3.4',
                                tcp_dst=80,
                                tcp_src=51115,
                                direction=FlowMatch.UPLINK)
        flow_match2 = FlowMatch(ip_proto=FlowMatch.IPPROTO_TCP,
                                ipv4_dst='1.10.0.1',
                                ipv4_src='6.2.3.1',
                                tcp_dst=111,
                                tcp_src=222,
                                direction=FlowMatch.UPLINK)
        flow_match3 = FlowMatch(ip_proto=FlowMatch.IPPROTO_UDP,
                                ipv4_dst='22.2.2.24',
                                ipv4_src='15.22.32.2',
                                udp_src=111,
                                udp_dst=222,
                                direction=FlowMatch.UPLINK)
        flow_match_for_no_proto = FlowMatch(ip_proto=FlowMatch.IPPROTO_UDP,
                                            ipv4_dst='1.1.1.1')
        flow_match_not_added = FlowMatch(ip_proto=FlowMatch.IPPROTO_UDP,
                                         ipv4_src='22.22.22.22')
        self.dpi_controller.add_classify_flow(flow_match_not_added,
                                              FlowRequest.FLOW_CREATED,
                                              'nickproto', 'bestproto')
        self.dpi_controller.add_classify_flow(
            flow_match_for_no_proto, FlowRequest.FLOW_PARTIAL_CLASSIFICATION,
            'notanAPP', 'null')
        self.dpi_controller.add_classify_flow(
            flow_match1, FlowRequest.FLOW_PARTIAL_CLASSIFICATION,
            'base.ip.http.facebook', 'NotReal')
        self.dpi_controller.add_classify_flow(
            flow_match2,
            FlowRequest.FLOW_PARTIAL_CLASSIFICATION,
            'base.ip.https.google_gen.google_docs',
            'MAGMA',
        )
        self.dpi_controller.add_classify_flow(
            flow_match3,
            FlowRequest.FLOW_PARTIAL_CLASSIFICATION,
            'base.ip.udp.viber',
            'AudioTransfer Receiving',
        )

        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager)
        with snapshot_verifier:
            pass
Ejemplo n.º 2
0
    def _get_whitelist_flows(self, ip: str, port: int) -> List[FlowDescription]:
        """
        Args:
            ip: IP address to allow traffic to. This should be the captive
                portal address
            port:  Port of the captive portal server. Probably 80.

        Returns:
            Two flows, one for traffic towards the captive portal server, and a
            second for traffic from the captive portal server.
        """
        return [
            # Set flow match for outgoing TCP packets to whitelisted IP
            # Don't set the app_name field
            FlowDescription(  # uplink flow
                match=FlowMatch(
                    ipv4_dst=ip,
                    tcp_dst=port,
                    ip_proto=FlowMatch.IPProto.Value("IPPROTO_TCP"),
                    direction=FlowMatch.Direction.Value("UPLINK"),
                ),
                action=FlowDescription.Action.Value("PERMIT"),
            ),
            # Set flow match for incoming TCP packets from whitelisted IP
            # Don't set the app_name field
            FlowDescription(  # downlink flow
                match=FlowMatch(
                    ipv4_src=ip,
                    tcp_src=port,
                    ip_proto=FlowMatch.IPProto.Value("IPPROTO_TCP"),
                    direction=FlowMatch.Direction.Value("DOWNLINK"),
                ),
                action=FlowDescription.Action.Value("PERMIT"),
            ),
        ]
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
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()
Ejemplo n.º 5
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
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
 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)),
             ],
         )
     ]
Ejemplo n.º 8
0
    def test_add_app_rules(self):
        """
        Test DPI classifier flows are properly added

        Assert:
            1 App not tracked -> no rule installed(`notanAPP`)
            3 App types are matched on:
                facebook other
                google_docs other
                viber audio
        """
        MAC_DEST = "5e:cc:cc:b1:49:4b"
        flow_match1 = FlowMatch(ip_proto=FlowMatch.IPPROTO_TCP,
                                ipv4_dst='45.10.0.8',
                                ipv4_src='1.2.3.4',
                                tcp_dst=80,
                                tcp_src=51115,
                                direction=FlowMatch.UPLINK)
        flow_match2 = FlowMatch(ip_proto=FlowMatch.IPPROTO_TCP,
                                ipv4_dst='1.10.0.1',
                                ipv4_src='6.2.3.1',
                                tcp_dst=111,
                                tcp_src=222,
                                direction=FlowMatch.UPLINK)
        flow_match3 = FlowMatch(ip_proto=FlowMatch.IPPROTO_UDP,
                                ipv4_dst='22.2.2.24',
                                ipv4_src='15.22.32.2',
                                udp_src=111,
                                udp_dst=222,
                                direction=FlowMatch.UPLINK)
        flow_match_for_no_proto = FlowMatch(ip_proto=FlowMatch.IPPROTO_UDP,
                                            ipv4_dst='1.1.1.1')
        self.dpi_controller.add_classify_flow(flow_match_for_no_proto,
                                              'notanAPP', 'null', MAC_DEST,
                                              MAC_DEST)
        self.dpi_controller.add_classify_flow(flow_match1,
                                              'base.ip.http.facebook',
                                              'NotReal', MAC_DEST, MAC_DEST)
        self.dpi_controller.add_classify_flow(
            flow_match2, 'base.ip.https.google_gen.google_docs', 'MAGMA',
            MAC_DEST, MAC_DEST)
        self.dpi_controller.add_classify_flow(flow_match3, 'base.ip.udp.viber',
                                              'AudioTransfer Receiving',
                                              MAC_DEST, MAC_DEST)

        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager)
        with snapshot_verifier:
            pass
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
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,
    )
Ejemplo n.º 11
0
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))
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
    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))
Ejemplo n.º 14
0
    def test_subscriber_policy(self):
        """
        Classify DPI flow, verify internal packet is generated

        Assert:
            snapshots math
        """
        imsi = 'IMSI010000000088888'
        ue_mac = '5e:cc:cc:b1:49:4b'

        self.ue_mac_controller.add_ue_mac_flow(imsi, ue_mac)

        flow_match = FlowMatch(
            ip_proto=FlowMatch.IPPROTO_TCP,
            ip_dst=convert_ipv4_str_to_ip_proto('45.10.0.1'),
            ip_src=convert_ipv4_str_to_ip_proto('1.2.3.0'),
            tcp_dst=80,
            tcp_src=51115,
            direction=FlowMatch.UPLINK)
        self.dpi_controller.add_classify_flow(
            flow_match, FlowRequest.FLOW_FINAL_CLASSIFICATION,
            'base.ip.http.facebook', 'tbd')
        self.ipfix_controller.add_ue_sample_flow(imsi,
                                                 "magma_is_awesome_msisdn",
                                                 "00:11:22:33:44:55",
                                                 "apn_name123456789", 145)

        snapshot_verifier = SnapshotVerifier(self,
                                             self.BRIDGE,
                                             self.service_manager,
                                             include_stats=False)

        with snapshot_verifier:
            pass
Ejemplo n.º 15
0
    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_policy(self):
        """
        Classify DPI flow, verify internal packet is generated

        Assert:
            snapshots math
        """
        imsi = 'IMSI010000000088888'
        ue_mac = '5e:cc:cc:b1:49:4b'

        self.ue_mac_controller.add_ue_mac_flow(imsi, ue_mac)

        flow_match = FlowMatch(ip_proto=FlowMatch.IPPROTO_TCP,
                               ipv4_dst='45.10.0.1',
                               ipv4_src='1.2.3.0',
                               tcp_dst=80,
                               tcp_src=51115,
                               direction=FlowMatch.UPLINK)
        self.dpi_controller.add_classify_flow(
            flow_match, FlowRequest.FLOW_FINAL_CLASSIFICATION,
            'base.ip.http.facebook', 'tbd')

        snapshot_verifier = SnapshotVerifier(self,
                                             self.BRIDGE,
                                             self.service_manager,
                                             include_stats=False)

        with snapshot_verifier:
            pass
Ejemplo n.º 17
0
    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)
Ejemplo n.º 18
0
    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)
Ejemplo n.º 19
0
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=(',', ':'))
Ejemplo n.º 20
0
    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)
Ejemplo n.º 21
0
    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)
Ejemplo n.º 22
0
def _get_allow_all_flows() -> List[FlowDescription]:
    """
    Get flows for allowing all traffic
    Returns:
        Two flows, for outgoing and incoming traffic
    """
    return [
        # Set flow match for all packets
        # Don't set the app_name field
        FlowDescription(  # uplink flow
            match=FlowMatch(direction=FlowMatch.Direction.Value("UPLINK"), ),
            action=FlowDescription.Action.Value("PERMIT"),
        ),
        FlowDescription(  # downlink flow
            match=FlowMatch(direction=FlowMatch.Direction.Value("DOWNLINK"), ),
            action=FlowDescription.Action.Value("PERMIT"),
        ),
    ]
Ejemplo n.º 23
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(
                    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
Ejemplo n.º 24
0
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)),
                ],
            )
        ],
        request_origin=RequestOriginType(type=RequestOriginType.GX))
    response = client.ActivateFlows(request)
    _print_rule_mod_results(response.dynamic_rule_results)
Ejemplo n.º 25
0
    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
Ejemplo n.º 26
0
    def get_flow_match(self, flow_list, flow_match_list):
        """
        Populates flow match list
        """
        for flow in flow_list:
            flow_direction = (FlowMatch.UPLINK if flow["direction"] == "UL"
                              else FlowMatch.DOWNLINK)
            ip_protocol = flow["ip_proto"]
            if ip_protocol == "TCP":
                ip_protocol = FlowMatch.IPPROTO_TCP
                udp_src_port = 0
                udp_dst_port = 0
                tcp_src_port = (int(flow["tcp_src_port"])
                                if "tcp_src_port" in flow else 0)
                tcp_dst_port = (int(flow["tcp_dst_port"])
                                if "tcp_dst_port" in flow else 0)
            elif ip_protocol == "UDP":
                ip_protocol = FlowMatch.IPPROTO_UDP
                tcp_src_port = 0
                tcp_dst_port = 0
                udp_src_port = (int(flow["udp_src_port"])
                                if "udp_src_port" in flow else 0)
                udp_dst_port = (int(flow["udp_dst_port"])
                                if "udp_dst_port" in flow else 0)
            else:
                udp_src_port = 0
                udp_dst_port = 0
                tcp_src_port = 0
                tcp_dst_port = 0

            ipv4_src_addr = None
            if flow.get("ipv4_src", None):
                ipv4_src_addr = IPAddress(
                    version=IPAddress.IPV4,
                    address=flow.get("ipv4_src").encode('utf-8'))
            ipv4_dst_addr = None
            if flow.get("ipv4_dst", None):
                ipv4_dst_addr = IPAddress(
                    version=IPAddress.IPV4,
                    address=flow.get("ipv4_dst").encode('utf-8'))

            flow_match_list.append(
                FlowDescription(
                    match=FlowMatch(
                        ip_dst=ipv4_dst_addr,
                        ip_src=ipv4_src_addr,
                        tcp_src=tcp_src_port,
                        tcp_dst=tcp_dst_port,
                        udp_src=udp_src_port,
                        udp_dst=udp_dst_port,
                        ip_proto=ip_protocol,
                        direction=flow_direction,
                    ),
                    action=FlowDescription.PERMIT,
                ))
Ejemplo n.º 27
0
    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()
Ejemplo n.º 28
0
    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)
Ejemplo n.º 29
0
 def _get_allow_all_flows(self) -> List[FlowDescription]:
     """
     Returns:
         Two flows, for outgoing and incoming traffic
     """
     return [
         # Set flow match for ll packets
         # Don't set the app_name field
         FlowDescription(  # uplink flow
             match=FlowMatch(),
             action=FlowDescription.Action.Value("PERMIT"),
         ),
     ]
Ejemplo n.º 30
0
    def CreateAddQERinPDR(qos_enforce_rule: QoSEnforceRuleEntry,
                          ue_ip_addr: str) -> 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,
            dynamic_rules=[
                PolicyRule(id=qos_enforce_rule.rule_id,
                           priority=qos_enforce_rule.priority,
                           hard_timeout=qos_enforce_rule.hard_timeout,
                           flow_list=flow_list)
            ],
            request_origin=RequestOriginType(type=RequestOriginType.N4))
        return qos_enforce_rule