Skip to content

Loading builds...

Changes

#767 (Mar 27, 2026, 12:46:08 AM)

pfcp_peer: implement periodic PFCP heartbeat

Add a heartbeat_interval parameter to the pfcp_peer config section.
When non-zero, pfcp_peer sends a periodic Heartbeat Request to the UPF
at the configured interval using a named gen_statem timeout (hb_timer).
The timer is started on entry to the connected state and cancelled on
re-entry to the connecting state.  Default is 10000 ms (10 seconds).

Change-Id: I306324f8eca325202a3fa23125854db9d5eaab38
laforge at

#766 (Mar 26, 2026, 11:51:10 AM)

s1ap_proxy: fix build_erab_setup_response_failure() to report all E-RABs

The previous implementation only included the first E-RAB from the
registry in the failure response (a FIXME was left in place).

Fix it to extract all E-RAB IDs from the original E-RAB SETUP REQUEST
and include each of them in the failure list, as required by 3GPP.

Change-Id: I7933fceb0edcdfdc95ace35416297b11c83f0bc9
Related: osmo-ttcn3-hacks.git I8a5dc338d28013dc85e1ce4b3bdac92cb3b35304
Vadim Yanitskiy at

#765 (Mar 26, 2026, 10:11:09 AM)

pfcp_peer: tune Heartbeat Request/Response logging

Reduce verbosity of the Tx/Rx Heartbeat Req/Resp log messages from
LOG_INFO to LOG_DEBUG in preparation for periodic heartbeat support.
Without this change, periodic heartbeats would flood the logging.

Change-Id: I6435cdf64fd86fa5358d57ea4d56dcad8eb9e69e
Vadim Yanitskiy at

#763 (Mar 25, 2026, 2:16:07 PM)

[REST] PfcpAssocState: field 'lrts' is required

The local RTS is always known and thus always gets included regardless
of the PFCP association state.  Only the remote RTS is optional.

Change-Id: Ic766ebc56ce1810fc27cb49ddcac50bc94e539d9
Related: osmo-ttcn3-hacks.git I332e95a32935e0c8da99e600e8d30af14bd36b16
Vadim Yanitskiy at
gtpu_kpi: use ?ENV_DEFAULT_GTPU_KPI_{TABLE_NAME,INTERVAL}

Change-Id: Ia8194966b20da1adc26c02f416b8ec0508191d98
Vadim Yanitskiy at
config/sys.config: group pfcp_peer params into a map

Following the same pattern as sctp_{client,server}, group the flat
pfcp_loc_addr/pfcp_rem_addr environment variables into a pfcp_peer
map.  The old flat keys are still supported for backwards compat.

Changes:
* osmo_s1gw_sup: add pfcp_cfg(), merging legacy flat keys with the new
  pfcp_peer map (new takes priority); store the resolved config back via
  set_env(pfcp_peer, ...) so all consumers see a single canonical map
* pfcp_peer: change start_link/2 to start_link/1 taking a cfg() map;
  simplify init() using sctp_common:parse_addr/1; add cfg() type
* rest_server: read pfcp laddr/raddr from the pfcp_peer map

Change-Id: Iba954746fe20e6b9eeaec3196e1f83e3fc3e7fc2
Vadim Yanitskiy at
pfcp_peer: make assoc_setup and heartbeat_req timeouts configurable

Add assoc_setup_timeout and heartbeat_req_timeout as optional fields
in the pfcp_peer config map, with 2000 ms defaults.  Store the full
cfg() map in #peer_state{} and read values from it with maps:get/3
at the point of use.

Change-Id: I58a472a3bbbbad029a2f0246b084428ab3b1905c
Vadim Yanitskiy at

#757 (Mar 20, 2026, 9:31:08 PM)

contrib/jenkins_manuals: fix doc/manuals paths

Change-Id: Ibfccefec7e44a4803d4ff8ad061db395fc498b89
Oliver Smith at
[REST] Add MME source address/port to EnbItem

The enb_proxy now captures the local address and port of the S1GW-MME
SCTP connection (mme_saddr/mme_sport) at comm_up and includes them in
conn_info().  Expose this info through the REST API (EnbItem schema),
show it as a new column/row in the CLI (enb_list/enb_info).

Change-Id: I15bbddf96ac7d5b6f9962a8d745db58fdec334e7
Related: SYS#7066
Vadim Yanitskiy at
[REST] Add PLMN/eNB IDs to EnbItem

Change-Id: I79690223a34afea5e6661125ac04f98462dadb03
Related: SYS#7066
Vadim Yanitskiy at
doc/manuals: cli: shorten enb_list example table

The full enb_list table with all address columns is too wide to fit
on a page and does not render well in PDF.  Collapse the address
columns with '...'; add a note that they are omitted for readability.

Change-Id: I4e25233a3e77358060f1098e97907c93deab334b
Related: OS#6671
Vadim Yanitskiy at
enb_{proxy,registry}: signal MME conn info on SCTP comm_up

