[[configuration]]
== Configuration

OsmoS1GW is configured through an Erlang/OTP system configuration file.
By default this file is `config/sys.config` in the source tree, or
`/etc/osmocom/osmo-s1gw.config` after installation.  A different path
can be supplied at start time via the `-c` option of the `osmo-s1gw`
bootstrap script (see <<running_bootstrap_script>>) or via the `CONFIG`
variable when using the project Makefile (see <<running_building_make_targets>>).

The file uses Erlang term syntax.  The top level is a list of
`{ApplicationName, [{Key, Value}, ...]}` tuples.  OsmoS1GW-specific
parameters live under the `osmo_s1gw` application key.  Kernel
parameters (logging) live under the standard `kernel` key, and metrics
reporting parameters under the `exometer_core` key.

[[config_sctp_server]]
=== `sctp_server` — eNB-Facing SCTP Listener

This section controls the SCTP socket on which OsmoS1GW listens for
incoming connections from eNodeBs.

----
{sctp_server, #{
    laddr => "127.0.1.1",  %% local bind address
    lport => 36412,        %% local bind port (S1AP standard port)
    sockopts => #{ }       %% optional socket options (see below)
}}
----

`laddr`::
  IP address to bind to.  Accepts a string in dotted-decimal (IPv4) or
  colon-separated (IPv6) notation, or the atom `any` to bind to all
  interfaces.  Default: `"127.0.1.1"`.

`lport`::
  TCP/SCTP port to listen on.  Default: `36412` (the IANA-assigned S1AP
  port).

`sockopts`::
  An optional map of additional SCTP socket options:
+
[options="header",cols="20,60,20"]
|===
| Option | Description | Default
| `recbuf` | Receive buffer size in bytes | `65536`
| `sndbuf` | Send buffer size in bytes | `65536`
| `nodelay` | Disable Nagle algorithm (`true` to disable) | `true`
|===

[[config_mme_pool]]
=== `mme_pool` — MME Pool Configuration

The `mme_pool` key defines the list of MMEs that OsmoS1GW may connect to
on behalf of connecting eNBs.  This is the recommended way to configure
MME connectivity; it supports multiple MMEs and TAC-based selection.

----
{mme_pool, [
    #{
        name => "mme0",          %% unique name (required)
        raddr => "192.168.2.10", %% MME IP address (required)
        rport => 36412,          %% MME SCTP port (default: 36412)
        laddr => any,            %% local bind address (default: any)
        tac_list => []           %% allowed TACs (default: [] = all)
    },
    #{
        name => "mme1",
        raddr => "192.168.2.20",
        tac_list => [100, 101, 102]
    }
]}
----

Each entry in the list is a map with the following fields:

`name`::
  A unique, human-readable string identifying this MME in log messages,
  the REST API, and per-MME metrics.  Required.

`raddr`::
  The remote IP address of the MME.  Required.

`rport`::
  The remote SCTP port of the MME.  Default: `36412`.

`laddr`::
  The local IP address to bind to when connecting to this MME.  Accepts
  a string or the atom `any`.  Default: `any`.

`tac_list`::
  A list of Tracking Area Codes (TACs) that this MME is willing to serve.
  When an eNB connects and sends its S1 Setup Request, OsmoS1GW filters
  the pool to MMEs whose `tac_list` is a superset of the eNB's
  advertised TACs.  An empty list means the MME accepts all TACs.
  Default: `[]`.

MMEs can also be added and removed at run time via the REST API without
restarting OsmoS1GW (see <<rest_mme>>).

NOTE: The `mme_pool` key is mutually exclusive with the deprecated
`sctp_client` key described in the next section.  If `mme_pool` is
present, keys `laddr`, `raddr`, and `rport` from the `sctp_client`
block are ignored.

[[config_sctp_client]]
=== `sctp_client` — Single MME (Deprecated)

Prior to the introduction of MME pooling, the outbound MME connection was
configured via the `sctp_client` section:

