fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41098?usp=email )
Change subject: [REST] Integrate Erlang REST Framework
......................................................................
[REST] Integrate Erlang REST Framework
Change-Id: I20ad3208b8cd4f5483992e3bf22af30ff62b0311
Related: SYS#7066
---
M config/sys.config
M rebar.config
M rebar.lock
M src/osmo_s1gw.app.src
M src/osmo_s1gw.erl
M src/osmo_s1gw_sup.erl
A src/rest_server.erl
7 files changed, 106 insertions(+), 4 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/98/41098/1
diff --git a/config/sys.config b/config/sys.config
index 4e5a80c..5184ebb 100644
--- a/config/sys.config
+++ b/config/sys.config
@@ -25,7 +25,9 @@
%% {gtpu_kpi_table_name, "osmo-s1gw"}, %% the NFT table name to be used by this process
%% {gtpu_kpi_ul_addr, s1ap}, %% GTP-U UL address: s1ap | sctp (default: learn from S1AP)
%% {gtpu_kpi_dl_addr, s1ap}, %% GTP-U DL address: s1ap | sctp (default: learn from S1AP)
-%% {gtpu_kpi_interval, 3000} %% counter reporting interval (ms)
+%% {gtpu_kpi_interval, 3000}, %% counter reporting interval (ms)
+%% {rest_srv_port, 8080}, %% REST server port (default: 8080)
+%% {rest_srv_swagger_ui, true} %% REST Swagger UI (default: true)
]},
%% ================================================================================
%% kernel config
diff --git a/rebar.config b/rebar.config
index de8b023..d729401 100644
--- a/rebar.config
+++ b/rebar.config
@@ -16,7 +16,9 @@
{exometer_core,
{git, "https://github.com/Feuerlabs/exometer_core.git", {branch, "master"}}},
{exometer_report_statsd,
- {git, "https://github.com/osmocom/exometer_report_statsd.git", {branch, "counters"}}}
+ {git, "https://github.com/osmocom/exometer_report_statsd.git", {branch, "counters"}}},
+ {erf,
+ {git, "https://github.com/nomasystems/erf.git", {tag, "0.1.2"}}}
]}.
%% test deps
diff --git a/rebar.lock b/rebar.lock
index 647bca0..1efe90b 100644
--- a/rebar.lock
+++ b/rebar.lock
@@ -1,9 +1,17 @@
{"1.2.0",
[{<<"cut">>,{pkg,<<"cut">>,<<"1.0.3">>},1},
+ {<<"elli">>,
+ {git,"https://github.com/elli-lib/elli.git",
+ {ref,"3ec352293ef493c142767127f4113c85541c32cc"}},
+ 1},
{<<"enftables">>,
{git,"https://gitea.osmocom.org/erlang/enftables.git",
{ref,"8b9b4acd624b9d0d3a58d725f11afa96d31fe5d7"}},
0},
+ {<<"erf">>,
+ {git,"https://github.com/nomasystems/erf.git",
+ {ref,"0dac504f9988d3b96154c1e80b8af3defb772b58"}},
+ 0},
{<<"exometer_core">>,
{git,"https://github.com/Feuerlabs/exometer_core.git",
{ref,"fc744c45bbe5de2ab0ee550e2667f93f7abbb618"}},
@@ -25,6 +33,18 @@
{git,"https://gitea.osmocom.org/erlang/logger_gsmtap.git",
{ref,"5194badde912a8179f2a818155ee2b01f9e6377e"}},
0},
+ {<<"ncalendar">>,
+ {git,"https://github.com/nomasystems/ncalendar.git",
+ {ref,"aa5615f6723585e45e82fa5524cb976cdfe3d7f7"}},
+ 2},
+ {<<"ndto">>,
+ {git,"https://github.com/nomasystems/ndto.git",
+ {ref,"295281b72ea4ac85e7c4d5ca42337c68b1aac137"}},
+ 1},
+ {<<"njson">>,
+ {git,"https://github.com/nomasystems/njson.git",
+ {ref,"94c586b92a7e24c403089cdbe2994b7e7c87b9cc"}},
+ 1},
{<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.4.1">>},1},
{<<"pfcplib">>,
{git,"https://github.com/travelping/pfcplib.git",
diff --git a/src/osmo_s1gw.app.src b/src/osmo_s1gw.app.src
index 13240dd..2885cc6 100644
--- a/src/osmo_s1gw.app.src
+++ b/src/osmo_s1gw.app.src
@@ -12,7 +12,8 @@
pfcplib,
enftables,
exometer_core,
- exometer_report_statsd
+ exometer_report_statsd,
+ erf
]},
{modules, []},
{mod, {osmo_s1gw_app, []}},
diff --git a/src/osmo_s1gw.erl b/src/osmo_s1gw.erl
index d5f9efd..e90d927 100644
--- a/src/osmo_s1gw.erl
+++ b/src/osmo_s1gw.erl
@@ -35,6 +35,7 @@
-module(osmo_s1gw).
-export([get_env/2,
+ get_priv/1,
main/1]).
-define(ENV_APP_NAME, osmo_s1gw).
@@ -52,6 +53,14 @@
application:get_env(?ENV_APP_NAME, Param, Default).
+-spec get_priv(Name) -> Path
+ when Name :: file:filename_all(),
+ Path :: file:filename_all().
+get_priv(Name) ->
+ PrivDir = code:priv_dir(?ENV_APP_NAME),
+ filename:join(PrivDir, Name).
+
+
main(_Args) ->
application:ensure_all_started(?MODULE),
timer:sleep(infinity).
diff --git a/src/osmo_s1gw_sup.erl b/src/osmo_s1gw_sup.erl
index 934f040..1616fe5 100644
--- a/src/osmo_s1gw_sup.erl
+++ b/src/osmo_s1gw_sup.erl
@@ -53,6 +53,8 @@
-define(ENV_DEFAULT_GTPU_KPI_ENABLE, false).
-define(ENV_DEFAULT_GTPU_KPI_TABLE_NAME, "osmo-s1gw").
-define(ENV_DEFAULT_GTPU_KPI_INTERVAL, 3000).
+-define(ENV_DEFAULT_REST_SRV_PORT, 8080).
+-define(ENV_DEFAULT_REST_SRV_SWAGGER_UI, true).
%% ------------------------------------------------------------------
%% supervisor API
@@ -87,9 +89,14 @@
5000,
worker,
[gtpu_kpi]},
+ RestServer = {rest_server, {erf, start_link, [rest_server_cfg()]},
+ permanent,
+ 5000,
+ worker,
+ [erf]},
s1gw_metrics:init(),
- {ok, {{one_for_one, 5, 10}, [EnbRegistry, SctpServer, PfcpPeer, GtpuKpi]}}.
+ {ok, {{one_for_one, 5, 10}, [EnbRegistry, SctpServer, PfcpPeer, GtpuKpi, RestServer]}}.
%% ------------------------------------------------------------------
@@ -126,4 +133,13 @@
table_name => osmo_s1gw:get_env(gtpu_kpi_table_name, ?ENV_DEFAULT_GTPU_KPI_TABLE_NAME),
interval => osmo_s1gw:get_env(gtpu_kpi_interval, ?ENV_DEFAULT_GTPU_KPI_INTERVAL)}.
+
+-spec rest_server_cfg() -> erf:conf().
+rest_server_cfg() ->
+ #{callback => rest_server,
+ spec_path => list_to_binary(osmo_s1gw:get_priv("openapi.json")),
+ port => osmo_s1gw:get_env(rest_srv_port, ?ENV_DEFAULT_REST_SRV_PORT),
+ swagger_ui => osmo_s1gw:get_env(rest_srv_swagger_ui, ?ENV_DEFAULT_REST_SRV_SWAGGER_UI)}.
+
+
%% vim:set ts=4 sw=4 et:
diff --git a/src/rest_server.erl b/src/rest_server.erl
new file mode 100644
index 0000000..c4e0373
--- /dev/null
+++ b/src/rest_server.erl
@@ -0,0 +1,52 @@
+%% Copyright (C) 2025 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+%% Author: Vadim Yanitskiy <vyanitskiy(a)sysmocom.de>
+%%
+%% All Rights Reserved
+%%
+%% SPDX-License-Identifier: AGPL-3.0-or-later
+%%
+%% This program is free software; you can redistribute it and/or modify
+%% it under the terms of the GNU Affero General Public License as
+%% published by the Free Software Foundation; either version 3 of the
+%% License, or (at your option) any later version.
+%%
+%% This program is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU Affero General Public License
+%% along with this program. If not, see <https://www.gnu.org/licenses/>.
+%%
+%% Additional Permission under GNU AGPL version 3 section 7:
+%%
+%% If you modify this Program, or any covered work, by linking or
+%% combining it with runtime libraries of Erlang/OTP as released by
+%% Ericsson on https://www.erlang.org (or a modified version of these
+%% libraries), containing parts covered by the terms of the Erlang Public
+%% License (https://www.erlang.org/EPLICENSE), the licensors of this
+%% Program grant you additional permission to convey the resulting work
+%% without the need to license the runtime libraries of Erlang/OTP under
+%% the GNU Affero General Public License. Corresponding Source for a
+%% non-source form of such a combination shall include the source code
+%% for the parts of the runtime libraries of Erlang/OTP used as well as
+%% that of the covered work.
+
+-module(rest_server).
+
+-export([]).
+
+-include_lib("kernel/include/logger.hrl").
+
+
+%% ------------------------------------------------------------------
+%% public API
+%% ------------------------------------------------------------------
+
+
+%% ------------------------------------------------------------------
+%% private API
+%% ------------------------------------------------------------------
+
+
+%% vim:set ts=4 sw=4 et:
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41098?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I20ad3208b8cd4f5483992e3bf22af30ff62b0311
Gerrit-Change-Number: 41098
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
Attention is currently required from: fixeria, jolly.
Hello Jenkins Builder, jolly,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41035?usp=email
to look at the new patch set (#2).
The following approvals got outdated and were removed:
Code-Review+1 by jolly, Verified+1 by Jenkins Builder
Change subject: enb_registry: track eNB uptime
......................................................................
enb_registry: track eNB uptime
Now that we have the global eNB registry, it makes more sense to
perform uptime tracking there instead of spawning a separate
enb_uptime process for each eNB connection.
Change-Id: I94fd06e559ae52d4d9c8b22e618e48dff718b53c
Related: SYS#7594, SYS#7066
---
M src/enb_registry.erl
D src/enb_uptime.erl
M src/s1ap_proxy.erl
3 files changed, 59 insertions(+), 109 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/35/41035/2
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41035?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newpatchset
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I94fd06e559ae52d4d9c8b22e618e48dff718b53c
Gerrit-Change-Number: 41035
Gerrit-PatchSet: 2
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: jolly <andreas(a)eversberg.eu>
Gerrit-CC: pespin <pespin(a)sysmocom.de>
Gerrit-Attention: jolly <andreas(a)eversberg.eu>
Gerrit-Attention: fixeria <vyanitskiy(a)sysmocom.de>
fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41097?usp=email )
Change subject: [REST] osmo-s1gw-cli.py skeleton
......................................................................
[REST] osmo-s1gw-cli.py skeleton
This is an interactive shell based on Python's cmd2 library, providing
an alternative to the traditional VTY interface used in many Osmocom
projects. It communicates with the main process via the REST interface.
Currently there's only one command fetching the OpenAPI specification.
More commands will be introduced in follow-up commits.
Change-Id: I05600f2fa6d213b9cee28871761231722ff5b876
Related: SYS#7066
---
M Makefile
A contrib/osmo-s1gw-cli.py
M debian/control
A debian/osmo-s1gw-cli.install
A debian/osmo-s1gw.install
5 files changed, 137 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/97/41097/1
diff --git a/Makefile b/Makefile
index ddc3dd5..76d9f7e 100644
--- a/Makefile
+++ b/Makefile
@@ -51,6 +51,8 @@
cp -r $(REBAR_BASE_DIR)/default/rel/osmo-s1gw $(DESTDIR)$(LIBDIR)/
install -Dm0755 contrib/osmo-s1gw.sh \
$(DESTDIR)$(BINDIR)/osmo-s1gw
+ install -Dm0755 contrib/osmo-s1gw-cli.py \
+ $(DESTDIR)$(BINDIR)/osmo-s1gw-cli
install -Dm0644 config/sys.config \
$(DESTDIR)$(CONFDIR)/osmo-s1gw.config
install -Dm0644 contrib/systemd/osmo-s1gw.service \
diff --git a/contrib/osmo-s1gw-cli.py b/contrib/osmo-s1gw-cli.py
new file mode 100755
index 0000000..7d13b08
--- /dev/null
+++ b/contrib/osmo-s1gw-cli.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2025 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+# Author: Vadim Yanitskiy <vyanitskiy(a)sysmocom.de>
+#
+# All Rights Reserved
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import logging
+import argparse
+import cmd2
+import sys
+
+import tabulate
+import urllib.request
+import http.client
+import json
+
+# local logger for this module
+log = logging.getLogger(__name__)
+
+
+class RestIface:
+ ''' REST interface for OsmoS1GW '''
+
+ HTTPResponse = http.client.HTTPResponse
+ RESTResponse = dict | list[dict]
+
+ def __init__(self, host: str, port: int):
+ self.url = f'http://{host}:{port}'
+
+ def send_req(self, method: str,
+ path: str = '',
+ data: dict = {}) -> HTTPResponse:
+ ''' Send an HTTP request to the given endpoint (path) '''
+ req = urllib.request.Request(f'{self.url}/{path}', method=method)
+ req.add_header("Accept", "application/json")
+ if data:
+ req.add_header("Content-Type", "application/json")
+ req.data = json.dumps(data).encode("utf-8")
+ log.debug(f'HTTP {req.method} {req.full_url}')
+ return urllib.request.urlopen(req)
+
+ def send_get_req(self, path: str, query: dict = {}) -> HTTPResponse:
+ ''' Send an HTTP GET request to the given endpoint (path) '''
+ if query:
+ path += '?' + urllib.parse.urlencode(query)
+ return self.send_req('GET', path)
+
+ def send_post_req(self, path: str, data: dict = {}) -> HTTPResponse:
+ ''' Send an HTTP POST request to the given endpoint (path) '''
+ return self.send_req('POST', path, data)
+
+ def send_delete_req(self, path: str, data: dict = {}) -> HTTPResponse:
+ ''' Send an HTTP DELETE request to the given endpoint (path) '''
+ return self.send_req('DELETE', path, data)
+
+ def fetch_spec(self) -> RESTResponse:
+ with self.send_get_req('swagger/spec.json') as f:
+ return json.load(f)
+
+
+class OsmoS1GWCli(cmd2.Cmd):
+ DESC = 'Interactive CLI for OsmoS1GW'
+
+ def __init__(self, argv):
+ super().__init__(allow_cli_args=False, include_py=True)
+
+ if argv.verbose > 0:
+ logging.root.setLevel(logging.DEBUG)
+ self.debug = True
+
+ self.intro = cmd2.style('Welcome to %s!' % self.DESC, fg=cmd2.Fg.RED)
+ self.default_category = 'Built-in commands'
+ self.prompt = 'OsmoS1GW# '
+
+ self.tablefmt = 'github' # default table format for tabulate
+ self.add_settable(cmd2.Settable('tablefmt', str, 'Table format for tabulate', self,
+ choices=tabulate.tabulate_formats))
+
+ self.iface = RestIface(argv.HOST, argv.port)
+
+ def do_fetch_openapi_spec(self, opts):
+ ''' Fetch the OpenAPI specification (JSON) '''
+ spec = self.iface.fetch_spec()
+ self.poutput(json.dumps(spec, indent=4))
+
+
+ap = argparse.ArgumentParser(prog='osmo-s1gw-cli', description=OsmoS1GWCli.DESC)
+
+ap.add_argument('-v', '--verbose', action='count', default=0,
+ help='print debug logging')
+ap.add_argument('-p', '--port', metavar='PORT', type=int, default=8080,
+ help='OsmoS1GW REST port (default: %(default)s)')
+ap.add_argument('HOST', type=str, nargs='?', default='localhost',
+ help='OsmoS1GW REST host/address (default: %(default)s)')
+
+logging.basicConfig(
+ format='\r[%(levelname)s] %(filename)s:%(lineno)d %(message)s', level=logging.INFO)
+
+if __name__ == '__main__':
+ argv = ap.parse_args()
+ app = OsmoS1GWCli(argv)
+ sys.exit(app.cmdloop())
diff --git a/debian/control b/debian/control
index f7e9258..7d7192f 100644
--- a/debian/control
+++ b/debian/control
@@ -23,3 +23,15 @@
This can be used on the S1 interface between eNB and MME/CN, and
acts as separation between the eNB-facing IP network and the
CN-facing IP network, which may be separate without routing in between.
+
+Package: osmo-s1gw-cli
+Architecture: any
+Section: utils
+Depends: ${misc:Depends},
+ ${python3:Depends},
+ python3-cmd2,
+ python3-tabulate
+Description: Interactive CLI for the Osmocom S1 gateway
+ This is an interactive shell for the Osmocom S1 gateway, providing
+ an alternative to the traditional VTY interface used in many Osmocom
+ projects. It communicates with OsmoS1GW via the REST interface.
diff --git a/debian/osmo-s1gw-cli.install b/debian/osmo-s1gw-cli.install
new file mode 100644
index 0000000..037a640
--- /dev/null
+++ b/debian/osmo-s1gw-cli.install
@@ -0,0 +1 @@
+usr/bin/osmo-s1gw-cli
diff --git a/debian/osmo-s1gw.install b/debian/osmo-s1gw.install
new file mode 100644
index 0000000..b52efe2
--- /dev/null
+++ b/debian/osmo-s1gw.install
@@ -0,0 +1,4 @@
+usr/bin/osmo-s1gw
+usr/lib/osmo-s1gw
+etc/osmocom/osmo-s1gw.config
+lib/systemd/system/osmo-s1gw.service
--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41097?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I05600f2fa6d213b9cee28871761231722ff5b876
Gerrit-Change-Number: 41097
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/41091?usp=email )
Change subject: m3ua: Forward SCON messages in SG role
......................................................................
m3ua: Forward SCON messages in SG role
The rx handler for SG role was missing to call the already existing code
to propagate state of congestion state towards ASP peers.
Spec references to the feature are added in place in the code.
Change-Id: Ic68345688d39f5430c30e156b94b1501d77e388c
---
M src/m3ua.c
M src/xua_snm.c
2 files changed, 25 insertions(+), 4 deletions(-)
Approvals:
pespin: Looks good to me, approved
Jenkins Builder: Verified
diff --git a/src/m3ua.c b/src/m3ua.c
index 4af17a9..8c30775 100644
--- a/src/m3ua.c
+++ b/src/m3ua.c
@@ -1058,15 +1058,32 @@
* xua is owned by parent call m3ua_rx_snm() */
static int m3ua_rx_snm_sg(struct osmo_ss7_asp *asp, struct xua_msg *xua)
{
+ struct osmo_ss7_as *as = NULL;
+ struct xua_msg_part *rctx_ie;
+ int rc = 0;
+
switch (xua->hdr.msg_type) {
- case M3UA_SNM_DAUD: /* Audit: ASP inquires about availability of Point Codes */
+ case M3UA_SNM_SCON:
+ /* RFC4666 1.4.6: "The M3UA layer at an ASP or IPSP MAY indicate local congestion
+ * to an M3UA peer with an SCON message."
+ * RFC4666 3.4.4: The SCON message MAY also be sent from the M3UA layer of an ASP
+ * to an M3UA peer, indicating that the congestion level of the M3UA layer or the
+ * ASP has changed.*/
+ rctx_ie = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX);
+ rc = xua_find_as_for_asp(&as, asp, rctx_ie);
+ if (rc)
+ return rc;
+ xua_snm_rx_scon(asp, as, xua);
+ break;
+ case M3UA_SNM_DAUD:
+ /* Audit: ASP inquires about availability of Point Codes */
xua_snm_rx_daud(asp, xua);
break;
default:
return M3UA_ERR_UNSUPP_MSG_TYPE;
}
- return 0;
+ return rc;
}
/* received SNM message
diff --git a/src/xua_snm.c b/src/xua_snm.c
index eda03c9..344cc63 100644
--- a/src/xua_snm.c
+++ b/src/xua_snm.c
@@ -339,9 +339,13 @@
uint32_t rctx[OSMO_SS7_MAX_RCTX_COUNT];
unsigned int num_rctx;
- /* TODO: How to translate to MTP and towards SCCP (create N-PCSTATE.ind to SCU) */
+ /* TODO: Translate to MTP-STATUS.ind towards SCCP (will create N-PCSTATE.ind to SCU) */
- /* inform remote ASPs via SCON */
+ /* RFC4666 1.4.6: "When an SG receives a congestion message (SCON) from an ASP and the SG
+ * determines that an SPMC is now encountering congestion, it MAY trigger SS7 MTP3 Transfer
+ * Controlled management messages to concerned SS7 destinations according to congestion
+ * procedures of the relevant MTP3 standard."
+ * ie. inform remote ASPs via SCON: */
llist_for_each_entry(asp, &s7i->asp_list, list) {
/* SSNM is only permitted for ASPs in ACTIVE state */
if (!osmo_ss7_asp_active(asp))
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/41091?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: Ic68345688d39f5430c30e156b94b1501d77e388c
Gerrit-Change-Number: 41091
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>