[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.
...
This commit is contained in:
Bostjan Meglic 2022-09-12 11:07:51 +00:00 committed by Sukchan Lee
parent 5520cb65a5
commit 0f5d968149
2 changed files with 14 additions and 1 deletions

View File

@ -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);

View File

@ -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]",