Example #1
0
    def test_subscriber_two_policies(self):
        """
        Add 2 policies to subscriber

        Assert:
            Packets are properly matched with the 'match' policy
            The total packet delta in the table is from the above match
        """
        fake_controller_setup(self.enforcement_controller)
        imsi = 'IMSI208950000000001'
        sub_ip = '192.168.128.74'
        flow_list1 = [
            FlowDescription(
                match=FlowMatch(
                    ip_src=convert_ipv4_str_to_ip_proto('15.0.0.0/24'),
                    direction=FlowMatch.DOWNLINK,
                ),
                action=FlowDescription.DENY,
            ),
        ]
        flow_list2 = [
            FlowDescription(
                match=FlowMatch(ip_proto=6, direction=FlowMatch.UPLINK),
                action=FlowDescription.PERMIT,
            ),
        ]

        policies = [
            VersionedPolicy(
                rule=PolicyRule(id='match', priority=2, flow_list=flow_list1),
                version=1,
            ),
            VersionedPolicy(
                rule=PolicyRule(id='no_match',
                                priority=2,
                                flow_list=flow_list2),
                version=1,
            ),
        ]
        pkts_sent = 42

        # ============================ Subscriber ============================
        sub_context = RyuDirectSubscriberContext(
            imsi, sub_ip,
            self.enforcement_controller,
            self._tbl_num,
        ) \
            .add_policy(policies[0])\
            .add_policy(policies[1])
        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context.cfg).build_requests(),
            self.testing_controller,
        )
        pkt_sender = ScapyPacketInjector(self.IFACE)
        packet = IPPacketBuilder()\
            .set_ip_layer(sub_ip, '15.0.0.8')\
            .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 'match' rule pkt count
        flow_verifier = FlowVerifier(
            [
                FlowTest(
                    FlowQuery(self._tbl_num, self.testing_controller),
                    pkts_sent,
                ),
                FlowTest(flow_query, pkts_sent),
            ],
            lambda: wait_after_send(self.testing_controller),
        )
        snapshot_verifier = SnapshotVerifier(
            self,
            self.BRIDGE,
            self.service_manager,
        )

        with isolator, sub_context, flow_verifier, snapshot_verifier:
            pkt_sender.send(packet, pkts_sent)

        flow_verifier.verify()
Example #2
0
    def test_two_subscribers(self):
        """
        Add 2 subscribers at the same time

        Assert:
            For subcriber1 the packets are matched to the proper policy
            For subcriber2 the packets are matched to the proper policy
            The total packet delta in the table is from the above matches
        """
        fake_controller_setup(self.enforcement_controller)
        pkt_sender = ScapyPacketInjector(self.IFACE)
        ip_match = [
            FlowDescription(
                match=FlowMatch(
                    ip_src=convert_ipv4_str_to_ip_proto('8.8.8.0/24'),
                    direction=1,
                ),
                action=1,
            ),
        ]
        tcp_match = [
            FlowDescription(
                match=FlowMatch(ip_proto=6, direction=FlowMatch.DOWNLINK),
                action=FlowDescription.DENY,
            ),
        ]

        policy = \
            VersionedPolicy(
                rule=PolicyRule(id='t', priority=2, flow_list=ip_match),
                version=1,
            )
        # =========================== Subscriber 1 ===========================
        sub_context1 = RyuDirectSubscriberContext(
            'IMSI208950001111111',
            '192.168.128.5',
            self.enforcement_controller,
            self._tbl_num,
        ).add_policy(policy)
        isolator1 = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context1.cfg).build_requests(),
            self.testing_controller,
        )
        packet_ip = IPPacketBuilder()\
            .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\
            .set_ip_layer(sub_context1.cfg.ip, '8.8.8.8')\
            .build()
        s1_pkts_sent = 29
        pkts_to_send = [PktsToSend(packet_ip, s1_pkts_sent)]
        flow_query1 = FlowQuery(
            self._tbl_num,
            self.testing_controller,
            match=flow_match_to_magma_match(ip_match[0].match),
        )
        s1 = SubTest(
            sub_context1,
            isolator1,
            FlowTest(flow_query1, s1_pkts_sent),
        )

        # =========================== Subscriber 2 ===========================
        sub_context2 = RyuDirectSubscriberContext(
            'IMSI911500451242001',
            '192.168.128.100',
            self.enforcement_controller,
            self._tbl_num,
        ).add_policy(
            VersionedPolicy(
                rule=PolicyRule(id='qqq', priority=2, flow_list=tcp_match),
                version=1,
            ), )
        isolator2 = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context2.cfg).build_requests(),
            self.testing_controller,
        )
        packet_tcp = TCPPacketBuilder()\
            .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\
            .set_ip_layer(sub_context2.cfg.ip, '15.0.0.8')\
            .build()
        s2_pkts_sent = 18
        pkts_to_send.append(PktsToSend(packet_tcp, s2_pkts_sent))
        flow_query2 = FlowQuery(
            self._tbl_num,
            self.testing_controller,
            match=flow_match_to_magma_match(tcp_match[0].match),
        )
        s2 = SubTest(
            sub_context2,
            isolator2,
            FlowTest(flow_query2, s2_pkts_sent),
        )

        # =========================== Verification ===========================
        # Verify aggregate table stats, subscriber 1 & 2 flows packet matches
        pkts = s1_pkts_sent + s2_pkts_sent
        flow_verifier = FlowVerifier(
            [
                FlowTest(FlowQuery(self._tbl_num, self.testing_controller),
                         pkts),
                s1.flowtest_list,
                s2.flowtest_list,
            ],
            lambda: wait_after_send(self.testing_controller),
        )
        snapshot_verifier = SnapshotVerifier(
            self,
            self.BRIDGE,
            self.service_manager,
        )

        with s1.isolator, s1.context, s2.isolator, s2.context, flow_verifier, \
             snapshot_verifier:
            for pkt in pkts_to_send:
                pkt_sender.send(pkt.pkt, pkt.num)

        flow_verifier.verify()
