Ejemplo n.º 1
0
    def test_setup_flows_req(self):
        gx_req1 = ActivateFlowsRequest()
        gx_req2 = ActivateFlowsRequest()
        gy_req = ActivateFlowsRequest(
            request_origin=RequestOriginType(type=RequestOriginType.GY), )
        setup_req = SetupPolicyRequest(requests=[gx_req1, gx_req2, gy_req])

        self.pipelined_srv.SetupPolicyFlows(setup_req, MagicMock())
        self._enforcer_app.handle_restart.assert_called_with(
            [gx_req1, gx_req2])
        self._enforcement_stats.handle_restart.assert_called_with(
            [gx_req1, gx_req2])
        self._gy_app.handle_restart.assert_called_with([gy_req])
Ejemplo n.º 2
0
def activate_flows(client, args):
    request = ActivateFlowsRequest(
        sid=SIDUtils.to_pb(args.imsi),
        rule_ids=args.rule_ids.split(','),
        request_origin=RequestOriginType(type=RequestOriginType.GX))
    response = client.ActivateFlows(request)
    _print_rule_mod_results(response.static_rule_results)
Ejemplo n.º 3
0
 def _activate_subscriber_rules(self):
     try_grpc_call_with_retries(
         lambda: self._pipelined_stub.ActivateFlows(
             ActivateFlowsRequest(sid=SIDUtils.to_pb(self.cfg.imsi),
                                  rule_ids=self._static_rule_names,
                                  dynamic_rules=self._dynamic_rules))
     )
Ejemplo n.º 4
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.º 5
0
    def CreateSession(self, request, context):
        """
        Handles create session request from MME by installing the necessary
        flows in pipelined's enforcement app.
        """
        sid = request.sid
        logging.info('Create session request for sid: %s' % sid.id)
        try:
            # Gather the set of policy rules to use
            if self._captive_portal_enabled(sid):
                rules = []
                rules.extend(self._get_whitelisted_policies())
                rules.extend(self._get_redirect_policies())
            else:
                rules = self._get_allow_all_traffic_policies()

            # Activate the flows in the enforcement app in pipelined
            act_request = ActivateFlowsRequest(sid=sid,
                                               ip_addr=request.ue_ipv4,
                                               dynamic_rules=rules)
            act_response = self._pipelined.ActivateFlows(
                act_request, timeout=self.RPC_TIMEOUT)
            for res in act_response.dynamic_rule_results:
                if res.result != res.SUCCESS:
                    # Hmm rolling back partial success is difficult
                    # Let's just log this for now
                    logging.error('Failed to activate rule: %s' % res.rule_id)
        except RpcError as err:
            self._set_rpc_error(context, err)
        return session_manager_pb2.LocalCreateSessionResponse()
Ejemplo n.º 6
0
 def _activate_subscriber_rules(self):
     try_grpc_call_with_retries(
         lambda: self._pipelined_stub.ActivateFlows(
             ActivateFlowsRequest(
                 sid=SIDUtils.to_pb(self.cfg.imsi),
                 policies=self._policies,
             ),
         ),
     )