Previously, mme_aid/mme_saddr/mme_sport were only signalled to the
enb_registry once the S1 Setup procedure completed.  This meant the
REST API could not show MME connection details for eNBs stuck in
wait_s1setup_rsp state (e.g. due to a slow or retrying MME).

Add notify_mme_comm_up/2, called at SCTP comm_up, which stores the full
conn_info (including mme_aid, mme_saddr, mme_sport) in the registry as
soon as the SCTP connection is established.

notify_mme_connected/2 is simplified to notify_mme_connected/1: it now
only flips the state to 'connected', since conn_info is already stored.

Change-Id: Iea9ba4fdf961e6cd262edc154884a2eee3d95355
Related: SYS#7066
Vadim Yanitskiy at
enb_proxy: split conn_info() into mme_conn_info() and proxy_info()

The old conn_info() conflated two distinct concerns: the MME SCTP
connection info stored in enb_registry (aid, saddr, sport) and the
broader operational state used for introspection (handler pid, enb
connection info, etc.).  Mixing them forced enb_registry to hold a
handler pid it has no business knowing about, and required rest_server
to extract that pid just to reach s1ap_proxy for E-RAB listing.

Split into two distinct types:

* mme_conn_info() - pure MME SCTP connection info (aid, saddr, sport),
  stored in the enb_registry and signalled via notify_mme_comm_up/2.
  The `mme_` prefix is dropped from field names as the type name
  provides the context.

* proxy_info() - richer operational snapshot (handler, enb_handle,
  enb_conn_info, mme_conn_info, genb_id_str, mme_info), returned by
  fetch_info/1 for introspection/debugging purposes.

Additionally:

* Add fetch_erab_list/1 to enb_proxy, delegating internally to
  s1ap_proxy:fetch_erab_list/1 via the cached handler pid.  This
  allows the rest_server to obtain a list of E-RAB without having
  to obtain pid of the s1ap_proxy and interact with it.

* Remove separate enb_aid/mme_aid/mme_saddr/mme_sport state fields;
  enb_aid is now read directly from enb_conn_info, and the MME fields
  are grouped in mme_conn_info.

Change-Id: Ia428ceb4762f972211e9b790688dc89fb5b8a274
Related: SYS#7066
Vadim Yanitskiy at
enb_proxy: add missing mme_info() to proxy_info()

As a bonus, `tried_mmes` now only serves its actual purpose - tracking
which MMEs have already been tried for selection filtering - rather
than being abused as a way to retrieve the current MME name.

Change-Id: Ibbb293d9e68b7c3a8c3ca7ee73132dbda3f2bf97
Related: SYS#7066
Vadim Yanitskiy at
s1ap_proxy: add public erab_list() type

Change-Id: I21a674537d1d9f16fdb319aaf2d758ba0906b407
Vadim Yanitskiy at
rest_server: fix TOC/TOU race when listing/fetching E-RABs

The list of E-RAB FSM pids is a snapshot taken at one point in time.
By the time we interrogate each erab_fsm process individually, any of
them may have already terminated (e.g. bearer released mid-request).
The current code fails to generate a response if this happens.

* fetch_erab_info/1: add a pid() clause that wraps erab_list_item/1
  in a try/catch, returning 'error' if the process is gone.

* fetch_erab_info/1: catch both exit forms
** `{noproc, _}` raised by gen_statem:call/2 on a monitored pid, and
** the bare noproc atom for other code paths.

* fetch_erab_list/1: switch from lists:map to lists:filtermap and
  call fetch_erab_info/1 per E-RAB, silently dropping any that died
  between the snapshot and the per-process interrogation.

Change-Id: I160b413aa535f2379ad4e40a3ae8f37c5bce2067
Related: SYS#7066
Vadim Yanitskiy at
rest_server: log received requests (as debug)

Change-Id: I25da9662fb98a0eafcedfde21b12a937225f5fb9
Related: SYS#7066
Vadim Yanitskiy at

#755 (Mar 20, 2026, 11:37:07 AM)

contrib/jenkins_manuals: fix doc/manuals paths

Change-Id: Ibfccefec7e44a4803d4ff8ad061db395fc498b89
Oliver Smith at

#754 (Mar 20, 2026, 11:34:41 AM)

contrib/jenkins_manuals: remove old symlinks

In master-builds, the job runs without wiping the workspace. Remove
previous build and common symlinks, so the manuals job doesn't fail
with:

  + make -C doc/manuals
  make: Entering directory '/build/doc/manuals'
  ln -s /opt/osmo-gsm-manuals/build build
  ln: failed to create symbolic link 'build': File exists

Change-Id: I88add52dc5a4671cf4dcfd498c3103023a35b7ba
Oliver Smith at

#750 (Mar 19, 2026, 6:36:09 PM)

doc/manuals: merge doc/osmo-s1gw-cli.md