Example #3
0
    def test_url_redirect(self):
        """
        Partial redirection test, checks if flows were added properly for url
        based redirection.

        Assert:
            1 Packet is matched
            Packet bypass flows are added
            Flow learn action is triggered - another flow is added to the table
        """
        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller)
        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/"))

        # ============================ Subscriber ============================
        sub_context = RyuDirectSubscriberContext(imsi, sub_ip,
                                                 self.enforcement_controller,
                                                 self._tbl_num)

        setup_flows_request = SetupFlowsRequest(requests=[
            ActivateFlowsRequest(sid=SIDUtils.to_pb(imsi),
                                 ip_addr=sub_ip,
                                 dynamic_rules=[policy]),
        ],
                                                epoch=global_epoch)

        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller,
            setup_flows_request=setup_flows_request)

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

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

        with isolator, sub_context, snapshot_verifier:
            pkt_sender.send(packet)
Example #4
0
    def test_delete_tunnel_ip_flow_dl(self):

        dest_ip = IPAddress(
            version=IPAddress.IPV4,
            address=socket.inet_pton(socket.AF_INET, "192.168.128.12"),
        )
        src_ip = IPAddress(
            version=IPAddress.IPV4,
            address=socket.inet_pton(socket.AF_INET, "192.168.129.64"),
        )

        ip_flow_dl = IPFlowDL(
            set_params=71,
            tcp_dst_port=0,
            tcp_src_port=5002,
            udp_dst_port=0,
            udp_src_port=0,
            ip_proto=6,
            dest_ip=dest_ip,
            src_ip=src_ip,
            precedence=65530,
        )

        seid1 = 5000
        ue_ip_addr = "192.168.128.30"
        self.classifier_controller.gtp_handler(
            1,
            65525,
            1,
            100000,
            IPAddress(version=IPAddress.IPV4,
                      address=ue_ip_addr.encode('utf-8')),
            self.EnodeB_IP,
            seid1,
            ip_flow_dl=ip_flow_dl,
        )

        dest_ip = IPAddress(
            version=IPAddress.IPV4,
            address=socket.inet_pton(socket.AF_INET, "192.168.128.111"),
        )
        src_ip = IPAddress(
            version=IPAddress.IPV4,
            address=socket.inet_pton(socket.AF_INET, "192.168.129.4"),
        )

        ip_flow_dl = IPFlowDL(
            set_params=70,
            tcp_dst_port=0,
            tcp_src_port=0,
            udp_dst_port=80,
            udp_src_port=5060,
            ip_proto=17,
            dest_ip=dest_ip,
            src_ip=src_ip,
            precedence=65525,
        )

        seid2 = 5001
        ue_ip_addr = "192.168.128.31"
        self.classifier_controller.gtp_handler(
            1,
            65525,
            2,
            100001,
            IPAddress(version=IPAddress.IPV4,
                      address=ue_ip_addr.encode('utf-8')),
            self.EnodeB_IP,
            seid2,
            ip_flow_dl=ip_flow_dl,
        )

        snapshot_verifier = SnapshotVerifier(
            self,
            self.BRIDGE,
            self.service_manager,
        )
        with snapshot_verifier:
            pass
    def test_rule_reactivation(self):
        """
        Adds a policy to a subscriber, deletes it by incrementing the
        version, and add it back. Verifies that the usage stats is correctly
        reported, the old flows are deleted, and the new flows are installed.

        Assert:
            UPLINK policy matches 128 packets (*34 = 4352 bytes)
            Old flows are deleted
            New flows are installed
            No other stats are reported
        """
        fake_controller_setup(self.enforcement_controller,
                              self.enforcement_stats_controller)
        imsi = 'IMSI001010000000013'
        sub_ip = '192.168.128.74'
        num_pkts_tx_match = 128

        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)
        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context.cfg).build_requests(), self.testing_controller)
        """ Create a packet """
        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 ===========================
        """ Verify that flows are properly deleted """
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager)
        """
        Send a packet, then deactivate and reactivate the same rule and send a
        packet. Wait until it is received by ovs and enf stats.
        """
        with isolator, sub_context, snapshot_verifier:
            pkt_sender.send(packet)

            self.service_manager.session_rule_version_mapper. \
                save_version(imsi, convert_ipv4_str_to_ip_proto(sub_ip),
                             'rule1', 2)
            self.enforcement_controller.deactivate_rules(
                imsi, convert_ipv4_str_to_ip_proto(sub_ip), [policy.rule.id])
            policy.version = 2
            self.enforcement_controller.activate_rules(
                imsi, None, None, convert_ipv4_str_to_ip_proto(sub_ip), None,
                [policy])
            self.enforcement_stats_controller.activate_rules(
                imsi, None, None, convert_ipv4_str_to_ip_proto(sub_ip), None,
                [policy])
            pkt_sender.send(packet)

            enf_stat_names = [
                imsi + '|rule1' + '|' + sub_ip + '|' + "1",
                imsi + '|rule1' + '|' + sub_ip + '|' + "2"
            ]
            wait_for_enforcement_stats(self.enforcement_stats_controller,
                                       enf_stat_names)
            stats = get_enforcement_stats(
                self.enforcement_stats_controller._report_usage.call_args_list)
            for args in self.enforcement_stats_controller._report_usage.call_args_list:
                self.enforcement_stats_controller._delete_old_flows(
                    args[0][0].values())

            self.assertEqual(stats[enf_stat_names[0]].sid, imsi)
            self.assertEqual(stats[enf_stat_names[0]].rule_id, "rule1")
            self.assertEqual(stats[enf_stat_names[0]].rule_version, 1)
            self.assertEqual(stats[enf_stat_names[0]].bytes_rx, 0)
            self.assertEqual(len(stats), 3)

        self.enforcement_stats_controller._report_usage.reset_mock()
        wait_for_enforcement_stats(self.enforcement_stats_controller,
                                   [enf_stat_names[1]])
        stats = get_enforcement_stats(
            self.enforcement_stats_controller._report_usage.call_args_list)
        """
        Verify both packets are reported after reactivation.
        """
        self.assertEqual(stats[enf_stat_names[1]].sid, imsi)
        self.assertEqual(stats[enf_stat_names[1]].rule_id, "rule1")
        self.assertEqual(stats[enf_stat_names[1]].rule_version, 2)
        self.assertEqual(stats[enf_stat_names[1]].bytes_rx, 0)
        # TODO Figure out why this one fails.
        #self.assertEqual(stats[enf_stat_name].bytes_tx,
        #                 num_pkts_tx_match * len(packet))
        self.assertEqual(len(stats), 2)
Example #6
0
    def test_enforcement_restart(self):
        """
        Adds rules using the setup feature

        1) Empty SetupFlowsRequest
            - assert default flows
        2) Add 2 imsis, add 2 policies(sub1_rule_temp, sub2_rule_keep),
            - assert everything is properly added
        3) Same imsis 1 new policy, 1 old (sub2_new_rule, sub2_rule_keep)
            - assert everything is properly added
        4) Empty SetupFlowsRequest
            - assert default flows
        """
        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller)
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager,
                                             'default_flows')
        with snapshot_verifier:
            pass

        imsi1 = 'IMSI010000000088888'
        imsi2 = 'IMSI010000000012345'
        sub2_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),
            FlowDescription(match=FlowMatch(
                ip_dst=convert_ipv4_str_to_ip_proto('45.11.0.0/24'),
                direction=FlowMatch.UPLINK),
                            action=FlowDescription.PERMIT)
        ]
        flow_list2 = [
            FlowDescription(match=FlowMatch(
                ip_dst=convert_ipv4_str_to_ip_proto('10.10.1.0/24'),
                direction=FlowMatch.UPLINK),
                            action=FlowDescription.PERMIT)
        ]
        policies1 = [
            PolicyRule(id='sub1_rule_temp', priority=2, flow_list=flow_list1),
        ]
        policies2 = [
            PolicyRule(id='sub2_rule_keep', priority=3, flow_list=flow_list2)
        ]
        enf_stat_name = [
            imsi1 + '|sub1_rule_temp' + '|' + sub2_ip,
            imsi2 + '|sub2_rule_keep' + '|' + sub2_ip
        ]

        self.service_manager.session_rule_version_mapper.update_version(
            imsi1, convert_ipv4_str_to_ip_proto(sub2_ip), 'sub1_rule_temp')
        self.service_manager.session_rule_version_mapper.update_version(
            imsi2, convert_ipv4_str_to_ip_proto(sub2_ip), 'sub2_rule_keep')

        setup_flows_request = SetupFlowsRequest(requests=[
            ActivateFlowsRequest(sid=SIDUtils.to_pb(imsi1),
                                 ip_addr=sub2_ip,
                                 dynamic_rules=policies1),
            ActivateFlowsRequest(sid=SIDUtils.to_pb(imsi2),
                                 ip_addr=sub2_ip,
                                 dynamic_rules=policies2),
        ],
                                                epoch=global_epoch)

        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller,
            setup_flows_request=setup_flows_request)
        sub_context = RyuDirectSubscriberContext(imsi2, sub2_ip,
                                                 self.enforcement_controller,
                                                 self._enforcement_tbl_num)
        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context.cfg).build_requests(), self.testing_controller)
        pkt_sender = ScapyPacketInjector(self.IFACE)
        packets = IPPacketBuilder()\
            .set_ip_layer('10.10.1.8/20', sub2_ip)\
            .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\
            .build()
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager,
                                             'before_restart')
        with isolator, snapshot_verifier:
            pkt_sender.send(packets)

        flow_list1 = [
            FlowDescription(match=FlowMatch(
                ip_dst=convert_ipv4_str_to_ip_proto('24.10.0.0/24'),
                direction=FlowMatch.UPLINK),
                            action=FlowDescription.PERMIT)
        ]
        policies = [
            PolicyRule(id='sub2_new_rule', priority=2, flow_list=flow_list1),
            PolicyRule(id='sub2_rule_keep', priority=3, flow_list=flow_list2)
        ]
        self.service_manager.session_rule_version_mapper.update_version(
            imsi2, convert_ipv4_str_to_ip_proto(sub2_ip), 'sub2_new_rule')
        enf_stat_name = [
            imsi2 + '|sub2_new_rule' + '|' + sub2_ip,
            imsi2 + '|sub2_rule_keep' + '|' + sub2_ip
        ]
        setup_flows_request = SetupFlowsRequest(requests=[
            ActivateFlowsRequest(sid=SIDUtils.to_pb(imsi2),
                                 ip_addr=sub2_ip,
                                 dynamic_rules=policies)
        ],
                                                epoch=global_epoch)

        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller,
            setup_flows_request=setup_flows_request)
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager,
                                             'after_restart')
        with snapshot_verifier:
            pass

        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller)
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager,
                                             'default_flows_w_packets')

        with snapshot_verifier:
            pass
    def test_enforcement_ipv6_restart(self):
        """
        Adds rules using the setup feature

        1) Empty SetupFlowsRequest
            - assert default flows
        2) Add imsi with ipv6 policy
            - assert everything is properly added
        """
        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller,
        )
        snapshot_verifier = SnapshotVerifier(
            self, self.BRIDGE,
            self.service_manager,
            'default_flows',
        )
        with snapshot_verifier:
            pass

        imsi = 'IMSI010000002388888'
        sub_ip = b'fe80:24c3:d0ff:fef3:9d21:4407:d337:1928'

        flow_list = [
            FlowDescription(
                match=FlowMatch(
                    ip_dst=convert_ipv6_bytes_to_ip_proto(b'fe80::'),
                    direction=FlowMatch.UPLINK,
                ),
                action=FlowDescription.PERMIT,
            ),
        ]
        policies = [
            VersionedPolicy(
                rule=PolicyRule(id='ipv6_rule', priority=2, flow_list=flow_list),
                version=1,
            ),
        ]
        enf_stat_name = [imsi + '|ipv6_rule' + '|' + str(sub_ip) + "|" + "1"]
        setup_flows_request = SetupFlowsRequest(
            requests=[
                ActivateFlowsRequest(
                    sid=SIDUtils.to_pb(imsi),
                    ipv6_addr=sub_ip,
                    policies=policies,
                ),
            ],
            epoch=global_epoch,
        )

        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller,
            setup_flows_request=setup_flows_request,
        )
        snapshot_verifier = SnapshotVerifier(
            self, self.BRIDGE,
            self.service_manager,
            'after_restart',
        )
        with snapshot_verifier:
            pass

        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller,
        )
        snapshot_verifier = SnapshotVerifier(
            self, self.BRIDGE,
            self.service_manager,
            'default_flows',
        )

        with snapshot_verifier:
            pass
    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 = 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,
        )
        stat_name = imsi + '|redir_test' + '|' + sub_ip + '|' + "1"
        self.service_manager.session_rule_version_mapper.save_version(
            imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'redir_test', 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)
        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))
