Example #1
0
    def __init__(self, magma_service: MagmaService):
        self._magma_service = magma_service
        # inout is a mandatory app and it occupies:
        #   table 1(for ingress)
        #   table 10(for middle)
        #   table 20(for egress)
        self._apps = [
            App(name=InOutController.APP_NAME,
                module=InOutController.__module__,
                type=None,
                order_priority=0)
        ]
        self._table_manager = _TableManager()

        self.rule_id_mapper = RuleIDToNumMapper()
        self.session_rule_version_mapper = SessionRuleToVersionMapper()

        apps = self._get_static_apps()
        apps.extend(self._get_dynamic_apps())
        apps.sort(key=lambda x: x.order_priority)

        self._apps.extend(apps)
        # Filter out reserved apps and apps that don't need a table
        for app in apps:
            if app.name in self.STATIC_APP_WITH_NO_TABLE:
                continue
            # UE MAC service must be registered with Table 0
            if app.name in [
                    self.UE_MAC_ADDRESS_SERVICE_NAME, self.XWF_PASSTHRU_NAME
            ]:
                self._table_manager.register_apps_for_table0_service([app])
                continue
            self._table_manager.register_apps_for_service([app])
Example #2
0
    def __init__(self, magma_service: MagmaService):
        self._magma_service = magma_service
        if 'enable5g_features' not in magma_service.config:
            self._5G_flag_enable = False
        else:
            self._5G_flag_enable = magma_service.config.get(
                'enable5g_features')

        # ingress, middle and egress are mandatory apps and occupy:
        #   table 1 (for ingress)
        #   table 10 (for middle)
        #   table 20 (for egress)
        self._apps = [
            App(
                name=IngressController.APP_NAME,
                module=IngressController.__module__,
                type=None,
                order_priority=0,
            ),
            App(
                name=MiddleController.APP_NAME,
                module=MiddleController.__module__,
                type=None,
                order_priority=0,
            ),
            App(
                name=EgressController.APP_NAME,
                module=EgressController.__module__,
                type=None,
                order_priority=0,
            ),
        ]
        self._table_manager = _TableManager()

        self.rule_id_mapper = RuleIDToNumMapper()
        self.session_rule_version_mapper = SessionRuleToVersionMapper()
        self.interface_to_prefix_mapper = InterfaceIDToPrefixMapper()
        self.restart_info_store = RestartInfoStore()
        self.ebpf = get_ebpf_manager(magma_service.config)

        apps = self._get_static_apps()
        apps.extend(self._get_dynamic_apps())
        apps.sort(key=lambda x: x.order_priority)

        self._apps.extend(apps)
        # Filter out reserved apps and apps that don't need a table
        for app in apps:
            if app.name in self.STATIC_APP_WITH_NO_TABLE:
                continue
            # UE MAC service must be registered with Table 0
            if app.name in [
                    self.UE_MAC_ADDRESS_SERVICE_NAME, self.XWF_PASSTHRU_NAME
            ]:
                self._table_manager.register_apps_for_table0_service([app])
                continue
            if self._5G_flag_enable:
                if app.name in [self.CLASSIFIER_NAME]:
                    self._table_manager.register_apps_for_table0_service([app])
                    continue
            self._table_manager.register_apps_for_service([app])
Example #3
0
    def start_ryu_apps(self, launch_successful_future):
        """
        Starts up ryu applications, all the configuration is parsed from the
        test_setup config provided in the unit test.

        If apps throw an exception on launch, error is passed in the
        launch_successful_future and will prevent infinitely waiting.
        """
        self.reset_static_vars()
        hub.spawn(self._process_queue)

        app_lists = [a.value.name for a in self._test_setup.apps]
        app_futures = {
            controller.value.app_future: future
            for (controller, future) in self._test_setup.references.items()
        }

        manager = AppManager.get_instance()
        manager.load_apps(app_lists)
        contexts = manager.create_contexts()
        contexts['sids_by_ip'] = {}     # shared by both metering apps
        contexts['rule_id_mapper'] = RuleIDToNumMapper()
        contexts['internal_ip_allocator'] = \
            InternalIPAllocator(self._test_setup.config)
        contexts['session_rule_version_mapper'] = \
            self._test_setup.service_manager.session_rule_version_mapper
        contexts['app_futures'] = app_futures
        contexts['config'] = self._test_setup.config
        contexts['mconfig'] = self._test_setup.mconfig
        contexts['loop'] = self._test_setup.loop
        contexts['rpc_stubs'] = self._test_setup.rpc_stubs
        contexts['service_manager'] = self._test_setup.service_manager

        logging.basicConfig(
            level=logging.INFO,
            format='[%(asctime)s %(levelname)s %(name)s] %(message)s')

        services = []
        try:
            services.extend(manager.instantiate_apps(**contexts))
        except Exception as e:
            launch_successful_future.set_result(
                "Ryu apps launch exception: {}".format(e))
            raise

        launch_successful_future.set_result("Setup successful")

        self.run(manager)
