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