Example #9
0
    def test_ue_flows_multi_rule(self):
        """
        Verify that a proxy flows are setup
        """
        cls = self.__class__
        self._msg_hub = MessageHub(HeTableTest.he_controller.logger)
        dp = HeTableTest.he_controller._datapath
        ue_ip1 = '1.1.1.200'
        tun_id1 = 1
        dest_server1 = '2.2.2.4'
        rule1 = 123
        flow_msg = cls.he_controller.get_subscriber_he_flows(
            'rule1',
            Direction.OUT,
            ue_ip1,
            tun_id1,
            dest_server1,
            rule1,
            ['abc.com'],
            'IMSI01',
            b'1',
        )

        tun_id2 = 2
        dest_server2 = '20.20.20.40'
        rule2 = 1230
        flow_msg.extend(
            cls.he_controller.get_subscriber_he_flows(
                'rule2',
                Direction.OUT,
                ue_ip1,
                tun_id2,
                dest_server2,
                rule2,
                ['abc1.com'],
                'IMSI01',
                b'1',
            ), )
        self.assertEqual(cls.he_controller._ue_rule_counter.get(ue_ip1), 2)

        dest_server2 = '20.20.40.40'
        rule3 = 1230
        flow_msg.extend(
            cls.he_controller.get_subscriber_he_flows(
                'rule3',
                Direction.OUT,
                ue_ip1,
                tun_id2,
                dest_server2,
                rule3,
                ['abc2.com'],
                'IMSI01',
                None,
            ), )

        self.assertEqual(cls.he_controller._ue_rule_counter.get(ue_ip1), 3)

        dest_server2 = '20.20.50.50'
        rule4 = 22
        flow_msg.extend(
            cls.he_controller.get_subscriber_he_flows(
                'rule4',
                Direction.OUT,
                ue_ip1,
                tun_id2,
                dest_server2,
                rule4,
                ['abc2.com'],
                'IMSI01',
                None,
            ), )

        self.assertEqual(cls.he_controller._ue_rule_counter.get(ue_ip1), 4)

        chan = self._msg_hub.send(flow_msg, dp)
        self._wait_for_responses(chan, len(flow_msg),
                                 HeTableTest.he_controller.logger)

        cls.he_controller.remove_subscriber_he_flows(
            convert_ip_str_to_ip_proto(ue_ip1), "rule1", rule1)

        snapshot_verifier = SnapshotVerifier(
            self,
            self.BRIDGE,
            self.service_manager,
            max_sleep_time=20,
            datapath=HeTableTest.he_controller._datapath,
        )

        with snapshot_verifier:
            pass
        # verify multiple remove works.
        cls.he_controller.remove_subscriber_he_flows(
            convert_ip_str_to_ip_proto(ue_ip1), "rule2", rule2)
        self.assertEqual(cls.he_controller._ue_rule_counter.get(ue_ip1), 2)
        cls.he_controller.remove_subscriber_he_flows(
            convert_ip_str_to_ip_proto(ue_ip1))
        self.assertEqual(cls.he_controller._ue_rule_counter.get(ue_ip1), 0)
Example #10
0
    def test_enforcemnet_rule_multiple_sessions(self):
        """
        Add QOS policy to enforcement table into OVS.
        """
        fake_controller_setup(self.enforcement_controller)
        imsi = 'IMSI001000000000088'
        sub_ip = '192.168.128.40'
        flow_list = [
            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", 2,
        )

        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_list),
                    version=2,
                ),
            ], shard_id=0, local_f_teid_ng=555,
        )
        imsi = 'IMSI001000000100088'
        sub_ip = '192.168.128.150'
        flow_list = [
            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), "rule2", 3,
        )

        self.enforcement_controller.activate_rules(
            imsi, None, 0, convert_ipv4_str_to_ip_proto(sub_ip),
            None, policies=[
                VersionedPolicy(
                    rule=PolicyRule(id='rule2', priority=65536, flow_list=flow_list),
                    version=3,
                ),
            ], shard_id=0, local_f_teid_ng=5000,
        )

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

        with snapshot_verifier:
            pass
Example #11
0
    def test_rule_reactivation(self):
        """
        Adds a policy to a subscriber, deletes it by incrementing the
        version, and add it back. Verifies that the usage stats is correctly
        reported, the old flows are deleted, and the new flows are installed.

        Assert:
            UPLINK policy matches 128 packets (*34 = 4352 bytes)
            Old flows are deleted
            New flows are installed
            No other stats are reported
        """
        imsi = 'IMSI001010000000013'
        sub_ip = '192.168.128.74'
        num_pkts_tx_match = 128

        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)
        enf_stat_name = imsi + '|rule1'
        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)
        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context.cfg).build_requests(), self.testing_controller)
        """ Create a packet """
        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 ===========================
        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_old_version_query = FlowQuery(self._scratch_tbl_num,
                                         self.testing_controller,
                                         match=MagmaMatch(
                                             imsi=encode_imsi(imsi),
                                             reg2=rule_num,
                                             rule_version=version),
                                         cookie=rule_num)
        es_new_version_query = FlowQuery(self._scratch_tbl_num,
                                         self.testing_controller,
                                         match=MagmaMatch(
                                             imsi=encode_imsi(imsi),
                                             reg2=rule_num,
                                             rule_version=version + 1),
                                         cookie=rule_num)
        packet_wait = FlowVerifier([], self._wait_func([enf_stat_name]))
        """ Verify that flows are properly deleted """
        verifier = FlowVerifier([
            FlowTest(es_old_version_query, 0, flow_count=0),
            FlowTest(es_new_version_query, num_pkts_tx_match, flow_count=2),
            FlowTest(enf_query, num_pkts_tx_match, flow_count=1),
        ], self._wait_func([enf_stat_name]))
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager)
        """
        Send a packet, then deactivate and reactivate the same rule and send a
        packet. Wait until it is received by ovs and enf stats.
        """
        with isolator, sub_context, verifier, snapshot_verifier:
            with packet_wait:
                self.enforcement_stats_controller._report_usage.reset_mock()
                pkt_sender.send(packet)

            self.enforcement_stats_controller._report_usage.reset_mock()
            self.service_manager.session_rule_version_mapper. \
                update_version(imsi, 'rule1')
            self.enforcement_controller.deactivate_rules(imsi, [policy.id])
            self.enforcement_controller.activate_rules(imsi, sub_ip,
                                                       [policy.id], [])
            self.enforcement_stats_controller.activate_rules(
                imsi, sub_ip, [policy.id], [])
            pkt_sender.send(packet)

        verifier.verify()

        stats = get_enforcement_stats(
            self.enforcement_stats_controller._report_usage.call_args_list)
        """
        Verify both packets are reported after reactivation.
        """
        self.assertEqual(stats[enf_stat_name].sid, imsi)
        self.assertEqual(stats[enf_stat_name].rule_id, "rule1")
        self.assertEqual(stats[enf_stat_name].bytes_rx, 0)
        self.assertEqual(stats[enf_stat_name].bytes_tx,
                         num_pkts_tx_match * len(packet))

        self.assertEqual(len(stats), 1)
    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()
