fixeria submitted this change.
[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
---
M contrib/openapi.yaml
M contrib/osmo-s1gw-cli.py
M doc/manuals/chapters/cli.adoc
M doc/manuals/chapters/rest.adoc
M priv/openapi.json
M src/enb_proxy.erl
M src/rest_server.erl
7 files changed, 76 insertions(+), 38 deletions(-)
diff --git a/contrib/openapi.yaml b/contrib/openapi.yaml
index 55448f4..d1aaba9 100644
--- a/contrib/openapi.yaml
+++ b/contrib/openapi.yaml
@@ -420,15 +420,18 @@
enb_saddr:
type: string
description: Source (remote) address of the eNB
- mme_daddr:
- type: string
- description: Destination (remote) address of the MME
enb_sport:
type: integer
description: Source (remote) port of the eNB-S1GW connection
+ mme_saddr:
+ type: string
+ description: Source (local) address of the S1GW-MME connection
mme_sport:
type: integer
description: Source (local) port of the S1GW-MME connection
+ mme_daddr:
+ type: string
+ description: Destination (remote) address of the MME
mme_dport:
type: integer
description: Destination (remote) port of the S1GW-MME connection
diff --git a/contrib/osmo-s1gw-cli.py b/contrib/osmo-s1gw-cli.py
index 3878708..12079be 100755
--- a/contrib/osmo-s1gw-cli.py
+++ b/contrib/osmo-s1gw-cli.py
@@ -395,17 +395,28 @@
self.iface.mme_delete(self.gen_mme_id(opts))
@staticmethod
- def enb_list_item(item: dict) -> dict:
+ def enb_list_item_addr_port(item: dict, enb_mme: str, sd: str) -> str:
+ ''' Generate an 'addr:port (aid)' string for the given EnbItem '''
+ addr = item.get(f'{enb_mme}_{sd}addr')
+ port = item.get(f'{enb_mme}_{sd}port')
+ if (addr is None) or (port is None):
+ return ''
+ aid = item.get(f'{enb_mme}_sctp_aid')
+ if aid is None:
+ return f'{addr}:{port}'
+ return f'{addr}:{port} ({aid})'
+
+ @classmethod
+ def enb_list_item(cls, item: dict) -> dict:
''' Generate a table row for the given eNB '''
- enb_addr = lambda item: '{enb_saddr}:{enb_sport} ({enb_sctp_aid})'.format(**item)
- mme_addr = lambda item: '{mme_daddr}:{mme_dport} ({mme_sctp_aid})'.format(**item)
return {
'eNB handle': item.get('handle'),
'PID': item.get('pid'),
'Global-eNB-ID': item.get('genb_id', '(unknown)'),
'State': item.get('state'),
- 'eNB addr:port (aid)': enb_addr(item) if 'enb_saddr' in item else None,
- 'MME addr:port (aid)': mme_addr(item) if 'mme_daddr' in item else None,
+ 'eNB saddr:sport (aid)': cls.enb_list_item_addr_port(item, 'enb', 's'),
+ 'MME saddr:sport (aid)': cls.enb_list_item_addr_port(item, 'mme', 's'),
+ 'MME daddr:dport (aid)': cls.enb_list_item_addr_port(item, 'mme', 'd'),
'MME name': item.get('mme_name'),
'Uptime (s)': item.get('uptime'),
'# E-RABs': item.get('erab_count'),
diff --git a/doc/manuals/chapters/cli.adoc b/doc/manuals/chapters/cli.adoc
index f24016b..2daf0b4 100644
--- a/doc/manuals/chapters/cli.adoc
+++ b/doc/manuals/chapters/cli.adoc
@@ -285,11 +285,11 @@
----
OsmoS1GW# enb_list
-| handle | PID | Global-eNB-ID | State | eNB addr:port (aid) | MME addr:port (aid) | MME name | Uptime | E-RABs |
-|----------|-----------|---------------|-----------|-------------------------|-------------------------|----------|----------|----------|
-| 0 | <0.699.0> | 001-01-0 | connected | 127.0.1.10:56767 (5706) | 127.0.2.10:36412 (5707) | mme0 | 418 | 0 |
-| 1 | <0.701.0> | 001-01-1 | connected | 127.0.1.10:54140 (5710) | 127.0.2.10:36412 (5711) | mme0 | 33 | 3 |
-| 2 | <0.703.0> | 001-01-2 | connected | 127.0.1.10:34076 (5714) | 127.0.2.10:36412 (5715) | mme0 | 3600 | 20 |
+| handle | PID | Global-eNB-ID | State | eNB saddr:sport (aid) | MME saddr:sport (aid) | MME daddr:dport (aid) | MME name | Uptime | E-RABs |
+|----------|-----------|---------------|-----------|-------------------------|------------------------|-------------------------|----------|----------|----------|
+| 0 | <0.699.0> | 001-01-0 | connected | 127.0.1.10:56767 (5706) | 127.0.2.1:34650 (5707) | 127.0.2.10:36412 (5707) | mme0 | 418 | 0 |
+| 1 | <0.701.0> | 001-01-1 | connected | 127.0.1.10:54140 (5710) | 127.0.2.1:34651 (5711) | 127.0.2.10:36412 (5711) | mme0 | 33 | 3 |
+| 2 | <0.703.0> | 001-01-2 | connected | 127.0.1.10:34076 (5714) | 127.0.2.1:34652 (5715) | 127.0.2.10:36412 (5715) | mme0 | 3600 | 20 |
----
==== `enb_info`
@@ -315,17 +315,18 @@
----
OsmoS1GW# enb_info -H 8
-| Parameter | Value |
-|---------------------|-------------------------|
-| eNB handle | 8 |
-| PID | <0.715.0> |
-| Global-eNB-ID | 001-01-8 |
-| State | connected |
-| eNB addr:port (aid) | 127.0.1.10:57362 (5734) |
-| MME addr:port (aid) | 127.0.2.10:36412 (5745) |
-| MME name | mme0 |
-| Uptime (s) | 521 |
-| # E-RABs | 99 |
+| Parameter | Value |
+|-----------------------|-------------------------|
+| eNB handle | 8 |
+| PID | <0.715.0> |
+| Global-eNB-ID | 001-01-8 |
+| State | connected |
+| eNB saddr:sport (aid) | 127.0.1.10:57362 (5734) |
+| MME saddr:sport (aid) | 127.0.2.1:73421 (5745) |
+| MME daddr:dport (aid) | 127.0.2.10:36412 (5745) |
+| MME name | mme0 |
+| Uptime (s) | 521 |
+| # E-RABs | 99 |
----
==== `enb_delete`
diff --git a/doc/manuals/chapters/rest.adoc b/doc/manuals/chapters/rest.adoc
index 7c1383b..cc74ba1 100644
--- a/doc/manuals/chapters/rest.adoc
+++ b/doc/manuals/chapters/rest.adoc
@@ -259,9 +259,10 @@
"enb_sport": 56767,
"enb_sctp_aid": 5706,
"mme_name": "mme0",
+ "mme_saddr": "192.168.2.1",
+ "mme_sport": 34500,
"mme_daddr": "192.168.2.10",
"mme_dport": 36412,
- "mme_sport": 34500,
"mme_sctp_aid": 5707,
"uptime": 418,
"erab_count": 3
@@ -278,8 +279,8 @@
`enb_saddr` / `enb_sport`:: Source address and port of the eNB's SCTP connection.
`enb_sctp_aid`:: SCTP association ID of the eNB-S1GW connection.
`mme_name`:: Name of the selected MME (from the MME pool).
+`mme_saddr` / `mme_sport`:: Local address and port of the S1GW-MME SCTP connection.
`mme_daddr` / `mme_dport`:: Destination address and port of the MME.
-`mme_sport`:: Local source port of the S1GW-MME SCTP connection.
`mme_sctp_aid`:: SCTP association ID of the S1GW-MME connection.
`uptime`:: Seconds since the eNB connected.
`erab_count`:: Number of currently active E-RABs for this eNB.
diff --git a/priv/openapi.json b/priv/openapi.json
index 59c9676..bcec82b 100644
--- a/priv/openapi.json
+++ b/priv/openapi.json
@@ -622,18 +622,22 @@
"type": "string",
"description": "Source (remote) address of the eNB"
},
- "mme_daddr": {
- "type": "string",
- "description": "Destination (remote) address of the MME"
- },
"enb_sport": {
"type": "integer",
"description": "Source (remote) port of the eNB-S1GW connection"
},
+ "mme_saddr": {
+ "type": "string",
+ "description": "Source (local) address of the S1GW-MME connection"
+ },
"mme_sport": {
"type": "integer",
"description": "Source (local) port of the S1GW-MME connection"
},
+ "mme_daddr": {
+ "type": "string",
+ "description": "Destination (remote) address of the MME"
+ },
"mme_dport": {
"type": "integer",
"description": "Destination (remote) port of the S1GW-MME connection"
diff --git a/src/enb_proxy.erl b/src/enb_proxy.erl
index c76ac42..17296bd 100644
--- a/src/enb_proxy.erl
+++ b/src/enb_proxy.erl
@@ -60,12 +60,15 @@
-type conn_info() :: #{handler := pid(),
enb_aid := gen_sctp:assoc_id(),
- mme_aid => gen_sctp:assoc_id()
- %% TODO: add mme_saddr / mme_sport
+ mme_aid => gen_sctp:assoc_id(),
+ mme_saddr => inet:ip_address(),
+ mme_sport => inet:port_number()
}.
-record(state, {enb_aid :: gen_sctp:assoc_id(),
mme_aid :: undefined | gen_sctp:assoc_id(),
+ mme_saddr :: undefined | inet:ip_address(),
+ mme_sport :: undefined | inet:port_number(),
enb_conn_info :: sctp_server:conn_info(),
s1setup_req :: undefined | binary(),
tried_mmes :: [mme_registry:mme_name()],
@@ -117,6 +120,8 @@
{ok, Pid} = s1ap_proxy:start_link(self()),
{ok, wait_s1setup_req,
#state{enb_aid = maps:get(aid, EnbConnInfo),
+ mme_saddr = undefined,
+ mme_sport = undefined,
enb_conn_info = EnbConnInfo,
enb_handle = EnbHandle,
tried_mmes = [],
@@ -206,6 +211,8 @@
{next_state, ?FUNCTION_NAME, %% loop transition to enable state_timeout
S#state{sock = Sock,
mme_aid = undefined,
+ mme_saddr = undefined,
+ mme_sport = undefined,
tried_mmes = [MmeName | TriedMMEs]},
[{state_timeout, 2_000, conn_est_timeout}]};
error ->
@@ -241,12 +248,15 @@
MmeName = hd(S#state.tried_mmes),
case ConnState of
comm_up ->
+ {ok, {MmeLAddr, MmeLPort}} = inet:sockname(Socket),
?LOG_NOTICE("MME ~p: connection (id=~p, ~p:~p) established",
[MmeName, Aid, MmeAddr, MmePort]),
%% send the S1 SETUP REQUEST PDU to the MME
sctp_send_from_enb(S#state.s1setup_req,
S#state{mme_aid = Aid}),
- {next_state, wait_s1setup_rsp, S#state{mme_aid = Aid}};
+ {next_state, wait_s1setup_rsp, S#state{mme_aid = Aid,
+ mme_saddr = MmeLAddr,
+ mme_sport = MmeLPort}};
_ ->
?LOG_NOTICE("MME ~p: connection establishment failed: ~p",
[MmeName, ConnState]),
@@ -467,7 +477,9 @@
conn_info(S) ->
Info = #{handler => S#state.handler,
enb_aid => S#state.enb_aid,
- mme_aid => S#state.mme_aid},
+ mme_aid => S#state.mme_aid,
+ mme_saddr => S#state.mme_saddr,
+ mme_sport => S#state.mme_sport},
maps:filter(fun(_K, V) -> V =/= undefined end, Info).
diff --git a/src/rest_server.erl b/src/rest_server.erl
index 3b14b86..0107427 100644
--- a/src/rest_server.erl
+++ b/src/rest_server.erl
@@ -461,10 +461,16 @@
enb_item_add_mme_conn_info(M0, #{mme_conn_info := ConnInfo}) ->
Pid = maps:get(handler, ConnInfo),
ERABs = s1ap_proxy:fetch_erab_list(Pid),
- %% TODO: mme_sport (source port) is not yet available in conn_info()
- M0#{mme_sctp_aid => maps:get(mme_aid, ConnInfo),
- erab_count => length(ERABs)
- };
+ M1 = M0#{erab_count => length(ERABs)},
+ %% mme_aid/mme_saddr/mme_sport are only present once the MME SCTP
+ %% connection is fully established (comm_up); handle them together.
+ case maps:find(mme_aid, ConnInfo) of
+ {ok, Aid} ->
+ M1#{mme_sctp_aid => Aid,
+ mme_saddr => inet:ntoa(maps:get(mme_saddr, ConnInfo)),
+ mme_sport => maps:get(mme_sport, ConnInfo)};
+ error -> M1
+ end;
enb_item_add_mme_conn_info(M0, _) -> M0.
To view, visit change 42433. To unsubscribe, or for help writing mail filters, visit settings.