pespin has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-hnbgw/+/38581?usp=email )

Change subject: Fix SCCP RLSD not sent upon rx RUA Disconnect due to error 
condition
......................................................................

Fix SCCP RLSD not sent upon rx RUA Disconnect due to error condition

Scenario: HNB tears down the RUA/Iu conn by first sending
RUA_DATA[RANAP IuReleaseReq], followed shortly by a RUA Disconnect with no
RANAP and Cause!=Normal. HNBGW should release the SCCP connection through
RLSD since it's impossible to terminate the Iu connection in a normal
condition.

Validated with TTCN-3 HNBGW_Tests.TC_cs_iu_release_req_rua_disconnect.

Related: osmo-ttcn3-hacks.git Change-Id 
I6782920c4a86d3311eb54239ab13a18e393c1ec0
Related: SYS#6602
Change-Id: I1b7f72034eaf40bfa60d552d434847467ac4e97a
---
M include/osmocom/hnbgw/context_map.h
M src/osmo-hnbgw/context_map_rua.c
M src/osmo-hnbgw/context_map_sccp.c
3 files changed, 62 insertions(+), 20 deletions(-)

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




diff --git a/include/osmocom/hnbgw/context_map.h 
b/include/osmocom/hnbgw/context_map.h
index 1e23777..8fe478c 100644
--- a/include/osmocom/hnbgw/context_map.h
+++ b/include/osmocom/hnbgw/context_map.h
@@ -55,9 +55,18 @@
        MAP_SCCP_EV_RX_DATA_INDICATION,
        /* RUA has received some data from HNB to forward via SCCP to CN. */
        MAP_SCCP_EV_TX_DATA_REQUEST,
-       /* The RAN side received a Disconnect, that means we are going to 
expect SCCP to disconnect too.
-        * CN should have received an Iu-ReleaseComplete with or before this, 
give CN a chance to send an SCCP RLSD;
-        * after a timeout we will send a non-standard RLSD to the CN instead. 
*/
+       /* 3GPP TS 25.468 9.1.5: The RAN side received a RUA Disconnect.
+        * - Under normal conditions (cause=Normal) the RUA Disconnect contains 
a RANAP Iu-ReleaseComplete.
+        *   On SCCP, the Iu-ReleaseComplete should still be forwarded as 
N-Data SCCP Data Form 1),
+        *   and we will expect the CN to send an SCCP RLSD soon. Hence, give 
CN a chance to send an SCCP RLSD;
+        *   after a timeout we will send a non-standard RLSD to the CN instead.
+        * - Under error conditions, cause!=Normal and there's no RANAP message.
+        *   In that case, we need to tear down the associated SCCP link 
towards CN with an RLSD,
+        *   which in turn will tear down the upper layer Iu conn.
+        *
+        * Parameter: bool rua_disconnect_err_condition, whether the disconnect
+        *            happened under error or normal conditions, as per the 
above.
+        */
        MAP_SCCP_EV_RAN_DISC,
        /* The RAN released ungracefully. We will directly disconnect the SCCP 
connection, too. */
        MAP_SCCP_EV_RAN_LINK_LOST,
@@ -127,6 +136,16 @@
        /* FSM handling the RUA state for rua_ctx_id. */
        struct osmo_fsm_inst *rua_fi;

+       /* State context related to field rua_fi above: */
+       struct {
+               /* Whether RUA Disconnect received from HNB happened as a 
normal condition or an error/abnormal condition.
+               * This is known based on cause and/or RANAP message included in 
the RUA
+               * Disconnect message, and tells us whether we should immediately
+               * terminate the related SCCP session or wait for CN to finish 
it.
+               * Defaults to false, only set to true explicitly when needed. */
+               bool rua_disconnect_err_condition;
+       } rua_fi_ctx;
+
        /* Pointer to CN, to transceive SCCP. */
        struct hnbgw_cnlink *cnlink;
        /* SCCP User SAP connection ID used in SCCP messages to/from the 
cn_link. */
diff --git a/src/osmo-hnbgw/context_map_rua.c b/src/osmo-hnbgw/context_map_rua.c
index 7286906..2d9fd8d 100644
--- a/src/osmo-hnbgw/context_map_rua.c
+++ b/src/osmo-hnbgw/context_map_rua.c
@@ -287,15 +287,21 @@
                return;

        case MAP_RUA_EV_RX_DISCONNECT:
-               /* received Disconnect from RUA. forward any payload to SCCP, 
and change state. */
-               if (!map_sccp_is_active(map)) {
-                       /* If, unlikely, the SCCP is already gone, changing to 
MAP_RUA_ST_DISCONNECTED frees the
-                        * hnbgw_context_map. Avoid a use-after-free. */
-                       map_rua_fsm_state_chg(MAP_RUA_ST_DISCONNECTED);
-                       return;
+               /* 3GPP TS 25.468 9.1.5: RUA has disconnected.
+                * - Under normal conditions (cause=Normal) the RUA Disconnect 
contains a RANAP Iu-ReleaseComplete.
+                *   On SCCP, the Iu-ReleaseComplete should still be forwarded 
as N-Data SCCP Data Form 1),
+                *   and we will expect the CN to send an SCCP RLSD soon.
+                * - Under error conditions, cause!=Normal and there's no RANAP 
message.
+                *   In that case, we need to tear down the associated SCCP 
link towards CN,
+                *   which in turn will tear down the upper layer Iu conn.
+                */
+               if (msg_has_l2_data(ranap_msg)) {
+                       /* Forward any payload to SCCP before Disconnect. */
+                       handle_rx_rua(fi, ranap_msg);
+               } else {
+                       map->rua_fi_ctx.rua_disconnect_err_condition = true;
                }
                map_rua_fsm_state_chg(MAP_RUA_ST_DISCONNECTED);
-               handle_rx_rua(fi, ranap_msg);
                return;

        case MAP_RUA_EV_HNB_LINK_LOST:
@@ -315,13 +321,13 @@
        }
 }

-static void map_rua_free_if_done(struct hnbgw_context_map *map, uint32_t 
sccp_event)
+static void map_rua_free_if_done(struct hnbgw_context_map *map, uint32_t 
sccp_event, void *ev_data)
 {
        /* From RUA's POV, we can now free the hnbgw_context_map.
         * If SCCP is still active, tell it to disconnect -- in that case the 
SCCP side will call context_map_free().
         * If SCCP is no longer active, free this map. */
        if (map_sccp_is_active(map))
-               map_sccp_dispatch(map, sccp_event, NULL);
+               map_sccp_dispatch(map, sccp_event, ev_data);
        else
                context_map_free(map);
 }
@@ -329,7 +335,7 @@
 static void map_rua_disconnected_onenter(struct osmo_fsm_inst *fi, uint32_t 
prev_state)
 {
        struct hnbgw_context_map *map = fi->priv;
-       map_rua_free_if_done(map, MAP_SCCP_EV_RAN_DISC);
+       map_rua_free_if_done(map, MAP_SCCP_EV_RAN_DISC, (void 
*)map->rua_fi_ctx.rua_disconnect_err_condition);
 }

 static void map_rua_disconnected_action(struct osmo_fsm_inst *fi, uint32_t 
event, void *data)
@@ -343,7 +349,7 @@
 static void map_rua_disrupted_onenter(struct osmo_fsm_inst *fi, uint32_t 
prev_state)
 {
        struct hnbgw_context_map *map = fi->priv;
-       map_rua_free_if_done(map, MAP_SCCP_EV_RAN_LINK_LOST);
+       map_rua_free_if_done(map, MAP_SCCP_EV_RAN_LINK_LOST, NULL);
 }

 void map_rua_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause 
cause)
diff --git a/src/osmo-hnbgw/context_map_sccp.c 
b/src/osmo-hnbgw/context_map_sccp.c
index 511577c..b79dc39 100644
--- a/src/osmo-hnbgw/context_map_sccp.c
+++ b/src/osmo-hnbgw/context_map_sccp.c
@@ -349,26 +349,40 @@

 static void map_sccp_connected_action(struct osmo_fsm_inst *fi, uint32_t 
event, void *data)
 {
-       struct msgb *ranap_msg = data;
+       struct msgb *ranap_msg;
+       bool rua_disconnect_err_condition;

        switch (event) {

        case MAP_SCCP_EV_RX_DATA_INDICATION:
+               ranap_msg = data;
                /* forward RANAP from SCCP to RUA */
                handle_rx_sccp(fi, ranap_msg);
                return;

        case MAP_SCCP_EV_TX_DATA_REQUEST:
+               ranap_msg = data;
                /* Someone (usually the RUA side) wants us to send a RANAP 
payload to CN via SCCP */
                tx_sccp_df1(fi, ranap_msg);
                return;

        case MAP_SCCP_EV_RAN_DISC:
-               /* RUA has disconnected, and usually has sent an 
Iu-ReleaseComplete along with its RUA Disconnect. On
-                * SCCP, the Iu-ReleaseComplete should still be forwarded as 
N-Data (SCCP Data Form 1), and we will
-                * expect the CN to send an SCCP RLSD soon. */
-               map_sccp_fsm_state_chg(MAP_SCCP_ST_WAIT_RLSD);
-               tx_sccp_df1(fi, ranap_msg);
+               rua_disconnect_err_condition = !!data;
+               /* 3GPP TS 25.468 9.1.5: RUA has disconnected.
+                * - Under normal conditions (cause=Normal) the RUA Disconnect
+                *   contained a RANAP Iu-ReleaseComplete which we already
+                *   handled here through MAP_SCCP_EV_TX_DATA_REQUEST.
+                *   On SCCP, We will expect the CN to send an SCCP RLSD soon.
+                * - Under error conditions, cause!=Normal and there was no 
RANAP message.
+                *   In that case, we need to tear down the associated SCCP 
link towards CN,
+                *   which in turn will tear down the upper layer Iu conn.
+                */
+               if (rua_disconnect_err_condition) {
+                       tx_sccp_rlsd(fi);
+                       map_sccp_fsm_state_chg(MAP_SCCP_ST_DISCONNECTED);
+               } else {
+                       map_sccp_fsm_state_chg(MAP_SCCP_ST_WAIT_RLSD);
+               }
                return;

        case MAP_SCCP_EV_RAN_LINK_LOST:
@@ -377,6 +391,7 @@
        case MAP_SCCP_EV_USER_ABORT:
                /* The user is asking for disconnection, so there is no Iu 
Release in progress. Disconnect now. */
        case MAP_SCCP_EV_CN_LINK_LOST:
+               ranap_msg = data;
                /* The CN peer has sent a RANAP RESET, so the old link that 
this map ran on is lost */

                /* There won't be any ranap_msg, but if a caller wants to 
dispatch a msg, forward it before
@@ -387,6 +402,7 @@
                return;

        case MAP_SCCP_EV_RX_RELEASED:
+               ranap_msg = data;
                /* The CN sends an N-Disconnect (SCCP Released) out of the 
usual sequence. Not what we expected, but
                 * handle it. */
                LOGPFSML(fi, LOGL_ERROR, "CN sends SCCP Released sooner than 
expected\n");
@@ -395,6 +411,7 @@
                return;

        case MAP_SCCP_EV_RX_CONNECTION_CONFIRM:
+               ranap_msg = data;
                /* Already connected. Unusual, but if there is data just 
forward it. */
                LOGPFSML(fi, LOGL_ERROR, "Already connected, but received SCCP 
CC again\n");
                handle_rx_sccp(fi, ranap_msg);

--
To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/38581?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: osmo-hnbgw
Gerrit-Branch: master
Gerrit-Change-Id: I1b7f72034eaf40bfa60d552d434847467ac4e97a
Gerrit-Change-Number: 38581
Gerrit-PatchSet: 3
Gerrit-Owner: pespin <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <[email protected]>
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: lynxis lazus <[email protected]>
Gerrit-Reviewer: neels <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>

Reply via email to