Example #4
0
    def __init__(self, magma_service: MagmaService):
        self._magma_service = magma_service
        if '5G_feature_set' not in magma_service.config:
            self._5G_flag_enable = False
        else:
            ng_flag = magma_service.config.get('5G_feature_set')
            self._5G_flag_enable = ng_flag['enable']

        # inout is a mandatory app and it occupies:
        #   table 1(for ingress)
        #   table 10(for middle)
        #   table 20(for egress)
        self._apps = [
            App(name=InOutController.APP_NAME,
                module=InOutController.__module__,
                type=None,
                order_priority=0)
        ]
        self._table_manager = _TableManager()

        self.rule_id_mapper = RuleIDToNumMapper()
        self.session_rule_version_mapper = SessionRuleToVersionMapper()
        self.interface_to_prefix_mapper = InterfaceIDToPrefixMapper()
        self.tunnel_id_mapper = TunnelToTunnelMapper()

        apps = self._get_static_apps()
        apps.extend(self._get_dynamic_apps())
        apps.sort(key=lambda x: x.order_priority)

        self._apps.extend(apps)
        # Filter out reserved apps and apps that don't need a table
        for app in apps:
            if app.name in self.STATIC_APP_WITH_NO_TABLE:
                continue
            # UE MAC service must be registered with Table 0
            if app.name in [
                    self.UE_MAC_ADDRESS_SERVICE_NAME, self.XWF_PASSTHRU_NAME
            ]:
                self._table_manager.register_apps_for_table0_service([app])
                continue
            if self._5G_flag_enable:
                if app.name in [self.CLASSIFIER_NAME]:
                    self._table_manager.register_apps_for_table0_service([app])
                    continue
            self._table_manager.register_apps_for_service([app])
Example #5
0
    def load(self):
        """
        Instantiates and schedules the Ryu app eventlets in the service
        eventloop.
        """
        manager = AppManager.get_instance()
        manager.load_apps([app.module for app in self._apps])
        contexts = manager.create_contexts()
        contexts['rule_id_mapper'] = RuleIDToNumMapper()
        contexts[
            'session_rule_version_mapper'] = self.session_rule_version_mapper
        contexts['app_futures'] = {app.name: Future() for app in self._apps}
        contexts['config'] = self._magma_service.config
        contexts['mconfig'] = self._magma_service.mconfig
        contexts['loop'] = self._magma_service.loop
        contexts['service_manager'] = self

        records_chan = ServiceRegistry.get_rpc_channel('meteringd_records',
                                                       ServiceRegistry.CLOUD)
        sessiond_chan = ServiceRegistry.get_rpc_channel(
            'sessiond', ServiceRegistry.LOCAL)
        mobilityd_chan = ServiceRegistry.get_rpc_channel(
            'mobilityd', ServiceRegistry.LOCAL)
        contexts['rpc_stubs'] = {
            'metering_cloud': MeteringdRecordsControllerStub(records_chan),
            'mobilityd': MobilityServiceStub(mobilityd_chan),
            'sessiond': LocalSessionManagerStub(sessiond_chan),
        }

        # Instantiate and schedule apps
        for app in manager.instantiate_apps(**contexts):
            # Wrap the eventlet in asyncio so it will stop when the loop is
            # stopped
            future = aioeventlet.wrap_greenthread(app,
                                                  self._magma_service.loop)

            # Schedule the eventlet for evaluation in service loop
            asyncio.ensure_future(future)

        # In development mode, run server so that
        if environment.is_dev_mode():
            server_thread = of_rest_server.start(manager)
            future = aioeventlet.wrap_greenthread(server_thread,
                                                  self._magma_service.loop)
            asyncio.ensure_future(future)
    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