fixeria has submitted this change. ( 
https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/42433?usp=email )

Change subject: [REST] Add MME source address/port to EnbItem
......................................................................

[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(-)

Approvals:
  laforge: Looks good to me, but someone else must approve
  fixeria: Looks good to me, approved
  Jenkins Builder: Verified
  pespin: Looks good to me, but someone else must approve




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 https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/42433?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I15bbddf96ac7d5b6f9962a8d745db58fdec334e7
Gerrit-Change-Number: 42433
Gerrit-PatchSet: 5
Gerrit-Owner: fixeria <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>

Reply via email to