----
{sctp_client, #{
    laddr => "127.0.2.1",  %% local bind address
    raddr => "127.0.2.10", %% MME IP address
    rport => 36412,        %% MME SCTP port
    sockopts => #{ }       %% optional socket options (same as sctp_server)
}}
----

When OsmoS1GW starts and finds no `mme_pool` key in the configuration,
it automatically creates a single `"default"` MME pool entry from the
`sctp_client` parameters and logs a deprecation warning.  This allows
existing single-MME deployments to continue working without changes, but
migration to `mme_pool` is strongly recommended.

NOTE: The socket options (`sockopts`) from the `sctp_client` section are
still used for the outbound SCTP socket regardless of whether `mme_pool`
or `sctp_client` is used for MME addressing.

[[config_pfcp]]
=== PFCP — User Plane Function

These parameters control the PFCP session between OsmoS1GW and the UPF.

----
{pfcp_peer, #{
    laddr => "127.0.1.1",  %% local address for PFCP (UDP)
    raddr => "127.0.1.2"   %% remote address of the UPF
    %% assoc_setup_timeout  => 2000,  %% optional, milliseconds
    %% heartbeat_req_timeout => 2000, %% optional, milliseconds
    %% heartbeat_interval => 0        %% optional, milliseconds (0 = disabled)
}},

%% Optional Network Instance IEs:
%% {pfcp_net_inst_core,   "core-side"},
%% {pfcp_net_inst_access, "radio-side"}
----

`laddr`::
  Local IP address on which OsmoS1GW listens for PFCP messages from the
  UPF.  Default: `"127.0.1.1"`.

`raddr`::
  Remote IP address of the UPF.  Default: `"127.0.1.2"`.

`assoc_setup_timeout`::
  How long (in milliseconds) to wait for a PFCP Association Setup Response
  before retrying.  Default: `2000`.

`heartbeat_req_timeout`::
  How long (in milliseconds) to wait for a PFCP Heartbeat Response before
  declaring the heartbeat timed out.  Default: `2000`.

`heartbeat_interval`::
  Interval (in milliseconds) between periodic PFCP Heartbeat Requests sent
  by OsmoS1GW while associated with the UPF.  Set to `0` to disable periodic
  heartbeats entirely.  Default: `10000`.

`heartbeat_fail_threshold`::
  Number of consecutive unanswered Heartbeat Requests after which OsmoS1GW
  considers the UPF unreachable and resets the PFCP association (transitions
  back to the connecting state).  Applies to both periodic heartbeats and
  those triggered via the REST API.  Default: `3`.

NOTE: The legacy flat keys `pfcp_loc_addr` and `pfcp_rem_addr` are still
accepted for backwards compatibility.  The `pfcp_peer` map takes priority
if both are present.

`pfcp_net_inst_core`::
  Value for the PFCP Network Instance IE on the core-network side of each
  GTP-U session.  Omit if the UPF does not require Network Instance IEs.

`pfcp_net_inst_access`::
  Value for the PFCP Network Instance IE on the radio-access side of each
  GTP-U session.  Omit if the UPF does not require Network Instance IEs.

[[config_gtpu_kpi]]
=== GTP-U KPI Reporting (Optional)

OsmoS1GW can optionally poll nftables counters to derive per-eNB GTP-U
traffic statistics and report them as exometer metrics (see <<gtpu_kpi>>).
This feature requires a matching nftables ruleset.

----
%% {gtpu_kpi_enable,     true},
%% {gtpu_kpi_table_name, "osmo-s1gw"},
%% {gtpu_kpi_ul_addr,    s1ap},
%% {gtpu_kpi_dl_addr,    s1ap},
%% {gtpu_kpi_interval,   3000}
----

`gtpu_kpi_enable`::
  Set to `true` to enable the GTP-U KPI module.  Default: `false`.

`gtpu_kpi_table_name`::
  The nftables table name to read counters from.
  Default: `"osmo-s1gw"`.

