Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
    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,
    )
Beispiel #5
0
    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
Beispiel #6
0
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", "")
Beispiel #7
0
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', '')
Beispiel #8
0
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
Beispiel #9
0
 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']
Beispiel #10
0
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()
Beispiel #11
0
    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)
Beispiel #12
0
    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))
Beispiel #14
0
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)
Beispiel #15
0
    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, ),
        )
Beispiel #16
0
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
Beispiel #17
0
    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
Beispiel #18
0
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()
Beispiel #19
0
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()