Change-Id: Ic2556f6add9c6a24f6da03f4388d7f86dde0c5dc
Related: OS#6671, SYS#7066
Vadim Yanitskiy at
doc/manuals: update MmeItem related info

The osmo-s1gw-cli documentation was not properly updated in 63ce2c9:

* default local/bind address for an MME is "any", not "::"
* allowed TACs (--tac) was missing in help and examples

Change-Id: I0b8115fe6342a80bf1eb99bd6ad210492a013947
Fixes: 63ce2c9 ("[REST] Add MmeList, MmeAdd, MmeInfo, MmeDelete")
Related: OS#6671, SYS#7066, SYS#7052
Vadim Yanitskiy at
contrib: add jenkins_manuals.sh

Change-Id: I54f0774575534519a2c40e0588f136c8a5e706f8
Related: osmo-ci.git Id62d806a648c8f3480cb4f162adf65f77c552848
Related: OS#6671
Vadim Yanitskiy at
rebar.lock: bump exometer_report_statsd version

The new version is using ETS instead of dict for counter lookups.
This significantly reduces performance impact when multiple eNBs
are registered, since the ETS provides O(1) average-case hash
lookups and in-place mutation.

Change-Id: I931321a831215012aa8186d851d9a8d38908a4bf
Vadim Yanitskiy at
config/sys.config: increase StatsD reporter interval to 10s

When running ttcn3-s1gw-test locally, I noticed OsmoS1GW consuming
30-40% of a CPU core while idle (not serving any eNBs).  Profiling
with etop pointed to `exometer_report_statsd` as the culprit: with
~1720 metrics registered, it was sending ~1720 datagrams per second.

A 1-second reporting interval causes noticeable CPU overhead as the
number of active metrics grows.  With per-eNB and per-MME counters,
the metric set scales with the number of connected eNBs/MMEs.

Increase the default StatsD reporting interval from 1s to 10s to
reduce that overhead.  Update the documentation accordingly.

Change-Id: Icd5e1a43d1df4a4909fe742aec67cc51a01bb857
Vadim Yanitskiy at
pfcp_peer: define ?PFCP_ASSOC_SETUP_TIMEOUT

Change-Id: I0b7299d9f3eaa8c0a3c7e4a4d6331d1ec5a1c779
Vadim Yanitskiy at
enb_proxy: signal mme_info() to the enb_registry

When an MME is selected from the pool, pass the mme_registry:mme_info()
to the enb_registry via notify_mme_connecting/2 (replacing /1).  This
makes all MME configuration details (name, address, port, TAC list)
available to consumers such as the REST server, without having to
look them up separately from the mme_registry.

Change-Id: I22e705b8196c9dcf436ed3c4d91c5c5a912e7282
Related: SYS#7052
Vadim Yanitskiy at
enb_proxy: obtain sctp_client sockopts from the env directly

Instead of passing the MmeConnCfg (sctp_client:cfg()) all the way
from osmo_s1gw_sup through sctp_server (as priv) into enb_proxy
(as state), read the sctp_client configuration in-place via
osmo_s1gw:get_env/2 when it is actually needed (connecting/enter).

This works because osmo_s1gw_sup already normalizes and writes back
the complete sctp_client config to the application env (set_env/2)
before starting the supervision tree.

As a result, mme_conn_cfg is removed from enb_proxy's state record,
start_link/2 no longer uses its Priv argument, and server_cfg/1 is
simplified to server_cfg/0.

Change-Id: Ic77d3eb3351c8981c87fa4b6febcdeb814b9187b
Vadim Yanitskiy at
[REST] Add GET /config endpoint (ConfigRead)

This endpoint returns the effective runtime configuration that
OsmoS1GW is currently using, with all defaults applied.  This
reflects the values read via `osmo_s1gw:get_env/2` at startup.

Change-Id: Ic6c9562a541e4a0728257538887537aac6b99b97
Related: SYS#7066
Vadim Yanitskiy at
[REST] Implement eNB/MME selection by addr-port

Add support for selecting an MME or eNB by remote address and port
in the REST API and CLI.  The selector format is `addr:IP:PORT` for
MMEs and `enb-conn:IP:PORT` for eNBs, where IP can be an IPv4 or
IPv6 address.  The colon is used as the address/port separator.

Change-Id: If02c8de1e1b7214bba868eee35233a79d0704dc5
Related: SYS#7066
Vadim Yanitskiy at
[REST] Implement PfcpAssoc{Setup,Release}

Change-Id: I2e24544563e4c4d23bb3d8a4a7b5434191b482d8
Related: SYS#7066
Vadim Yanitskiy at
[REST] EnbItem: expose name of the selected MME

For each eNB connection, include the name of the MME that was selected
from the pool.  Update the OpenAPI spec, CLI (enb_list/enb_info tables),
and user manual accordingly.

Change-Id: I4839275efa5d3545e84d684ad1b8b989214ef76a
Related: SYS#7066, SYS#7052
Vadim Yanitskiy at