Example #13
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)
Example #14
0
    def test_attach_multi_tunnel_flows(self):

        # Need to delete all default flows in table 0 before
        # install the specific flows test case.
        self.test_detach_default_tunnel_flows()

        ip_no = hex(socket.htonl(int(ipaddress.ip_address(self.EnodeB_IP))))
        buf = "g_{}".format(ip_no[2:])

        BridgeTools.create_veth_pair(buf, buf + "ns")
        BridgeTools.add_ovs_port(self.BRIDGE, buf, "40")

        seid1 = 5000
        ue_ip_addr = "192.168.128.30"
        ip_flow_dl = IPFlowDL(set_params=0)
        self.classifier_controller.add_tunnel_flows(
            65525,
            1,
            100000,
            IPAddress(version=IPAddress.IPV4,
                      address=ue_ip_addr.encode('utf-8')),
            self.EnodeB_IP,
            seid1,
            True,
            ip_flow_dl=ip_flow_dl)

        ip_no = hex(socket.htonl(int(ipaddress.ip_address(self.EnodeB2_IP))))
        buf = "g_{}".format(ip_no[2:])

        BridgeTools.create_veth_pair(buf, buf + "ns")
        BridgeTools.add_ovs_port(self.BRIDGE, buf, "41")

        seid2 = 5001
        ue_ip_addr = "192.168.128.31"
        self.classifier_controller.add_tunnel_flows(
            65525,
            2,
            100001,
            IPAddress(version=IPAddress.IPV4,
                      address=ue_ip_addr.encode('utf-8')),
            self.EnodeB2_IP,
            seid2,
            True,
            ip_flow_dl=ip_flow_dl)

        ue_ip_addr = "192.168.128.51"
        self.classifier_controller.add_tunnel_flows(
            65525,
            5,
            1001,
            IPAddress(version=IPAddress.IPV4,
                      address=ue_ip_addr.encode('utf-8')),
            self.EnodeB2_IP,
            seid2,
            True,
            ip_flow_dl=ip_flow_dl)

        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager)
        with snapshot_verifier:
            pass
Example #15
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,
            ip_dst=convert_ipv4_str_to_ip_proto('45.10.0.8'),
            ip_src=convert_ipv4_str_to_ip_proto('1.2.3.4'),
            tcp_dst=80, tcp_src=51115, direction=FlowMatch.UPLINK,
        )
        flow_match2 = FlowMatch(
            ip_proto=FlowMatch.IPPROTO_TCP,
            ip_dst=convert_ipv4_str_to_ip_proto('1.10.0.1'),
            ip_src=convert_ipv4_str_to_ip_proto('6.2.3.1'),
            tcp_dst=111, tcp_src=222, direction=FlowMatch.UPLINK,
        )
        flow_match3 = FlowMatch(
            ip_proto=FlowMatch.IPPROTO_UDP,
            ip_dst=convert_ipv4_str_to_ip_proto('22.2.2.24'),
            ip_src=convert_ipv4_str_to_ip_proto('15.22.32.2'),
            udp_src=111, udp_dst=222, direction=FlowMatch.UPLINK,
        )
        flow_match_for_no_proto = FlowMatch(
            ip_proto=FlowMatch.IPPROTO_UDP,
            ip_dst=convert_ipv4_str_to_ip_proto('1.1.1.1'),
        )
        flow_match_not_added = FlowMatch(
            ip_proto=FlowMatch.IPPROTO_UDP,
            ip_src=convert_ipv4_str_to_ip_proto('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
    def test_subscriber_policy(self):
        """
        Adds 2 policies to subscriber, verifies that EnforcementStatsController
        reports correct stats to sessiond

        Assert:
            UPLINK policy matches 128 packets (*34 = 4352 bytes)
            DOWNLINK policy matches 256 packets (*34 = 8704 bytes)
            No other stats are reported
        """
        fake_controller_setup(self.enforcement_controller,
                              self.enforcement_stats_controller)
        imsi = 'IMSI001010000000013'
        sub_ip = '192.168.128.74'
        num_pkts_tx_match = 128
        num_pkts_rx_match = 256
        """ Create 2 policy rules for the subscriber """
        flow_list1 = [
            FlowDescription(match=FlowMatch(
                ip_dst=convert_ipv4_str_to_ip_proto('45.10.0.0/25'),
                direction=FlowMatch.UPLINK),
                            action=FlowDescription.PERMIT)
        ]
        flow_list2 = [
            FlowDescription(match=FlowMatch(
                ip_src=convert_ipv4_str_to_ip_proto('45.10.0.0/24'),
                direction=FlowMatch.DOWNLINK),
                            action=FlowDescription.PERMIT)
        ]
        policies = [
            VersionedPolicy(
                rule=PolicyRule(id='tx_match',
                                priority=3,
                                flow_list=flow_list1),
                version=1,
            ),
            VersionedPolicy(
                rule=PolicyRule(id='rx_match',
                                priority=5,
                                flow_list=flow_list2),
                version=1,
            )
        ]
        enf_stat_name = [
            imsi + '|tx_match' + '|' + sub_ip + '|' + "1",
            imsi + '|rx_match' + '|' + sub_ip + '|' + "1"
        ]
        self.service_manager.session_rule_version_mapper.save_version(
            imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'tx_match', 1)
        self.service_manager.session_rule_version_mapper.save_version(
            imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rx_match', 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(policies[0]) \
         .add_policy(policies[1])
        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context.cfg).build_requests(), self.testing_controller)
        """ Create 2 sets of packets, for policry rule1&2 """
        pkt_sender = ScapyPacketInjector(self.IFACE)
        packet1 = IPPacketBuilder()\
            .set_ip_layer('45.10.0.0/20', sub_ip)\
            .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\
            .build()
        packet2 = IPPacketBuilder()\
            .set_ip_layer(sub_ip, '45.10.0.0/20')\
            .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\
            .build()

        # =========================== Verification ===========================
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager)
        """ Send packets, wait until pkts are received by ovs and enf stats """
        with isolator, sub_context, snapshot_verifier:
            pkt_sender.send(packet1)
            pkt_sender.send(packet2)

        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[0]].sid, imsi)
        self.assertEqual(stats[enf_stat_name[0]].rule_id, "tx_match")
        self.assertEqual(stats[enf_stat_name[0]].bytes_rx, 0)
        self.assertEqual(stats[enf_stat_name[0]].bytes_tx,
                         num_pkts_tx_match * len(packet1))

        self.assertEqual(stats[enf_stat_name[1]].sid, imsi)
        self.assertEqual(stats[enf_stat_name[1]].rule_id, "rx_match")
        self.assertEqual(stats[enf_stat_name[1]].bytes_tx, 0)

        # downlink packets will discount ethernet header by default
        # so, only count the IP portion
        total_bytes_pkt2 = num_pkts_rx_match * len(packet2[IP])
        self.assertEqual(stats[enf_stat_name[1]].bytes_rx, total_bytes_pkt2)

        self.assertEqual(len(stats), 3)
