def build_desired_config( mconfig: Any, service_config: Any, device_config: EnodebConfiguration, data_model: DataModel, post_processor: EnodebConfigurationPostProcessor, ) -> EnodebConfiguration: """ Factory for initializing DESIRED data model configuration. When working with the configuration of an eNodeB, we track the current state of configuration for that device, as well as what configuration we want to set on the device. Args: mconfig: Managed configuration, eNodeB protobuf message service_config: Returns: Desired data model configuration for the device """ cfg_desired = EnodebConfiguration(data_model) # Determine configuration parameters _set_management_server(cfg_desired) # Attempt to load device configuration from YANG before service mconfig enb_config = _get_enb_yang_config(device_config) or \ _get_enb_config(mconfig, device_config) _set_earfcn_freq_band_mode(device_config, cfg_desired, data_model, enb_config.earfcndl) if enb_config.subframe_assignment is not None: _set_tdd_subframe_config(device_config, cfg_desired, enb_config.subframe_assignment, enb_config.special_subframe_pattern) _set_pci(cfg_desired, enb_config.pci) _set_plmnids_tac(cfg_desired, enb_config.plmnid_list, enb_config.tac) _set_bandwidth(cfg_desired, data_model, enb_config.bandwidth_mhz) _set_cell_id(cfg_desired, enb_config.cell_id) _set_perf_mgmt( cfg_desired, get_ip_from_if(service_config['tr069']['interface']), service_config['tr069']['perf_mgmt_port']) _set_misc_static_params(device_config, cfg_desired, data_model) if enb_config.mme_address is not None and enb_config.mme_port is not None: _set_s1_connection(cfg_desired, enb_config.mme_address, enb_config.mme_port) else: _set_s1_connection( cfg_desired, get_ip_from_if(service_config['s1_interface'])) # Enable LTE if we should cfg_desired.set_parameter(ParameterName.ADMIN_STATE, enb_config.allow_enodeb_transmit) post_processor.postprocess(cfg_desired) return cfg_desired
def build_desired_config( mconfig: Any, service_config: Any, device_config: EnodebConfiguration, data_model: DataModel, post_processor: EnodebConfigurationPostProcessor, ) -> EnodebConfiguration: """ Factory for initializing DESIRED data model configuration. When working with the configuration of an eNodeB, we track the current state of configuration for that device, as well as what configuration we want to set on the device. Args: mconfig: Managed configuration, eNodeB protobuf message service_config: Returns: Desired data model configuration for the device """ cfg_desired = EnodebConfiguration(data_model) # Determine configuration parameters _set_management_server(cfg_desired) if mconfig.tdd_config is not None and str(mconfig.tdd_config) != '': _set_earfcn_freq_band_mode(device_config, cfg_desired, data_model, mconfig.tdd_config.earfcndl) _set_tdd_subframe_config(device_config, cfg_desired, mconfig.tdd_config.subframe_assignment, mconfig.tdd_config.special_subframe_pattern) elif mconfig.fdd_config is not None and str(mconfig.fdd_config) != '': _set_earfcn_freq_band_mode(device_config, cfg_desired, data_model, mconfig.fdd_config.earfcndl) else: # back-compat: use legacy fields if tdd/fdd aren't set _set_earfcn_freq_band_mode(device_config, cfg_desired, data_model, mconfig.earfcndl) _set_tdd_subframe_config(device_config, cfg_desired, mconfig.subframe_assignment, mconfig.special_subframe_pattern) _set_pci(cfg_desired, mconfig.pci) _set_plmnids_tac(cfg_desired, mconfig.plmnid_list, mconfig.tac) _set_bandwidth(cfg_desired, data_model, mconfig.bandwidth_mhz) _set_s1_connection(cfg_desired, get_ip_from_if(service_config['s1_interface'])) _set_perf_mgmt(cfg_desired, get_ip_from_if(service_config['tr069']['interface']), service_config['tr069']['perf_mgmt_port']) _set_misc_static_params(device_config, cfg_desired, data_model) # Enable LTE if we should cfg_desired.set_parameter(ParameterName.ADMIN_STATE, mconfig.allow_enodeb_transmit) post_processor.postprocess(cfg_desired) return cfg_desired
def run(self) -> None: """ Create and start HTTP server """ svc_config = load_service_config("enodebd") app = web.Application() app.router.add_route( 'POST', "/{something}", self._post_and_put_handler, ) app.router.add_route( 'PUT', "/{something}", self._post_and_put_handler, ) handler = app.make_handler() create_server_func = self.loop.create_server( handler, host=get_ip_from_if(svc_config['tr069']['interface']), port=svc_config['tr069']['perf_mgmt_port'], ) self._periodic_check_rf_tx() self.loop.run_until_complete(create_server_func)
async def set_enodebd_iptables_rule(): """ Remove & Set iptable rules for exposing public IP for enobeb instead of private IP.. """ # Remove & Set iptable rules for exposing public ip # for enobeb instead of private cfg = load_service_config('enodebd') port, interface = cfg['tr069']['port'], cfg['tr069']['interface'] enodebd_public_ip = cfg['tr069']['public_ip'] # IPv4 only as iptables only works for IPv4. TODO: Investigate ip6tables? enodebd_ip = get_ip_from_if(interface, preference=IpPreference.IPV4_ONLY) # Incoming data from 192.88.99.142 -> enodebd address (eg 192.168.60.142) enodebd_netmask = get_if_ip_with_netmask( interface, preference=IpPreference.IPV4_ONLY, )[1] verify_config = does_iface_config_match_expected( enodebd_ip, enodebd_netmask, ) if not verify_config: logging.warning( 'The IP address of the %s interface is %s. The ' 'expected IP addresses are %s', interface, enodebd_ip, str(EXPECTED_IP4)) await check_and_apply_iptables_rules( port, enodebd_public_ip, enodebd_ip, )
def _get_platform_info(self) -> PlatformInfo: try: gw_ip = get_ip_from_if('tun0') # look for tun0 interface except ValueError: gw_ip = 'N/A' kernel_versions_installed = [] if self._kernel_version_poller is not None: kernel_versions_installed = \ self._kernel_version_poller.get_kernel_versions_installed() platform_info = PlatformInfo( vpn_ip=gw_ip, packages=[ Package( name='magma', version=self._service.version, )._asdict(), ], kernel_version=self._kernel_version, kernel_versions_installed=kernel_versions_installed, config_info=ConfigInfo( mconfig_created_at=self._service.mconfig_metadata.created_at, )._asdict(), ) return platform_info
def _get_dns_ip(iface_config): """ Get dnsd interface IP without netmask. If caching is enabled, use the ip of interface that dnsd listens over. Otherwise, just use dns server in yml. """ if load_service_mconfig("mme", MME()).enable_dns_caching: iface_name = get_service_config_value("dnsd", iface_config, "") return get_ip_from_if(iface_name) return get_service_config_value("spgw", "ipv4_dns", "")
def _get_dns_ip(iface_config): """ Get dnsd interface IP without netmask. If caching is enabled, use the ip of interface that dnsd listens over. Otherwise, just use dns server in yml. """ if load_service_mconfig('mme').enable_dns_caching: iface_name = get_service_config_value('dnsd', iface_config, '') return get_ip_from_if(iface_name) return get_service_config_value('spgw', 'ipv4_dns', '')
def _get_primary_dns_ip(service_mconfig, iface_config): """ Get dnsd interface IP without netmask. If caching is enabled, use the ip of interface that dnsd listens over. Otherwise, use dns server from service mconfig. """ if service_mconfig.enable_dns_caching: iface_name = get_service_config_value("dnsd", iface_config, "") return get_ip_from_if(iface_name) else: return service_mconfig.dns_primary or DEFAULT_DNS_IP_PRIMARY_ADDR
def __init__(self, service): chan = ServiceRegistry.get_rpc_channel('pipelined', ServiceRegistry.LOCAL) self._pipelined = PipelinedStub(chan) chan = ServiceRegistry.get_rpc_channel('subscriberdb', ServiceRegistry.LOCAL) self._subscriberdb = SubscriberDBStub(chan) self._enabled = service.config['captive_portal_enabled'] self._captive_portal_address = service.config['captive_portal_url'] self._local_ip = get_ip_from_if(service.config['bridge_interface']) self._whitelisted_ips = service.config['whitelisted_ips'] self._sub_profile_substr = service.config[ 'subscriber_profile_substr_match']
def tr069_server(state_machine_manager: StateMachineManager) -> None: """ TR-069 server Inputs: - acs_to_cpe_queue = instance of Queue containing messages from parent process/thread to be sent to CPE - cpe_to_acs_queue = instance of Queue containing messages from CPE to be sent to parent process/thread """ config = load_service_config("enodebd") AutoConfigServer.set_state_machine_manager(state_machine_manager) app = Tr069Application( [AutoConfigServer], CWMP_NS, in_protocol=Tr069Soap11(validator='soft'), out_protocol=Tr069Soap11(), ) wsgi_app = WsgiApplication(app) try: ip_address = get_ip_from_if(config['tr069']['interface']) except (ValueError, KeyError) as e: # Interrupt main thread since process should not continue without TR-069 _thread.interrupt_main() raise e socket.setdefaulttimeout(SOCKET_TIMEOUT) logger.info( 'Starting TR-069 server on %s:%s', ip_address, config['tr069']['port'], ) server = make_server( ip_address, config['tr069']['port'], wsgi_app, WSGIServer, tr069_WSGIRequestHandler, ) # Note: use single-thread server, to avoid state contention try: server.serve_forever() finally: # Log error and interrupt main thread, to ensure that entire process # is restarted if this thread exits logger.error('Hit error in TR-069 thread. Interrupting main thread.') _thread.interrupt_main()
async def _checkin(self, service_statusmeta): """ if previous checkin is successful, create a new channel (to make sure the channel does't become stale). Otherwise, keep the existing channel. """ if self._checkin_client is None: chan = ServiceRegistry.get_rpc_channel('checkind', ServiceRegistry.CLOUD) self._checkin_client = CheckindStub(chan) mconfig = self._service.mconfig cpu = psutil.cpu_times() mem = psutil.virtual_memory() try: gw_ip = get_ip_from_if('tun0') # look for tun0 interface except ValueError: gw_ip = 'N/A' request = CheckinRequest( gateway_id=snowflake.snowflake(), magma_pkg_version=self._service.version, system_status=SystemStatus( cpu_user=int(cpu.user * 1000), # convert second to millisecond cpu_system=int(cpu.system * 1000), cpu_idle=int(cpu.idle * 1000), mem_total=mem.total, mem_available=mem.available, mem_used=mem.used, mem_free=mem.free, uptime_secs=int(time.time() - self._boot_time), ), vpn_ip=gw_ip, kernel_version=self._kernel_version, kernel_versions_installed=self._kernel_versions_installed, ) for statusmeta in service_statusmeta.values(): request.status.meta.update(statusmeta) try: await grpc_async_wrapper( self._checkin_client.Checkin.future( request, mconfig.checkin_timeout, ), self._loop) self._checkin_done() except grpc.RpcError as err: self._checkin_error(err)
def run(self): """ Create and start HTTP server """ svc_config = load_service_config("enodebd") app = web.Application() app.router.add_route('POST', "/{something}", self.post_handler) loop = asyncio.get_event_loop() handler = app.make_handler() create_server_func = loop.create_server( handler, host=get_ip_from_if(svc_config['tr069']['interface']), port=svc_config['tr069']['perf_mgmt_port']) loop.run_until_complete(create_server_func)
def set_enodebd_iptables_rule(): """ Remove & Set iptable rules for exposing public IP for enobeb instead of private IP.. """ # Remove & Set iptable rules for exposing public ip # for enobeb instead of private cfg = load_service_config('enodebd') port, interface = cfg['tr069']['port'], cfg['tr069']['interface'] enodebd_public_ip = cfg['tr069']['public_ip'] # IPv4 only as iptables only works for IPv4. TODO: Investigate ip6tables? enodebd_ip = get_ip_from_if(interface, preference=IpPreference.IPV4_ONLY) # Incoming data from 192.88.99.142 -> enodebd address (eg 192.168.60.142) yield from run(get_iptables_rule( port, enodebd_public_ip, enodebd_ip, add=False)) yield from run(get_iptables_rule( port, enodebd_public_ip, enodebd_ip, add=True))
def main(): """ This module is used for manual testing of the TR-069 server """ config = load_service_config("enodebd") app = Tr069Application([AutoConfigServer], CWMP_NS, in_protocol=Tr069Soap11(validator="soft"), out_protocol=Tr069Soap11()) ip_address = get_ip_from_if(config['tr069']['interface']) client = Tr069HttpClient( "http://%s:%s" % (ip_address, config["tr069"]["port"]), app) client.set_options(out_header=ID("123", mustUnderstand="1")) rpc_methods = client.service.get_rpc_methods() for rpc_method in rpc_methods: print("Method: %s" % rpc_method) inform_req = client.factory.create("Inform") inform_req.DeviceId = client.factory.create("DeviceIdStruct") inform_req.DeviceId.Manufacturer = "Magma" inform_req.DeviceId.OUI = "ABCDEF" inform_req.DeviceId.ProductClass = "TopClass" inform_req.DeviceId.SerialNumber = "123456789" inform_req.Event = None inform_req.MaxEnvelopes = 1 inform_req.CurrentTime = None inform_req.RetryCount = 4 inform_req.ParameterList = None client.set_options(out_header=ID("456", mustUnderstand="1")) client.service.Inform(inform_req) dummy = DummyInput() dummy.Field1 = 5 rsp = client.service.EmptyHttp(dummy) print("EmptyHttp response = ", rsp) paramNames = client.factory.create("GetParameterNamesResponse") paramNames.ParameterList = client.factory.create("ParameterInfoList") paramNames.ParameterList.ParameterInfoStruct =\ [client.factory.create("ParameterInfoStruct")] paramNames.ParameterList.ParameterInfoStruct[0].Name = "Parameter1" paramNames.ParameterList.ParameterInfoStruct[0].Writable = True rsp = client.service.GetParameterNamesResponse(paramNames) print("GetParameterNamesResponse response = ", rsp)
def _platform_info(self): try: gw_ip = get_ip_from_if('tun0') # look for tun0 interface except ValueError: gw_ip = 'N/A' mconfig_metadata = self._service.mconfig_metadata return PlatformInfo( vpn_ip=gw_ip, packages=[ Package( name='magma', version=self._service.version, ), ], kernel_version=self._kernel_version, kernel_versions_installed=self._kernel_versions_installed, config_info=ConfigInfo( mconfig_created_at=mconfig_metadata.created_at, ), )
def get_context(): """ Provide context to pass to Jinja2 for templating. """ context = {} cfg = load_service_config("lighttpd") ip = "127.0.0.1" enable_caching = False try: mconfig = load_service_mconfig_as_json('lighttpd') enable_caching = mconfig.enable_caching except LoadConfigError: logging.info("Using default values for service 'lighttpd'") if enable_caching: ip = get_ip_from_if(cfg['interface']) context['interface_ip'] = ip context['store_root'] = cfg['store_root'] return context
def _get_platform_info_tuple(self, kernel_versions: List[str]) -> PlatformInfo: try: gw_ip = get_ip_from_if('tun0') # look for tun0 interface except ValueError: gw_ip = 'N/A' mconfig_metadata = self._service.mconfig_metadata platform_info = PlatformInfo( vpn_ip=gw_ip, packages=[ Package( name='magma', version=self._service.version, )._asdict(), ], kernel_version=self._kernel_version, kernel_versions_installed=kernel_versions, config_info=ConfigInfo( mconfig_created_at=mconfig_metadata.created_at, )._asdict(), ) return platform_info
def main(): """ Loads the Ryu apps we want to run from the config file. This should exit on keyboard interrupt. """ # Run asyncio loop in a greenthread so we can evaluate other eventlets # TODO: Remove once Ryu migrates to asyncio asyncio.set_event_loop_policy(aioeventlet.EventLoopPolicy()) service = MagmaService('pipelined', mconfigs_pb2.PipelineD()) # Optionally pipe errors to Sentry sentry_init(service_name=service.name) service_config = service.config if environment.is_dev_mode(): of_rest_server.configure(service_config) # Set Ryu config params cfg.CONF.ofp_listen_host = "127.0.0.1" # override mconfig using local config. # TODO: move config compilation to separate module. enable_nat = service.config.get('enable_nat', service.mconfig.nat_enabled) service.config['enable_nat'] = enable_nat logging.info("Nat: %s", enable_nat) vlan_tag = service.config.get( 'sgi_management_iface_vlan', service.mconfig.sgi_management_iface_vlan, ) service.config['sgi_management_iface_vlan'] = vlan_tag sgi_ip = service.config.get( 'sgi_management_iface_ip_addr', service.mconfig.sgi_management_iface_ip_addr, ) service.config['sgi_management_iface_ip_addr'] = sgi_ip sgi_gateway_ip = service.config.get( 'sgi_management_iface_gw', service.mconfig.sgi_management_iface_gw, ) service.config['sgi_management_iface_gw'] = sgi_gateway_ip # Keep router mode off for smooth upgrade path service.config['dp_router_enabled'] = service.config.get( 'dp_router_enabled', False, ) if 'virtual_mac' not in service.config: if service.config['dp_router_enabled']: up_bridge_name = service.config.get( 'uplink_bridge', UPLINK_OVS_BRIDGE_NAME, ) mac_addr = get_if_hwaddr(up_bridge_name) else: mac_addr = get_if_hwaddr(service.config.get('bridge_name')) service.config['virtual_mac'] = mac_addr # this is not read from yml file. service.config['uplink_port'] = OFPP_LOCAL uplink_port_name = service.config.get('ovs_uplink_port_name', None) if enable_nat is False and uplink_port_name is not None: service.config['uplink_port'] = BridgeTools.get_ofport( uplink_port_name, ) # header enrichment related configuration. service.config['proxy_port_name'] = PROXY_PORT_NAME he_enabled_flag = False if service.mconfig.he_config: he_enabled_flag = service.mconfig.he_config.enable_header_enrichment he_enabled = service.config.get('he_enabled', he_enabled_flag) service.config['he_enabled'] = he_enabled # monitoring related configuration mtr_interface = service.config.get('mtr_interface', None) if mtr_interface: mtr_ip = get_ip_from_if(mtr_interface) service.config['mtr_ip'] = mtr_ip # Load the ryu apps service_manager = ServiceManager(service) service_manager.load() def callback(returncode): if returncode != 0: logging.error( "Failed to set MASQUERADE: %d", returncode, ) # TODO fix this hack for XWF if enable_nat is True or service.config.get('setup_type') == 'XWF': call_process( 'iptables -t nat -A POSTROUTING -o %s -j MASQUERADE' % service.config['nat_iface'], callback, service.loop, ) service.loop.create_task( monitor_ifaces( service.config['monitored_ifaces'], ), ) manager = AppManager.get_instance() # Add pipelined rpc servicer pipelined_srv = PipelinedRpcServicer( service.loop, manager.applications.get('GYController', None), manager.applications.get('EnforcementController', None), manager.applications.get('EnforcementStatsController', None), manager.applications.get('DPIController', None), manager.applications.get('UEMacAddressController', None), manager.applications.get('CheckQuotaController', None), manager.applications.get('IPFIXController', None), manager.applications.get('VlanLearnController', None), manager.applications.get('TunnelLearnController', None), manager.applications.get('Classifier', None), manager.applications.get('InOutController', None), manager.applications.get('NGServiceController', None), service.config, service_manager, ) pipelined_srv.add_to_server(service.rpc_server) if service.config['setup_type'] == 'CWF': bridge_ip = service.config['bridge_ip_address'] has_quota_port = service.config['has_quota_port'] no_quota_port = service.config['no_quota_port'] def on_exit_server_thread(): service.StopService(None, None) # For CWF start quota check servers start_check_quota_server( run_flask, bridge_ip, has_quota_port, True, on_exit_server_thread, ) start_check_quota_server( run_flask, bridge_ip, no_quota_port, False, on_exit_server_thread, ) if service.config['setup_type'] == 'LTE': polling_interval = service.config.get( 'ovs_gtp_stats_polling_interval', MIN_OVSDB_DUMP_POLLING_INTERVAL, ) collector = GTPStatsCollector( polling_interval, service.loop, ) collector.start() # Run the service loop service.run() # Cleanup the service service.close()
def main(): """ Loads the Ryu apps we want to run from the config file. This should exit on keyboard interrupt. """ # Run asyncio loop in a greenthread so we can evaluate other eventlets # TODO: Remove once Ryu migrates to asyncio asyncio.set_event_loop_policy(aioeventlet.EventLoopPolicy()) service = MagmaService('pipelined', mconfigs_pb2.PipelineD()) # Optionally pipe errors to Sentry sentry_init(service_name=service.name, sentry_mconfig=service.shared_mconfig.sentry_config) service_config = service.config if environment.is_dev_mode(): of_rest_server.configure(service_config) # Set Ryu config params cfg.CONF.ofp_listen_host = "127.0.0.1" # override mconfig using local config. # TODO: move config compilation to separate module. enable_nat = service.config.get('enable_nat', service.mconfig.nat_enabled) service.config['enable_nat'] = enable_nat logging.info("Nat: %s", enable_nat) enable5g_features = service.config.get( 'enable5g_features', service.mconfig.enable5g_features, ) service.config['enable5g_features'] = enable5g_features logging.info("enable5g_features: %s", enable5g_features) vlan_tag = service.config.get( 'sgi_management_iface_vlan', service.mconfig.sgi_management_iface_vlan, ) service.config['sgi_management_iface_vlan'] = vlan_tag sgi_ip = service.config.get( 'sgi_management_iface_ip_addr', service.mconfig.sgi_management_iface_ip_addr, ) service.config['sgi_management_iface_ip_addr'] = sgi_ip sgi_gateway_ip = service.config.get( 'sgi_management_iface_gw', service.mconfig.sgi_management_iface_gw, ) service.config['sgi_management_iface_gw'] = sgi_gateway_ip # SGi IPv6 address conf sgi_ipv6 = service.config.get( 'sgi_management_iface_ipv6_addr', service.mconfig.sgi_management_iface_ipv6_addr, ) service.config['sgi_management_iface_ipv6_addr'] = sgi_ipv6 sgi_gateway_ipv6 = service.config.get( 'sgi_management_iface_ipv6_gw', service.mconfig.sgi_management_iface_ipv6_gw, ) service.config['sgi_management_iface_ipv6_gw'] = sgi_gateway_ipv6 # Keep router mode off for smooth upgrade path service.config['dp_router_enabled'] = service.config.get( 'dp_router_enabled', False, ) if 'virtual_mac' not in service.config: if service.config['dp_router_enabled']: up_iface_name = service.config.get('nat_iface', None) mac_addr = get_if_hwaddr(up_iface_name) else: mac_addr = get_if_hwaddr(service.config.get('bridge_name')) service.config['virtual_mac'] = mac_addr # this is not read from yml file. service.config['uplink_port'] = OFPP_LOCAL uplink_port_name = service.config.get('ovs_uplink_port_name', None) if enable_nat is False and uplink_port_name is not None: service.config['uplink_port'] = BridgeTools.get_ofport( uplink_port_name, ) # header enrichment related configuration. service.config['proxy_port_name'] = PROXY_PORT_NAME he_enabled_flag = False if service.mconfig.he_config: he_enabled_flag = service.mconfig.he_config.enable_header_enrichment if he_enabled_flag: bridge = service.config.get('bridge_name') BridgeTools.add_ovs_port(bridge, PROXY_PORT_NAME, PROXY_OF_PORT) he_enabled = service.config.get('he_enabled', he_enabled_flag) service.config['he_enabled'] = he_enabled # tune datapath according to config configure_tso(service.config) setup_sgi_tunnel(service.config, service.loop) tune_datapath(service.config) setup_masquerade_rule(service.config, service.loop) # monitoring related configuration mtr_interface = service.config.get('mtr_interface', None) if mtr_interface: try: service.config['mtr_ip'] = get_ip_from_if(mtr_interface) except ValueError: logging.warning("Unable to set up mtr interface", exc_info=True) # Load the ryu apps service_manager = ServiceManager(service) service_manager.load() service.loop.create_task( monitor_ifaces( service.config['monitored_ifaces'], ), ) manager = AppManager.get_instance() # Add pipelined rpc servicer pipelined_srv = PipelinedRpcServicer( service.loop, manager.applications.get('GYController', None), manager.applications.get('EnforcementController', None), manager.applications.get('EnforcementStatsController', None), manager.applications.get('DPIController', None), manager.applications.get('UEMacAddressController', None), manager.applications.get('CheckQuotaController', None), manager.applications.get('IPFIXController', None), manager.applications.get('VlanLearnController', None), manager.applications.get('TunnelLearnController', None), manager.applications.get('Classifier', None), manager.applications.get('InOutController', None), manager.applications.get('NGServiceController', None), service.config, service_manager, ) pipelined_srv.add_to_server(service.rpc_server) if service.config['setup_type'] == 'CWF': bridge_ip = service.config['bridge_ip_address'] has_quota_port = service.config['has_quota_port'] no_quota_port = service.config['no_quota_port'] def on_exit_server_thread(): service.StopService(None, None) # For CWF start quota check servers start_check_quota_server( run_flask, bridge_ip, has_quota_port, True, on_exit_server_thread, ) start_check_quota_server( run_flask, bridge_ip, no_quota_port, False, on_exit_server_thread, ) if service.config['setup_type'] == 'LTE': polling_interval = service.config.get( 'ovs_gtp_stats_polling_interval', MIN_OVSDB_DUMP_POLLING_INTERVAL, ) collector = GTPStatsCollector( polling_interval, service.loop, ) collector.start() # Run the service loop service.run() # Cleanup the service service.close()