[MME] Cancel Location while Idle (#1797)

* Cancel Location while Idle Fix

* Forgot about SGSAP on MME Change.

Added "action" to sgsap_send_detach..

* Make handle_clr uniform with other handlers

* Added Robustness for Any Detach Type

* Memory wasn't freed upon CLR for unknown IMSIs

* Moving MME Detach to new PR
This commit is contained in:
jmasterfunk84 2022-10-04 20:06:01 -06:00 committed by GitHub
parent 7c8722d9d4
commit 15680003b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 102 additions and 40 deletions

View File

@ -179,6 +179,7 @@ typedef struct ogs_diam_s6a_clr_message_s {
#define OGS_DIAM_S6A_CLR_FLAGS_S6A_S6D_INDICATOR (1)
#define OGS_DIAM_S6A_CLR_FLAGS_REATTACH_REQUIRED (1 << 1)
uint32_t clr_flags;
uint32_t cancellation_type;
} ogs_diam_s6a_clr_message_t;
typedef struct ogs_diam_s6a_idr_message_s {

View File

@ -96,15 +96,17 @@ typedef struct ogs_gtp_xact_s {
#define OGS_GTP_MODIFY_QOS_UPDATE ((uint64_t)1<<1)
uint64_t update_flags;
#define OGS_GTP_DELETE_NO_ACTION 1
#define OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST 2
#define OGS_GTP_DELETE_SEND_DETACH_ACCEPT 3
#define OGS_GTP_DELETE_NO_ACTION 1
#define OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST 2
#define OGS_GTP_DELETE_SEND_DETACH_ACCEPT 3
#define OGS_GTP_DELETE_SEND_DEACTIVATE_BEARER_CONTEXT_REQUEST 4
#define OGS_GTP_DELETE_SEND_UE_CONTEXT_RELEASE_COMMAND 5
#define OGS_GTP_DELETE_SEND_S1_REMOVE_AND_UNLINK 6
#define OGS_GTP_DELETE_HANDLE_PDN_CONNECTIVITY_REQUEST 7
#define OGS_GTP_DELETE_UE_CONTEXT_REMOVE 8
#define OGS_GTP_DELETE_IN_PATH_SWITCH_REQUEST 9
#define OGS_GTP_DELETE_SEND_UE_CONTEXT_RELEASE_COMMAND 5
#define OGS_GTP_DELETE_SEND_S1_REMOVE_AND_UNLINK 6
#define OGS_GTP_DELETE_HANDLE_PDN_CONNECTIVITY_REQUEST 7
#define OGS_GTP_DELETE_UE_CONTEXT_REMOVE 8
#define OGS_GTP_DELETE_UE_CONTEXT_COMPLETE_REMOVE 9
#define OGS_GTP_DELETE_IN_PATH_SWITCH_REQUEST 10
int delete_action;
#define OGS_GTP_RELEASE_SEND_UE_CONTEXT_RELEASE_COMMAND 1

View File

@ -389,10 +389,10 @@ int emm_handle_detach_request(
*
* So, we will lose the MME_EPS_TYPE_DETACH_REQUEST_TO_UE.
*
* We need more variable(nas_eps.detach_type)
* We need more variable(detach_type)
* to keep Detach-Type whether UE-initiated or MME-initiaed. */
mme_ue->nas_eps.type = mme_ue->nas_eps.detach_type =
MME_EPS_TYPE_DETACH_REQUEST_FROM_UE;
mme_ue->nas_eps.type = MME_EPS_TYPE_DETACH_REQUEST_FROM_UE;
mme_ue->detach_type = MME_DETACH_TYPE_REQUEST_FROM_UE;
mme_ue->nas_eps.ksi = detach_type->nas_key_set_identifier;
ogs_debug(" OGS_NAS_EPS TYPE[%d] KSI[%d]",

View File

@ -316,20 +316,25 @@ struct mme_ue_s {
ogs_nas_eps_update_type_t update;
ogs_nas_service_type_t service;
ogs_nas_detach_type_t detach;
/* 1. MME initiated detach request to the UE.
* (nas_eps.type = MME_EPS_TYPE_DETACH_REQUEST_TO_UE)
* 2. If UE is IDLE, Paging sent to the UE
* 3. If UE is wake-up, UE will send Server Request.
* (nas_eps.type = MME_EPS_TYPE_SERVICE_REQUEST)
*
* So, we will lose the MME_EPS_TYPE_DETACH_REQUEST_TO_UE.
*
* We need more variable(nas_eps.detach_type)
* to keep Detach-Type whether UE-initiated or MME-initiaed. */
uint8_t detach_type;
} nas_eps;
/* 1. MME initiated detach request to the UE.
* (nas_eps.type = MME_EPS_TYPE_DETACH_REQUEST_TO_UE)
* 2. If UE is IDLE, Paging sent to the UE
* 3. If UE is wake-up, UE will send Server Request.
* (nas_eps.type = MME_EPS_TYPE_SERVICE_REQUEST)
*
* So, we will lose the MME_EPS_TYPE_DETACH_REQUEST_TO_UE.
*
* We need more variable(detach_type)
* to keep Detach-Type whether UE-initiated or MME-initiaed. */
#define MME_DETACH_TYPE_REQUEST_FROM_UE 1
#define MME_DETACH_TYPE_MME_EXPLICIT 2
#define MME_DETACH_TYPE_HSS_EXPLICIT 3
#define MME_DETACH_TYPE_MME_IMPLICIT 4
#define MME_DETACH_TYPE_HSS_IMPLICIT 5
uint8_t detach_type;
/* UE identity */
#define MME_UE_HAVE_IMSI(__mME) \
((__mME) && ((__mME)->imsi_len))

View File

@ -1510,6 +1510,7 @@ static int mme_ogs_diam_s6a_clr_cb( struct msg **msg, struct avp *avp,
ogs_assert(ret == 0);
ret = fd_msg_avp_hdr(avp, &hdr);
ogs_assert(ret == 0);
clr_message->cancellation_type = hdr->avp_value->i32;
/* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */
ret = fd_msg_rescode_set(ans, (char*)"DIAMETER_SUCCESS", NULL, NULL, 1);
@ -1583,7 +1584,9 @@ out:
/* Send the answer */
ret = fd_msg_send(msg, NULL, NULL);
ogs_assert(ret == 0);
ogs_assert(ret == 0);
ogs_free(s6a_message);
return 0;
}

View File

@ -28,8 +28,9 @@ void mme_send_delete_session_or_detach(mme_ue_t *mme_ue)
{
ogs_assert(mme_ue);
switch (mme_ue->nas_eps.detach_type) {
case MME_EPS_TYPE_DETACH_REQUEST_FROM_UE:
switch (mme_ue->detach_type) {
case MME_DETACH_TYPE_REQUEST_FROM_UE:
ogs_debug("Detach Request from UE");
if (SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) {
mme_gtp_send_delete_all_sessions(
mme_ue, OGS_GTP_DELETE_SEND_DETACH_ACCEPT);
@ -37,11 +38,37 @@ void mme_send_delete_session_or_detach(mme_ue_t *mme_ue)
ogs_assert(OGS_OK == nas_eps_send_detach_accept(mme_ue));
}
break;
case MME_EPS_TYPE_DETACH_REQUEST_TO_UE:
/* MME Explicit Detach, ie: O&M Procedures */
case MME_DETACH_TYPE_MME_EXPLICIT:
break;
/* HSS Explicit Detach, ie: Subscription Withdrawl Cancel Location */
case MME_DETACH_TYPE_HSS_EXPLICIT:
ogs_debug("Explicit HSS Detach");
if (SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) {
mme_gtp_send_delete_all_sessions(mme_ue, OGS_GTP_DELETE_NO_ACTION);
}
break;
/* MME Implicit Detach, ie: Lost Communication */
case MME_DETACH_TYPE_MME_IMPLICIT:
break;
/* HSS Implicit Detach, ie: MME-UPDATE-PROCEDURE */
case MME_DETACH_TYPE_HSS_IMPLICIT:
ogs_debug("Implicit HSS Detach");
if (SESSION_CONTEXT_IS_AVAILABLE(mme_ue)) {
if (ECM_IDLE(mme_ue)) {
mme_gtp_send_delete_all_sessions(mme_ue,
OGS_GTP_DELETE_UE_CONTEXT_COMPLETE_REMOVE);
} else {
mme_gtp_send_delete_all_sessions(mme_ue,
OGS_GTP_DELETE_SEND_UE_CONTEXT_RELEASE_COMMAND);
}
}
break;
default:
ogs_fatal(" Invalid OGS_NAS_EPS TYPE[%d]", mme_ue->nas_eps.type);
ogs_assert_if_reached();

View File

@ -639,6 +639,12 @@ void mme_s11_handle_delete_session_response(
mme_ue_remove(mme_ue);
return;
} else if (action == OGS_GTP_DELETE_UE_CONTEXT_COMPLETE_REMOVE) {
/* Remove MME-UE Context and hash after Implicit Detach */
mme_ue_hash_remove(mme_ue);
mme_ue_remove(mme_ue);
return;
} else if (action == OGS_GTP_DELETE_IN_PATH_SWITCH_REQUEST) {
/* Don't have to remove Session in X2 Handover with SGW relocation */

View File

@ -170,11 +170,13 @@ uint8_t mme_s6a_handle_idr(
return OGS_OK;
}
void mme_s6a_handle_clr(
mme_ue_t *mme_ue, ogs_diam_s6a_clr_message_t *clr_message)
void mme_s6a_handle_clr(mme_ue_t *mme_ue, ogs_diam_s6a_message_t *s6a_message)
{
ogs_diam_s6a_clr_message_t *clr_message = NULL;
ogs_assert(mme_ue);
ogs_assert(clr_message);
ogs_assert(s6a_message);
clr_message = &s6a_message->clr_message;
ogs_assert(clr_message);
/* Set EPS Detach */
memset(&mme_ue->nas_eps.detach, 0, sizeof(ogs_nas_detach_type_t));
@ -194,26 +196,42 @@ void mme_s6a_handle_clr(
*
* So, we will lose the MME_EPS_TYPE_DETACH_REQUEST_TO_UE.
*
* We need more variable(nas_eps.detach_type)
* We need more variable(detach_type)
* to keep Detach-Type whether UE-initiated or MME-initiaed. */
mme_ue->nas_eps.type = mme_ue->nas_eps.detach_type =
MME_EPS_TYPE_DETACH_REQUEST_TO_UE;
mme_ue->nas_eps.type = MME_EPS_TYPE_DETACH_REQUEST_TO_UE;
ogs_debug(" OGS_NAS_EPS TYPE[%d]", mme_ue->nas_eps.type);
if (OGS_FSM_CHECK(&mme_ue->sm, emm_state_de_registered)) {
/* Remove all trace of subscriber even when detached. */
mme_ue_hash_remove(mme_ue);
mme_ue_remove(mme_ue);
} else if (ECM_IDLE(mme_ue)) {
MME_STORE_PAGING_INFO(mme_ue, MME_PAGING_TYPE_DETACH_TO_UE, NULL);
ogs_assert(OGS_OK == s1ap_send_paging(mme_ue, S1AP_CNDomain_ps));
} else {
ogs_assert(OGS_OK == nas_eps_send_detach_request(mme_ue));
return;
} else if (clr_message->cancellation_type ==
OGS_DIAM_S6A_CT_MME_UPDATE_PROCEDURE) {
mme_ue->detach_type = MME_DETACH_TYPE_HSS_IMPLICIT;
if (MME_P_TMSI_IS_AVAILABLE(mme_ue)) {
ogs_assert(OGS_OK == sgsap_send_detach_indication(mme_ue));
} else {
mme_send_delete_session_or_detach(mme_ue);
}
} else if (clr_message->cancellation_type ==
OGS_DIAM_S6A_CT_SUBSCRIPTION_WITHDRAWL) {
mme_ue->detach_type = MME_DETACH_TYPE_HSS_EXPLICIT;
if (ECM_IDLE(mme_ue)) {
MME_STORE_PAGING_INFO(mme_ue, MME_PAGING_TYPE_DETACH_TO_UE, NULL);
ogs_assert(OGS_OK == s1ap_send_paging(mme_ue, S1AP_CNDomain_ps));
} else {
ogs_assert(OGS_OK == nas_eps_send_detach_request(mme_ue));
if (MME_P_TMSI_IS_AVAILABLE(mme_ue)) {
ogs_assert(OGS_OK == sgsap_send_detach_indication(mme_ue));
} else {
mme_send_delete_session_or_detach(mme_ue);
}
}
} else {
ogs_error("Unsupported Cancellation-Type [%d]",
clr_message->cancellation_type);
}
}

View File

@ -33,7 +33,7 @@ uint8_t mme_s6a_handle_ula(
uint8_t mme_s6a_handle_idr(
mme_ue_t *mme_ue, ogs_diam_s6a_message_t *s6a_message);
void mme_s6a_handle_clr(
mme_ue_t *mme_ue, ogs_diam_s6a_clr_message_t *clr_message);
mme_ue_t *mme_ue, ogs_diam_s6a_message_t *s6a_message);
#ifdef __cplusplus
}

View File

@ -432,7 +432,7 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
}
break;
case OGS_DIAM_S6A_CMD_CODE_CANCEL_LOCATION:
mme_s6a_handle_clr(mme_ue, &s6a_message->clr_message);
mme_s6a_handle_clr(mme_ue, s6a_message);
break;
case OGS_DIAM_S6A_CMD_CODE_INSERT_SUBSCRIBER_DATA:
mme_s6a_handle_idr(mme_ue, s6a_message);