Ejemplo n.º 7
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.º 8
0
    def test_activate_flows_req(self):
        rule = PolicyRule(id="rule1", priority=100, flow_list=[])
        policies = [VersionedPolicy(rule=rule, version=1)]
        req = ActivateFlowsRequest(
            sid=SubscriberID(id="imsi12345"),
            ip_addr="1.2.3.4",
            msisdn=b'magma',
            uplink_tunnel=0x1,
            downlink_tunnel=0x2,
            policies=policies,
        )
        ip_addr = IPAddress(
            version=IPAddress.IPV4,
            address=req.ip_addr.encode('utf-8'),
        )

        self.pipelined_srv.ActivateFlows(req, MagicMock())
        # Not using assert_called_with because protos comparison

        assert self._enforcement_stats.activate_rules.call_args.args[
            0] == req.sid.id
        assert self._enforcement_stats.activate_rules.call_args.args[
            1] == req.msisdn
        assert self._enforcement_stats.activate_rules.call_args.args[
            2] == req.uplink_tunnel
        assert self._enforcement_stats.activate_rules.call_args.args[
            3].version == ip_addr.version
        assert self._enforcement_stats.activate_rules.call_args.args[
            3].address == ip_addr.address
        assert self._enforcement_stats.activate_rules.call_args.args[
            4] == req.apn_ambr
        assert self._enforcement_stats.activate_rules.call_args.args[5][
            0].version == policies[0].version
        assert self._enforcement_stats.activate_rules.call_args.args[
            6] == req.shard_id
        assert self._enforcement_stats.activate_rules.call_args.args[7] == 0

        assert self._enforcer_app.activate_rules.call_args.args[
            0] == req.sid.id
        assert self._enforcer_app.activate_rules.call_args.args[
            1] == req.msisdn
        assert self._enforcer_app.activate_rules.call_args.args[
            2] == req.uplink_tunnel
        assert self._enforcer_app.activate_rules.call_args.args[
            3].version == ip_addr.version
        assert self._enforcer_app.activate_rules.call_args.args[
            3].address == ip_addr.address
        assert self._enforcer_app.activate_rules.call_args.args[
            4] == req.apn_ambr
        assert self._enforcer_app.activate_rules.call_args.args[5][
            0].version == policies[0].version
        assert self._enforcer_app.activate_rules.call_args.args[
            6] == req.shard_id
        assert self._enforcer_app.activate_rules.call_args.args[7] == 0
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 activate_gy_redirect(client, args):
    request = ActivateFlowsRequest(
        sid=SIDUtils.to_pb(args.imsi),
        ip_addr=args.ipv4,
        dynamic_rules=[
            PolicyRule(id=args.rule_id,
                       priority=999,
                       flow_list=[],
                       redirect=RedirectInformation(
                           support=1,
                           address_type=2,
                           server_address=args.redirect_addr))
        ],
        request_origin=RequestOriginType(type=RequestOriginType.GY))
    response = client.ActivateFlows(request)
    _print_rule_mod_results(response.dynamic_rule_results)
Ejemplo n.º 11
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.º 12
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.º 13
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
Ejemplo n.º 14
0
def activate_gy_redirect(client, args):
    request = ActivateFlowsRequest(
        sid=SIDUtils.to_pb(args.imsi),
        ip_addr=args.ipv4,
        policies=[
            VersionedPolicy(
                rule=PolicyRule(
                    id=args.rule_id,
                    priority=999,
                    flow_list=[],
                    redirect=RedirectInformation(
                        support=1,
                        address_type=2,
                        server_address=args.redirect_addr,
                    ),
                ),
                version=1,
            ),
        ],
        request_origin=RequestOriginType(type=RequestOriginType.GY),
        shard_id=args.shard_id,
    )
    response = client.ActivateFlows(request)
    _print_rule_mod_results(response.policy_results)