Example #17
0
    def test_rule_deactivation(self):
        """
        Adds a policy to a subscriber, and then deletes it by incrementing the
        version, verifies that the usage stats is correctly reported and the
        flows are deleted.

        Assert:
            UPLINK policy matches 128 packets (*34 = 4352 bytes)
            Flows are deleted
            No other stats are reported
        """
        fake_controller_setup(
            self.enforcement_controller,
            self.enforcement_stats_controller,
        )
        imsi = 'IMSI001010000000013'
        sub_ip = '192.168.128.74'
        num_pkts_tx_match = 128

        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"
        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)
        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context.cfg).build_requests(),
            self.testing_controller,
        )
        """ Create a packet """
        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 ===========================
        """ Verify that flows are properly deleted """
        snapshot_verifier = SnapshotVerifier(
            self,
            self.BRIDGE,
            self.service_manager,
        )
        """
        Send packets, wait until packet is received by ovs and enf stats and
        then deactivate the rule in enforcement controller. This emulates the
        case where there is unreported traffic after rule deactivation.
        """
        with isolator, sub_context, snapshot_verifier:
            self.enforcement_stats_controller._report_usage.reset_mock()
            pkt_sender.send(packet)
            self.service_manager.session_rule_version_mapper. \
                save_version(
                    imsi, convert_ipv4_str_to_ip_proto(sub_ip),
                    'rule1', 2,
                )
            self.enforcement_controller.deactivate_rules(
                imsi,
                convert_ipv4_str_to_ip_proto(sub_ip),
                [policy.rule.id],
            )

            wait_for_enforcement_stats(
                self.enforcement_stats_controller,
                [enf_stat_name],
            )
            stats = get_enforcement_stats(
                self.enforcement_stats_controller._report_usage.call_args_list,
            )
            for args in self.enforcement_stats_controller._report_usage.call_args_list:
                self.enforcement_stats_controller._delete_old_flows(
                    args[0][0].values())

        self.assertEqual(stats[enf_stat_name].sid, imsi)
        self.assertEqual(stats[enf_stat_name].rule_id, "rule1")
        self.assertEqual(stats[enf_stat_name].rule_version, 1)
        self.assertEqual(stats[enf_stat_name].bytes_rx, 0)
        self.assertEqual(
            stats[enf_stat_name].bytes_tx,
            num_pkts_tx_match * len(packet),
        )

        self.assertEqual(len(stats), 2)

        self.enforcement_stats_controller.deactivate_default_flow(
            imsi,
            convert_ipv4_str_to_ip_proto(sub_ip),
        )
        snapshot_verifier = SnapshotVerifier(
            self,
            self.BRIDGE,
            self.service_manager,
            'nuke_ue',
        )
        with snapshot_verifier:
            pass
    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 = 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)

        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 + '|' + "0"
        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))
Example #19
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)
Example #20
0
    def test_passthrough_rules(self):
        """
           Add UE MAC flows for two subscribers
        """
        imsi_1 = 'IMSI010000000088888'
        other_mac = '5e:cc:cc:b1:aa:aa'
        cli_ip = '1.1.1.1'
        server_ip = '151.42.41.122'

        fake_inout_setup(self.inout_controller)
        # Add subscriber with UE MAC address """
        self.ue_mac_controller.add_ue_mac_flow(imsi_1, self.UE_MAC_1)

        # Create a set of packets
        pkt_sender = ScapyPacketInjector(self.BRIDGE)

        # Only send downlink as the pkt_sender sends pkts from in_port=LOCAL
        downlink_packet1 = EtherPacketBuilder() \
            .set_ether_layer(self.UE_MAC_1, other_mac) \
            .build()
        dhcp_packet = DHCPPacketBuilder() \
            .set_ether_layer(self.UE_MAC_1, other_mac) \
            .set_ip_layer(server_ip, cli_ip) \
            .set_udp_layer(67, 68) \
            .set_bootp_layer(2, cli_ip, server_ip, other_mac) \
            .set_dhcp_layer([("message-type", "ack"), "end"]) \
            .build()
        dns_packet = UDPPacketBuilder() \
            .set_ether_layer(self.UE_MAC_1, other_mac) \
            .set_ip_layer('151.42.41.122', '1.1.1.1') \
            .set_udp_layer(53, 32795) \
            .build()
        arp_packet = ARPPacketBuilder() \
            .set_ether_layer(self.UE_MAC_1, other_mac) \
            .set_arp_layer('1.1.1.1') \
            .set_arp_hwdst(self.UE_MAC_1) \
            .set_arp_src(other_mac, '1.1.1.12') \
            .build()

        # Check if these flows were added (queries should return flows)
        flow_queries = [
            FlowQuery(self._tbl_num,
                      self.testing_controller,
                      match=MagmaMatch(eth_dst=self.UE_MAC_1))
        ]

        # =========================== Verification ===========================
        # Verify 3 flows installed for ue_mac table (3 pkts matched)
        #        4 flows installed for inout (3 pkts matched)
        #        2 flows installed (2 pkts matches)
        flow_verifier = FlowVerifier([
            FlowTest(FlowQuery(self._tbl_num, self.testing_controller), 4, 3),
            FlowTest(FlowQuery(self._ingress_tbl_num, self.testing_controller),
                     4, 2),
            FlowTest(FlowQuery(self._egress_tbl_num, self.testing_controller),
                     3, 2),
            FlowTest(flow_queries[0], 4, 1),
        ], lambda: wait_after_send(self.testing_controller))

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

        with flow_verifier, snapshot_verifier:
            pkt_sender.send(dhcp_packet)
            pkt_sender.send(downlink_packet1)
            pkt_sender.send(dns_packet)
            hub.sleep(3)
            pkt_sender.send(arp_packet)

        flow_verifier.verify()
