From 7e29e7486f560dc5c043ea092407dc1812a440c4 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Sat, 27 Jun 2020 15:21:29 -0400 Subject: [PATCH] Add sanity check for unexpected gNB behavior --- src/amf/context.c | 3 --- src/amf/context.h | 2 ++ src/amf/gmm-handler.c | 26 +++++++++++++++++++++----- src/amf/ngap-handler.c | 21 ++++++++++++++++++++- src/amf/nsmf-handler.c | 16 +++++++++++++--- src/amf/sbi-path.c | 12 ++++++++---- 6 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/amf/context.c b/src/amf/context.c index 9130e9182..7cb48db8e 100644 --- a/src/amf/context.c +++ b/src/amf/context.c @@ -1488,9 +1488,6 @@ void amf_sess_remove(amf_sess_t *sess) if (sess->dnn) ogs_free(sess->dnn); - if (sess->n2smbuf) - ogs_pkbuf_free(sess->n2smbuf); - OGS_NAS_CLEAR_DATA(&sess->ue_pco); OGS_TLV_CLEAR_DATA(&sess->pgw_pco); diff --git a/src/amf/context.h b/src/amf/context.h index 890a62492..0cc3815f4 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -388,6 +388,8 @@ typedef struct amf_sess_s { uint8_t psi; /* PDU Session Identity */ uint8_t pti; /* Procedure Trasaction Identity */ +#define SESSION_CONTEXT_IN_SMF(__sESS) \ + ((__sESS) && (__sESS)->sm_context_ref) char *sm_context_ref; /* smContextRef from SMF */ #define SESSION_SYNC_DONE(__aMF) \ diff --git a/src/amf/gmm-handler.c b/src/amf/gmm-handler.c index 3428f0a22..4767a08aa 100644 --- a/src/amf/gmm-handler.c +++ b/src/amf/gmm-handler.c @@ -271,7 +271,19 @@ int gmm_handle_registration_update(amf_ue_t *amf_ue, ogs_list_for_each(&amf_ue->sess_list, sess) { if (psimask & (1 << sess->psi)) { - if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED) +#if REMOVED + /* + * TS23.502 + * 4.2.3.2 UE Triggered Service Request + * + * Step 4. The Nsmf_PDUSession_UpdateSMContext Request is invoked: + * + * - If the UE identifies List Of PDU Sessions To Be Activated + * in the Service Request message; + * if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED) + */ +#endif + if (SESSION_CONTEXT_IN_SMF(sess)) amf_sbi_send_activating_session(sess); } } @@ -289,7 +301,8 @@ int gmm_handle_registration_update(amf_ue_t *amf_ue, ogs_list_for_each(&amf_ue->sess_list, sess) { if ((psimask & (1 << sess->psi)) == 0) { - amf_sbi_send_release_session(sess); + if (SESSION_CONTEXT_IN_SMF(sess)) + amf_sbi_send_release_session(sess); } } } @@ -407,9 +420,10 @@ int gmm_handle_service_update(amf_ue_t *amf_ue, * * - If the UE identifies List Of PDU Sessions To Be Activated * in the Service Request message; + * if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED) */ - if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED) #endif + if (SESSION_CONTEXT_IN_SMF(sess)) amf_sbi_send_activating_session(sess); } } @@ -441,8 +455,10 @@ int gmm_handle_service_update(amf_ue_t *amf_ue, psimask |= pdu_session_status->psi >> 8; ogs_list_for_each(&amf_ue->sess_list, sess) { - if ((psimask & (1 << sess->psi)) == 0) - amf_sbi_send_release_session(sess); + if ((psimask & (1 << sess->psi)) == 0) { + if (SESSION_CONTEXT_IN_SMF(sess)) + amf_sbi_send_release_session(sess); + } } } diff --git a/src/amf/ngap-handler.c b/src/amf/ngap-handler.c index 7493eaa24..129ed69cc 100644 --- a/src/amf/ngap-handler.c +++ b/src/amf/ngap-handler.c @@ -757,6 +757,15 @@ void ngap_handle_initial_context_setup_response( return; } + if (!SESSION_CONTEXT_IN_SMF(sess)) { + ogs_error("Session Context is not in SMF [%d]", + (int)PDUSessionItem->pDUSessionID); + ngap_send_error_indication2(amf_ue, + NGAP_Cause_PR_radioNetwork, + NGAP_CauseRadioNetwork_unknown_PDU_session_ID); + return; + } + /* UPDATE_UpCnxState - ACTIVATED */ sess->ueUpCnxState = OpenAPI_up_cnx_state_ACTIVATED; @@ -1128,10 +1137,11 @@ void ngap_handle_ue_context_release_request( sess = amf_sess_find_by_psi(amf_ue, PDUSessionItem->pDUSessionID); - if (sess) + if (SESSION_CONTEXT_IN_SMF(sess)) { amf_sbi_send_deactivate_session( sess, Cause->present, (int)Cause->choice.radioNetwork); + } } } @@ -1388,6 +1398,15 @@ void ngap_handle_pdu_session_resource_setup_response( return; } + if (!SESSION_CONTEXT_IN_SMF(sess)) { + ogs_error("Session Context is not in SMF [%d]", + (int)PDUSessionItem->pDUSessionID); + ngap_send_error_indication2(amf_ue, + NGAP_Cause_PR_radioNetwork, + NGAP_CauseRadioNetwork_unknown_PDU_session_ID); + return; + } + /* UPDATE_UpCnxState - ACTIVATED */ sess->ueUpCnxState = OpenAPI_up_cnx_state_ACTIVATED; diff --git a/src/amf/nsmf-handler.c b/src/amf/nsmf-handler.c index ea8c6b103..a66d43351 100644 --- a/src/amf/nsmf-handler.c +++ b/src/amf/nsmf-handler.c @@ -214,8 +214,16 @@ int amf_nsmf_pdu_session_handle_update_sm_context( return OGS_ERROR; } + /* + * To Deliver N2 SM Content to gNB Temporarily, + * Store N2 SM Context in Session Context + */ if (sess->n2smbuf) { - /* Free the old n2smbuf */ + /* + * It should not be reached this way. + * If the problem occurred, free the old n2smbuf + */ + ogs_error("N2 SM Content is duplicated"); ogs_pkbuf_free(sess->n2smbuf); } /* @@ -229,14 +237,16 @@ int amf_nsmf_pdu_session_handle_update_sm_context( if (SESSION_SYNC_DONE(amf_ue)) { nas_5gs_send_accept(amf_ue); -#if 0 /* Move the context free to amf_sess_remove() */ + /* + * After sending accept message, N2 SM context is freed + * For checking memory, NULL pointer should be set to n2smbuf. + */ ogs_list_for_each(&amf_ue->sess_list, sess) { if (sess->n2smbuf) { ogs_pkbuf_free(sess->n2smbuf); sess->n2smbuf = NULL; } } -#endif } } else { diff --git a/src/amf/sbi-path.c b/src/amf/sbi-path.c index e51ac8dfe..3b87fb847 100644 --- a/src/amf/sbi-path.c +++ b/src/amf/sbi-path.c @@ -209,8 +209,10 @@ void amf_sbi_send_deactivate_all_sessions( ogs_assert(amf_ue); - ogs_list_for_each(&amf_ue->sess_list, sess) - amf_sbi_send_deactivate_session(sess, group, cause); + ogs_list_for_each(&amf_ue->sess_list, sess) { + if (SESSION_CONTEXT_IN_SMF(sess)) + amf_sbi_send_deactivate_session(sess, group, cause); + } } void amf_sbi_send_release_session(amf_sess_t *sess) @@ -228,6 +230,8 @@ void amf_sbi_send_release_all_sessions(amf_ue_t *amf_ue) ogs_assert(amf_ue); - ogs_list_for_each(&amf_ue->sess_list, sess) - amf_sbi_send_release_session(sess); + ogs_list_for_each(&amf_ue->sess_list, sess) { + if (SESSION_CONTEXT_IN_SMF(sess)) + amf_sbi_send_release_session(sess); + } }