Ejemplo n.º 15
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(ipv4_dst='45.10.0.0/24',
                                            direction=FlowMatch.UPLINK),
                            action=FlowDescription.PERMIT),
            FlowDescription(match=FlowMatch(ipv4_dst='45.11.0.0/24',
                                            direction=FlowMatch.UPLINK),
                            action=FlowDescription.PERMIT)
        ]
        flow_list2 = [
            FlowDescription(match=FlowMatch(ipv4_dst='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', imsi2 + '|sub2_rule_keep']

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

        setup_flows_request = SetupFlowsRequest(requests=[
            ActivateFlowsRequest(sid=SIDUtils.to_pb(imsi1),
                                 dynamic_rules=policies1),
            ActivateFlowsRequest(sid=SIDUtils.to_pb(imsi2),
                                 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()
        pkts_sent = 4096
        pkts_matched = 256
        flow_query = FlowQuery(self._enforcement_tbl_num,
                               self.testing_controller,
                               match=flow_match_to_magma_match(
                                   flow_list2[0].match))
        flow_verifier = FlowVerifier([
            FlowTest(
                FlowQuery(self._enforcement_tbl_num, self.testing_controller),
                pkts_sent),
            FlowTest(flow_query, pkts_matched)
        ], self._wait_func(enf_stat_name))
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager,
                                             'before_restart')
        with isolator, flow_verifier, snapshot_verifier:
            pkt_sender.send(packets)

        flow_verifier.verify()

        flow_list1 = [
            FlowDescription(match=FlowMatch(ipv4_dst='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, 'sub2_new_rule')
        enf_stat_name = [imsi2 + '|sub2_new_rule', imsi2 + '|sub2_rule_keep']
        setup_flows_request = SetupFlowsRequest(requests=[
            ActivateFlowsRequest(sid=SIDUtils.to_pb(imsi2),
                                 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)
        flow_verifier = FlowVerifier([FlowTest(flow_query, pkts_matched)],
                                     self._wait_func(enf_stat_name))
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager,
                                             'after_restart')
        with flow_verifier, 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
Ejemplo n.º 16
0
def activate_flows(client, args):
    request = ActivateFlowsRequest(
        sid=SIDUtils.to_pb(args.imsi),
        rule_ids=args.rule_ids.split(','))
    client.ActivateFlows(request)
Ejemplo n.º 17
0
def stress_test_grpc(client, args):
    print("WARNING: DO NOT USE ON PRODUCTION SETUPS")
    delta_time = 1 / args.attaches_per_sec
    print("Attach every ~{0} seconds".format(delta_time))

    if args.disable_qos:
        print("QOS Disabled")
        apn_ambr = None
    else:
        print("QOS Enabled")
        apn_ambr = AggregatedMaximumBitrate(
            max_bandwidth_ul=1000000000,
            max_bandwidth_dl=1000000000,
        )

    for i in range(0, args.test_iterations):
        print("Starting iteration {0} of attach/detach requests".format(i))
        ue_dict = _gen_ue_set(args.num_of_ues)
        print("Starting attaches")

        timestamp = datetime.now()
        completed_reqs = 0
        for ue in ue_dict:
            grpc_start_timestamp = datetime.now()
            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,
            )
            response = client.ActivateFlows(request)
            if any(
                r.result != RuleModResult.SUCCESS for
                r in response.policy_results
            ):
                _print_rule_mod_results(response.policy_results)

            grpc_end_timestamp = datetime.now()
            call_duration = (grpc_end_timestamp - grpc_start_timestamp).total_seconds()
            if call_duration < delta_time:
                time.sleep(delta_time - call_duration)
            if completed_reqs % LOG_INCREMENT == 0:
                print("Finished {0}".format(completed_reqs))
            completed_reqs += 1

        duration = (datetime.now() - timestamp).total_seconds()
        print(
            "Finished {0} attaches in {1} seconds".format(
                len(ue_dict),
                duration,
            ),
        )
        print("Actual attach rate = {0} UEs per sec".format(round(len(ue_dict) / duration)))

        time.sleep(args.time_between_detach)

        print("Starting detaches")
        timestamp = datetime.now()
        completed_reqs = 0
        for ue in ue_dict:
            grpc_start_timestamp = datetime.now()
            request = DeactivateFlowsRequest(
                sid=SIDUtils.to_pb(ue.imsi_str),
                ip_addr=ue.ipv4_src,
                policies=[
                    VersionedPolicyID(
                        rule_id=ue.rule_id,
                        version=1,
                    ),
                ],
                request_origin=RequestOriginType(type=RequestOriginType.GX),
                remove_default_drop_flows=True,
            )
            response = client.DeactivateFlows(request)
            if response.result != DeactivateFlowsResult.SUCCESS:
                _print_rule_mod_results(response.policy_results)

            grpc_end_timestamp = datetime.now()
            call_duration = (grpc_end_timestamp - grpc_start_timestamp).total_seconds()
            if call_duration < delta_time:
                time.sleep(delta_time - call_duration)
            if completed_reqs % LOG_INCREMENT == 0:
                print("Finished {0}".format(completed_reqs))
            completed_reqs += 1

        duration = (datetime.now() - timestamp).total_seconds()
        print(
            "Finished {0} detaches in {1} seconds".format(
                len(ue_dict),
                duration,
            ),
        )
        print(
            "Actual detach rate = {0} UEs per sec".format(
                round(len(ue_dict) / duration),
            ),
        )
Ejemplo n.º 18
0
def stress_test_grpc(client, args):
    print("WARNING: DO NOT USE ON PRODUCTION SETUPS")
    UEInfo = namedtuple('UEInfo', ['imsi_str', 'ipv4_src', 'ipv4_dst',
                                   'rule_id'])
    delta_time = 1/args.attaches_per_sec
    print("Attach every ~{0} seconds".format(delta_time))

    if args.disable_qos:
        print("QOS Disabled")
        apn_ambr = None
    else:
        print("QOS Enabled")
        apn_ambr = AggregatedMaximumBitrate(
            max_bandwidth_ul=1000000000,
            max_bandwidth_dl=1000000000,
        )

    def _gen_ue_set(num_of_ues):
        imsi = 123000000
        ue_set = set()
        for _ in range(0, num_of_ues):
            imsi_str = "IMSI" + str(imsi)
            ipv4_src = ".".join(str(random.randint(0, 255)) for _ in range(4))
            ipv4_dst = ".".join(str(random.randint(0, 255)) for _ in range(4))
            rule_id = "allow." + imsi_str
            ue_set.add(UEInfo(imsi_str, ipv4_src, ipv4_dst, rule_id))
            imsi = imsi + 1
        return ue_set

    for i in range (0, args.test_iterations):
        print("Starting iteration {0} of attach/detach requests".format(i))
        ue_dict = _gen_ue_set(args.num_of_ues)
        print("Starting attaches")

        timestamp = datetime.now()
        for ue in ue_dict:
            grpc_start_timestamp = datetime.now()
            request = ActivateFlowsRequest(
                sid=SIDUtils.to_pb(ue.imsi_str),
                ip_addr=ue.ipv4_src,
                dynamic_rules=[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)),
                    ],
                )],
                request_origin=RequestOriginType(type=RequestOriginType.GX),
                apn_ambr=apn_ambr,
            )
            response = client.ActivateFlows(request)
            if any(r.result != RuleModResult.SUCCESS for
                   r in response.dynamic_rule_results):
                _print_rule_mod_results(response.dynamic_rule_results)

            grpc_end_timestamp = datetime.now()
            call_duration = (grpc_end_timestamp - grpc_start_timestamp).total_seconds()
            if call_duration < delta_time:
                time.sleep(delta_time - call_duration)

        duration = (datetime.now() - timestamp).total_seconds()
        print("Finished {0} attaches in {1} seconds".format(len(ue_dict),
                                                            duration))
        print("Actual attach rate = {0} UEs per sec".format(round(len(ue_dict)/duration)))

        time.sleep(args.time_between_detach)

        print("Starting detaches")
        timestamp = datetime.now()
        for ue in ue_dict:
            grpc_start_timestamp = datetime.now()
            request = DeactivateFlowsRequest(
                sid=SIDUtils.to_pb(ue.imsi_str),
                ip_addr=ue.ipv4_src,
                rule_ids=[ue.rule_id],
                request_origin=RequestOriginType(type=RequestOriginType.GX),
                remove_default_drop_flows=True)
            response = client.DeactivateFlows(request)
            if response.result != DeactivateFlowsResult.SUCCESS:
                _print_rule_mod_results(response.dynamic_rule_results)

            grpc_end_timestamp = datetime.now()
            call_duration = (grpc_end_timestamp - grpc_start_timestamp).total_seconds()
            if call_duration < delta_time:
                time.sleep(delta_time - call_duration)

        duration = (datetime.now() - timestamp).total_seconds()
        print("Finished {0} detaches in {1} seconds".format(len(ue_dict),
                                                            duration))
        print("Actual detach rate = {0} UEs per sec",
              round(len(ue_dict)/duration))
Ejemplo n.º 19
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,
                    policies=[VersionedPolicy(rule=policy, version=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,
        )

        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)
Ejemplo n.º 20
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
        """
        self.enforcement_controller._rule_mapper = RuleIDToNumMapper()
        self.enforcement_stats_controller._rule_mapper = RuleIDToNumMapper()
        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 = [
            VersionedPolicy(
                rule=PolicyRule(id='sub1_rule_temp',
                                priority=2,
                                flow_list=flow_list1),
                version=1,
            ),
        ]
        policies2 = [
            VersionedPolicy(
                rule=PolicyRule(id='sub2_rule_keep',
                                priority=3,
                                flow_list=flow_list2),
                version=1,
            ),
        ]
        enf_stat_name = [
            imsi1 + '|sub1_rule_temp' + '|' + sub2_ip,
            imsi2 + '|sub2_rule_keep' + '|' + sub2_ip,
        ]

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

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

        # Simulate clearing the dict
        self.service_manager.session_rule_version_mapper\
            ._version_by_imsi_and_rule = {}

        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 = [
            VersionedPolicy(
                rule=PolicyRule(id='sub2_new_rule',
                                priority=2,
                                flow_list=flow_list1),
                version=1,
            ),
            VersionedPolicy(
                rule=PolicyRule(id='sub2_rule_keep',
                                priority=3,
                                flow_list=flow_list2),
                version=1,
            ),
        ]
        enf_stat_name = [
            imsi2 + '|sub2_new_rule' + '|' + sub2_ip + "|" + "1",
            imsi2 + '|sub2_rule_keep' + '|' + sub2_ip + "|" + "1",
        ]
        setup_flows_request = SetupFlowsRequest(
            requests=[
                ActivateFlowsRequest(
                    sid=SIDUtils.to_pb(imsi2),
                    ip_addr=sub2_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_w_packets',
        )

        with snapshot_verifier:
            pass
Ejemplo n.º 21
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
        """
        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(ipv4_dst='45.10.0.0/25',
                                            direction=FlowMatch.UPLINK),
                            action=FlowDescription.PERMIT)
        ]
        flow_list2 = [
            FlowDescription(match=FlowMatch(ipv4_src='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', imsi + '|rx_match']
        self.service_manager.session_rule_version_mapper.update_version(
            imsi, 'tx_match')
        self.service_manager.session_rule_version_mapper.update_version(
            imsi, 'rx_match')
        """ Setup subscriber, setup table_isolation to fwd pkts """
        self._static_rule_dict[policies[0].id] = policies[0]
        self._static_rule_dict[policies[1].id] = policies[1]
        sub_context = RyuDirectSubscriberContext(
            imsi,
            sub_ip,
            self.enforcement_controller,
            self._enforcement_tbl_num,
            self.enforcement_stats_controller,
            nuke_flows_on_exit=False).add_static_rule(
                policies[0].id).add_static_rule(policies[1].id)
        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 ===========================
        flow_verifier = FlowVerifier([], self._wait_func(enf_stat_name))
        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, flow_verifier, 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)

        # 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 5 because the EnforcementStatsController rule
        # reporting doesn't reset on clearing flows(lingers from old tests)
        self.assertEqual(len(stats), 5)

        setup_flows_request = SetupFlowsRequest(requests=[
            ActivateFlowsRequest(sid=SIDUtils.to_pb(imsi),
                                 rule_ids=[policies[0].id, policies[1].id]),
        ],
                                                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 flow_verifier, snapshot_verifier:
            pass

        self.assertEqual(stats[enf_stat_name[0]].bytes_tx,
                         num_pkts_tx_match * len(packet1))
Ejemplo n.º 22
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()
Ejemplo n.º 23
0
    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