Example #21
0
    def test_url_redirect(self):
        """
        Partial redirection test, checks if flows were added properly for url
        based redirection.

        Assert:
            1 Packet is matched
            Packet bypass flows are added
            Flow learn action is triggered - another flow is added to the table
        """
        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller)
        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/"))

        # ============================ Subscriber ============================
        sub_context = RyuDirectSubscriberContext(imsi, sub_ip,
                                                 self.enforcement_controller,
                                                 self._tbl_num)

        setup_flows_request = SetupFlowsRequest(requests=[
            ActivateFlowsRequest(sid=SIDUtils.to_pb(imsi),
                                 ip_addr=sub_ip,
                                 dynamic_rules=[policy]),
        ],
                                                epoch=global_epoch)

        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller,
            setup_flows_request=setup_flows_request)

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

        # Check if these flows were added (queries should return flows)
        permit_outbound, permit_inbound = [], []
        for ip in redirect_ips:
            permit_outbound.append(
                FlowQuery(self._tbl_num,
                          self.testing_controller,
                          match=flow_match_to_magma_match(
                              FlowMatch(ipv4_dst=ip,
                                        direction=FlowMatch.UPLINK))))
            permit_inbound.append(
                FlowQuery(self._tbl_num,
                          self.testing_controller,
                          match=flow_match_to_magma_match(
                              FlowMatch(ipv4_src=ip,
                                        direction=FlowMatch.DOWNLINK))))

        learn_action_flow = flow_match_to_magma_match(
            FlowMatch(ip_proto=6,
                      direction=FlowMatch.DOWNLINK,
                      ipv4_src=self.BRIDGE_IP_ADDRESS,
                      ipv4_dst=sub_ip))
        learn_action_query = FlowQuery(self._tbl_num, self.testing_controller,
                                       learn_action_flow)

        # =========================== Verification ===========================
        # 1 packet sent, permit rules installed, learn action installed. Since
        # the enforcement table is entered via the DPI table and the scratch
        # enforcement table, the number of packets handled by the table is 2.
        flow_verifier = FlowVerifier(
            [
                FlowTest(FlowQuery(self._tbl_num, self.testing_controller), 2),
                FlowTest(learn_action_query, 0, flow_count=1)
            ] +
            [FlowTest(query, 0, flow_count=1) for query in permit_outbound] +
            [FlowTest(query, 0, flow_count=1) for query in permit_inbound],
            lambda: wait_after_send(self.testing_controller))

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

        with isolator, sub_context, flow_verifier, snapshot_verifier:
            pkt_sender.send(packet)

        flow_verifier.verify()
Example #22
0
    def test_enforcement_stats_restart(self):
        """
        Adds 2 policies to subscriber, verifies that EnforcementStatsController
        reports correct stats to sessiond

        Assert:
            UPLINK policy matches 128 packets (*34 = 4352 bytes)
            DOWNLINK policy matches 256 packets (*34 = 8704 bytes)
            No other stats are reported

        The controller is then restarted with the same SetupFlowsRequest,
            - assert flows keep their packet counts
        """
        self.enforcement_stats_controller._report_usage.reset_mock()
        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller)
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager,
                                             'default_flows')
        with snapshot_verifier:
            pass

        imsi = 'IMSI001010000000013'
        sub_ip = '192.168.128.74'
        num_pkts_tx_match = 128
        num_pkts_rx_match = 256
        """ Create 2 policy rules for the subscriber """
        flow_list1 = [
            FlowDescription(match=FlowMatch(
                ip_dst=convert_ipv4_str_to_ip_proto('45.10.0.0/25'),
                direction=FlowMatch.UPLINK),
                            action=FlowDescription.PERMIT)
        ]
        flow_list2 = [
            FlowDescription(match=FlowMatch(
                ip_src=convert_ipv4_str_to_ip_proto('45.10.0.0/24'),
                direction=FlowMatch.DOWNLINK),
                            action=FlowDescription.PERMIT)
        ]
        policies = [
            PolicyRule(id='tx_match', priority=3, flow_list=flow_list1),
            PolicyRule(id='rx_match', priority=5, flow_list=flow_list2)
        ]
        enf_stat_name = [
            imsi + '|tx_match' + '|' + sub_ip,
            imsi + '|rx_match' + '|' + sub_ip
        ]
        self.service_manager.session_rule_version_mapper.update_version(
            imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'tx_match')
        self.service_manager.session_rule_version_mapper.update_version(
            imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rx_match')
        """ Setup subscriber, setup table_isolation to fwd pkts """
        sub_context = RyuDirectSubscriberContext(
            imsi,
            sub_ip,
            self.enforcement_controller,
            self._enforcement_tbl_num,
            self.enforcement_stats_controller,
            nuke_flows_on_exit=False).add_dynamic_rule(
                policies[0]).add_dynamic_rule(policies[1])
        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context.cfg).build_requests(), self.testing_controller)
        """ Create 2 sets of packets, for policry rule1&2 """
        pkt_sender = ScapyPacketInjector(self.IFACE)
        packet1 = IPPacketBuilder()\
            .set_ip_layer('45.10.0.0/20', sub_ip)\
            .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\
            .build()
        packet2 = IPPacketBuilder()\
            .set_ip_layer(sub_ip, '45.10.0.0/20')\
            .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\
            .build()

        # =========================== Verification ===========================
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager,
                                             'initial_flows')
        """ Send packets, wait until pkts are received by ovs and enf stats """
        with isolator, sub_context, snapshot_verifier:
            pkt_sender.send(packet1)
            pkt_sender.send(packet2)

        stats = get_enforcement_stats(
            self.enforcement_stats_controller._report_usage.call_args_list)

        self.assertEqual(stats[enf_stat_name[0]].sid, imsi)
        self.assertEqual(stats[enf_stat_name[0]].rule_id, "tx_match")
        self.assertEqual(stats[enf_stat_name[0]].bytes_rx, 0)
        self.assertEqual(stats[enf_stat_name[0]].bytes_tx,
                         num_pkts_tx_match * len(packet1))
        self.assertEqual(stats[enf_stat_name[1]].sid, imsi)
        self.assertEqual(stats[enf_stat_name[1]].rule_id, "rx_match")
        self.assertEqual(stats[enf_stat_name[1]].bytes_tx, 0)
        self.assertEqual(stats[enf_stat_name[1]].bytes_rx, 5120)

        # downlink packets will discount ethernet header by default
        # so, only count the IP portion
        total_bytes_pkt2 = num_pkts_rx_match * len(packet2[IP])
        self.assertEqual(stats[enf_stat_name[1]].bytes_rx, total_bytes_pkt2)

        # NOTE this value is 8 because the EnforcementStatsController rule
        # reporting doesn't reset on clearing flows(lingers from old tests)
        self.assertEqual(len(stats), 3)

        setup_flows_request = SetupFlowsRequest(requests=[
            ActivateFlowsRequest(sid=SIDUtils.to_pb(imsi),
                                 ip_addr=sub_ip,
                                 dynamic_rules=[policies[0], policies[1]]),
        ],
                                                epoch=global_epoch)

        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller,
            setup_flows_request=setup_flows_request)

        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager,
                                             'after_restart')

        with snapshot_verifier:
            pass
    def test_ue_mac_restart(self, directoryd_mock):
        """
        Verify that default flows are properly installed with empty setup
        Verify that ue mac flows are properly restored, with arp recovery from
        directoryd
        """

        imsi1 = 'IMSI111111111111111'
        imsi2 = 'IMSI222222222222222'
        ip1 = '152.81.12.41'
        mac1 = '5e:cc:cc:b1:aa:aa'
        mac2 = 'b2:6a:f3:b3:2f:4c'
        ap_mac_addr1 = '11:22:33:44:55:66'
        ap_mac_addr2 = '12:12:13:24:25:26'

        directoryd_mock.return_value = [
            DirectoryRecord(id=imsi1,
                            fields={
                                'ipv4_addr': ip1,
                                'mac_addr': mac1
                            })
        ]

        fake_cwf_setup(ue_mac_controller=self.ue_mac_controller)
        snapshot_verifier = SnapshotVerifier(self,
                                             self.BRIDGE,
                                             self.service_manager,
                                             'default_flows',
                                             include_stats=False)
        with snapshot_verifier:
            pass

        setup_ue_mac_request = SetupUEMacRequest(
            requests=[
                UEMacFlowRequest(
                    sid=SIDUtils.to_pb(imsi1),
                    mac_addr=mac1,
                    msisdn='123456',
                    ap_mac_addr=ap_mac_addr1,
                    ap_name='magma',
                    pdp_start_time=1,
                ),
                UEMacFlowRequest(
                    sid=SIDUtils.to_pb(imsi2),
                    mac_addr=mac2,
                    msisdn='654321',
                    ap_mac_addr=ap_mac_addr2,
                    ap_name='amgam',
                    pdp_start_time=9,
                ),
            ],
            epoch=global_epoch,
        )

        fake_cwf_setup(ue_mac_controller=self.ue_mac_controller,
                       setup_ue_mac_request=setup_ue_mac_request)

        snapshot_verifier = SnapshotVerifier(self,
                                             self.BRIDGE,
                                             self.service_manager,
                                             'recovery_flows',
                                             include_stats=False)
        with snapshot_verifier:
            pass
Example #24
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
        """
        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,
            ),
        ]
        policies = [
            VersionedPolicy(
                rule=PolicyRule(id='simple_match',
                                priority=2,
                                flow_list=flow_list1),
                version=1,
            ),
        ]
        pkts_matched = 256
        pkts_sent = 4096

        # ============================ 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 = 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),
        )
        snapshot_verifier = SnapshotVerifier(
            self,
            self.BRIDGE,
            self.service_manager,
        )

        with isolator, sub_context, flow_verifier, snapshot_verifier:
            pkt_sender.send(packet)

        flow_verifier.verify()
Example #25
0
    def test_traffic_paging_flow(self):
        """
           Add paging flow in table 0
        """
        # Need to delete all default flows in table 0 before
        # install the specific flows test case.
        self.classifier_controller._delete_all_flows()

        ue_ip_addr = "192.168.128.30"
        self.classifier_controller.install_paging_flow(
            200,
            IPAddress(version=IPAddress.IPV4,
                      address=ue_ip_addr.encode('utf-8')),
            True,
        )
        # Create a set of packets
        pkt_sender = ScapyPacketInjector(self.BRIDGE)
        eth = Ether(dst=self.MAC_1, src=self.MAC_2)
        ip = IP(src=self.Dst_nat, dst='192.168.128.30')
        o_udp = UDP(sport=2152, dport=2152)
        i_udp = UDP(sport=1111, dport=2222)
        i_tcp = TCP(seq=1, sport=1111, dport=2222)
        i_ip = IP(src='192.168.60.142', dst=self.EnodeB_IP)

        gtp_packet_udp = eth / ip / o_udp / GTP_U_Header(
            teid=0x1, length=28, gtp_type=255) / i_ip / i_udp
        gtp_packet_tcp = eth / ip / o_udp / GTP_U_Header(
            teid=0x1, length=68, gtp_type=255) / i_ip / i_tcp

        # Check if these flows were added (queries should return flows)
        flow_queries = [
            FlowQuery(
                self._tbl_num,
                self.testing_controller,
                match=MagmaMatch(tunnel_id=1, in_port=32768),
            ),
            FlowQuery(
                self._tbl_num,
                self.testing_controller,
                match=MagmaMatch(ipv4_dst='192.168.128.30'),
            ),
        ]
        # =========================== Verification ===========================
        # Verify 2 flows installed for classifier table (2 pkts matched)

        flow_verifier = FlowVerifier(
            [
                FlowTest(
                    FlowQuery(
                        self._tbl_num,
                        self.testing_controller,
                    ),
                    2,
                    2,
                ),
            ],
            lambda: wait_after_send(self.testing_controller),
        )

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

        with flow_verifier, snapshot_verifier:
            pkt_sender.send(gtp_packet_udp)
            pkt_sender.send(gtp_packet_tcp)

        flow_verifier.verify()