`gtpu_kpi_ul_addr`::
  Source of the uplink GTP-U address used to match nftables counters.
  `s1ap` means learn the address from S1AP signalling; `sctp` means use
  the eNB's SCTP source address.  Default: `s1ap`.

`gtpu_kpi_dl_addr`::
  Source of the downlink GTP-U address.  Same options as `gtpu_kpi_ul_addr`.
  Default: `s1ap`.

`gtpu_kpi_interval`::
  How often (in milliseconds) to poll the nftables counters.
  Default: `3000`.

[[config_rest]]
=== REST Interface

----
%% {rest_srv_port,       8080},
%% {rest_srv_swagger_ui, true}
----

`rest_srv_port`::
  TCP port on which the HTTP REST server listens.  Default: `8080`.

`rest_srv_swagger_ui`::
  Whether to serve the Swagger UI at `http://host:rest_srv_port/swagger`.
  Default: `true`.

For the full REST API reference see <<rest>>.  For the interactive CLI
tool that wraps the REST API see <<cli>>.

[[config_kernel]]
=== `kernel` — Logging

OsmoS1GW uses the standard Erlang/OTP `logger` framework.  The `kernel`
application section controls log levels and handlers.  See
<<running_logging>> for a description of the log handlers configured by
default.

----
{kernel, [
    {logger_level, debug},
    {logger, [
        {handler, gsmtap, logger_gsmtap_h,
         #{level => debug,
           config => #{rem_addr => "127.0.0.1",
                       app_name => "OsmoS1GW"}}},
        {handler, default, logger_std_h,
         #{level => info,
           formatter => {logger_color_formatter, #{...}}}}
    ]}
]}
----

`logger_level`::
  The global minimum log level.  Log records below this level are
  discarded before reaching any handler.  Common values: `debug`,
  `info`, `notice`, `warning`, `error`.

For each handler in the `logger` list:

`level`::
  Handler-specific minimum log level.  Can be set independently per
  handler to, for example, send only `warning` and above to the console
  while sending all `debug` output over GSMTAP.

`gsmtap` handler (`logger_gsmtap_h`)::
  Sends log messages as GSMTAP frames over UDP.
+
`rem_addr`::: Destination IP address.  Default: `"127.0.0.1"`.
`app_name`::: Application name tag embedded in each GSMTAP frame.

`default` handler (`logger_std_h`)::
  Writes log lines to standard output.  When OsmoS1GW runs under systemd
  this output is captured by the journal.

[[config_exometer]]
=== `exometer_core` — Metrics and StatsD Reporting

See <<metrics>> for an introduction to OsmoS1GW metrics and the full
list of available counters and gauges.  The `exometer_core` section
configures reporters — processes that periodically push metric values to
an external destination.

The default configuration reports all counters and gauges to a StatsD
server:

----
{exometer_core, [
    {report, [
        {reporters, [
            {exometer_report_statsd, [
                {hostname, "127.0.4.10"},
                {port, 8125},
                {prefix, "s1gw"},
                {type_map, []}
            ]}
        ]},
        {subscribers, [
            {select, {[{ {['_'|'_'], counter, '_'}, [], ['$_']}],
                       exometer_report_statsd, value, 10_000, true,
                       [{report_type, counter}]}},
            {select, {[{ {['_'|'_'], gauge, '_'}, [], ['$_']}],
                       exometer_report_statsd, value, 10_000, true,
                       [{report_type, gauge}]}}
        ]}
    ]}
]}
----

`hostname`::
  IP address or hostname of the StatsD server.

`port`::
  UDP port of the StatsD server.  Default: `8125`.

`prefix`::
  String prepended to all metric names as reported to StatsD.
  Default: `"s1gw"`.

The `subscribers` list uses exometer's `select` mechanism to
automatically subscribe all counters and gauges to the StatsD reporter
with a reporting interval of 10 000 ms.  To disable StatsD reporting,
comment out or remove the `exometer_report_statsd` reporter entry.

// vim:set ts=4 sw=4 et:
