From 0f5d9681492fc361772b5f15c971aaa97f9e23db Mon Sep 17 00:00:00 2001 From: Bostjan Meglic Date: Mon, 12 Sep 2022 11:07:51 +0000 Subject: [PATCH] [SMF] Wait for both N1&N2 release signals before releasing session When UE would send a request to release PDU session, AMF would eventually send "PDU Session Resource Release Command" downlink to both UE (N1) and gNB (N2). Each UE and gNB would then reply with "PDU Session Resource Release Response" indicating they released their own resources. Usually the first one to respond would be gNB. SMF made an assumption that this would always be the case. And it would wait for signal that UE resources were freed, before releasing session resources. But occasionally the situation is that UE responds first, and SMF releases resources prematurely. This situation does not normally occur. But under high stress (100's of UE PDU releases at the same time) this happens occasionally. According to the standard, this situation is perfectly normal. 3GPP TS 23.502 Rel. 16 4.3.4.2 UE or network requested PDU Session Release for Non-Roaming and Roaming with Local Breakout ... Steps 8-10 may happen before steps 6-7. ... --- src/smf/context.h | 3 +++ src/smf/gsm-sm.c | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/smf/context.h b/src/smf/context.h index f6d3f1312..d6a7f3a7b 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -405,6 +405,9 @@ typedef struct smf_sess_s { ogs_pfcp_node_t *pfcp_node; smf_ue_t *smf_ue; + + bool n1_released; + bool n2_released; } smf_sess_t; void smf_context_init(void); diff --git a/src/smf/gsm-sm.c b/src/smf/gsm-sm.c index 6750d887b..09e3ef7a9 100644 --- a/src/smf/gsm-sm.c +++ b/src/smf/gsm-sm.c @@ -1521,6 +1521,11 @@ void smf_gsm_state_wait_5gc_n1_n2_release(ogs_fsm_t *s, smf_event_t *e) ogs_assert(true == ogs_sbi_send_http_status_no_content(stream)); + sess->n2_released = true; + if ((sess->n1_released) && (sess->n2_released)) { + OGS_FSM_TRAN(s, &smf_gsm_state_session_will_release); + } + } else { ogs_fatal("Invalid state [%d]", ngap_state); ogs_assert_if_reached(); @@ -1545,7 +1550,12 @@ void smf_gsm_state_wait_5gc_n1_n2_release(ogs_fsm_t *s, smf_event_t *e) case OGS_NAS_5GS_PDU_SESSION_RELEASE_COMPLETE: ogs_assert(true == ogs_sbi_send_http_status_no_content(stream)); ogs_assert(true == smf_sbi_send_sm_context_status_notify(sess)); - OGS_FSM_TRAN(s, &smf_gsm_state_session_will_release); + + sess->n1_released = true; + if ((sess->n1_released) && (sess->n2_released)) { + OGS_FSM_TRAN(s, &smf_gsm_state_session_will_release); + } + break; default: strerror = ogs_msprintf("Unknown message [%d]",