forked from acouzens/open5gs
[ALL] Fix the memory leak (#1282)
This commit is contained in:
parent
340b23af94
commit
83d56fe40d
|
@ -92,6 +92,7 @@ typedef struct ogs_gtp_xact_s {
|
|||
#define OGS_GTP_DELETE_SEND_DEACTIVATE_BEARER_CONTEXT_REQUEST 3
|
||||
#define OGS_GTP_DELETE_SEND_UE_CONTEXT_RELEASE_COMMAND 4
|
||||
#define OGS_GTP_DELETE_HANDLE_PDN_CONNECTIVITY_REQUEST 5
|
||||
#define OGS_GTP_DELETE_UE_CONTEXT_REMOVE 6
|
||||
int delete_action;
|
||||
|
||||
#define OGS_GTP_RELEASE_SEND_UE_CONTEXT_RELEASE_COMMAND 1
|
||||
|
|
|
@ -1210,6 +1210,10 @@ void ogs_pfcp_far_remove(ogs_pfcp_far_t *far)
|
|||
|
||||
ogs_list_remove(&sess->far_list, far);
|
||||
|
||||
if (far->hash.teid.len)
|
||||
ogs_hash_set(self.far_teid_hash,
|
||||
&far->hash.teid.key, far->hash.teid.len, NULL);
|
||||
|
||||
if (far->hash.f_teid.len)
|
||||
ogs_hash_set(self.far_f_teid_hash,
|
||||
&far->hash.f_teid.key, far->hash.f_teid.len, NULL);
|
||||
|
|
|
@ -924,6 +924,8 @@ int amf_gnb_set_gnb_id(amf_gnb_t *gnb, uint32_t gnb_id)
|
|||
{
|
||||
ogs_assert(gnb);
|
||||
|
||||
ogs_hash_set(self.gnb_id_hash, &gnb_id, sizeof(gnb_id), NULL);
|
||||
|
||||
gnb->gnb_id = gnb_id;
|
||||
ogs_hash_set(self.gnb_id_hash, &gnb->gnb_id, sizeof(gnb->gnb_id), gnb);
|
||||
|
||||
|
@ -1508,6 +1510,7 @@ void amf_ue_set_suci(amf_ue_t *amf_ue,
|
|||
ogs_nas_5gs_mobile_identity_t *mobile_identity)
|
||||
{
|
||||
amf_ue_t *old_amf_ue = NULL;
|
||||
amf_sess_t *old_sess = NULL;
|
||||
char *suci = NULL;
|
||||
|
||||
ogs_assert(amf_ue);
|
||||
|
@ -1531,6 +1534,31 @@ void amf_ue_set_suci(amf_ue_t *amf_ue,
|
|||
(long long)old_amf_ue->ran_ue->amf_ue_ngap_id);
|
||||
ran_ue_remove(old_amf_ue->ran_ue);
|
||||
}
|
||||
|
||||
/*
|
||||
* We should delete the AMF-Session Context in the AMF-UE Context.
|
||||
* Otherwise, all unnecessary SESSIONs remain in SMF/UPF.
|
||||
*
|
||||
* In order to do this, AMF-Session Context should be moved
|
||||
* from OLD AMF-UE Context to NEW AMF-UE Context.
|
||||
*
|
||||
* If needed, The Session deletion process in NEW-AMF UE context will work.
|
||||
*
|
||||
* Note that we should not send Session-Release to the SMF at this point.
|
||||
* Another SBI Transaction can cause fatal errors.
|
||||
*/
|
||||
|
||||
/* Phase-1 : Change AMF-UE Context in Session Context */
|
||||
ogs_list_for_each(&old_amf_ue->sess_list, old_sess)
|
||||
old_sess->amf_ue = amf_ue;
|
||||
|
||||
/* Phase-2 : Move Session Context from OLD to NEW AMF-UE Context */
|
||||
memcpy(&amf_ue->sess_list,
|
||||
&old_amf_ue->sess_list, sizeof(amf_ue->sess_list));
|
||||
|
||||
/* Phase-3 : Clear Session Context in OLD AMF-UE Context */
|
||||
memset(&old_amf_ue->sess_list, 0, sizeof(old_amf_ue->sess_list));
|
||||
|
||||
amf_ue_remove(old_amf_ue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -413,7 +413,7 @@ int gmm_handle_registration_update(amf_ue_t *amf_ue,
|
|||
if ((psimask & (1 << sess->psi)) == 0) {
|
||||
if (SESSION_CONTEXT_IN_SMF(sess))
|
||||
amf_sbi_send_release_session(
|
||||
sess, AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT);
|
||||
sess, AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -622,7 +622,7 @@ int gmm_handle_service_update(amf_ue_t *amf_ue,
|
|||
if ((psimask & (1 << sess->psi)) == 0) {
|
||||
if (SESSION_CONTEXT_IN_SMF(sess))
|
||||
amf_sbi_send_release_session(
|
||||
sess, AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT);
|
||||
sess, AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -694,7 +694,8 @@ int gmm_handle_deregistration_request(amf_ue_t *amf_ue,
|
|||
|
||||
ogs_info("[%s] SUCI", amf_ue->suci);
|
||||
|
||||
amf_sbi_send_release_all_sessions(amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||
amf_sbi_send_release_all_sessions(
|
||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||
|
||||
if (ogs_list_count(&amf_ue->sess_list) == 0)
|
||||
ogs_assert(OGS_OK ==
|
||||
|
|
|
@ -261,7 +261,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
|
|||
}
|
||||
|
||||
amf_sbi_send_release_all_sessions(
|
||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||
if (amf_sess_xact_count(amf_ue) == xact_count) {
|
||||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
|
@ -1135,7 +1135,7 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
|
|||
}
|
||||
|
||||
amf_sbi_send_release_all_sessions(
|
||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||
if (amf_sess_xact_count(amf_ue) == xact_count) {
|
||||
ogs_assert(true ==
|
||||
amf_ue_sbi_discover_and_send(
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "s1ap-path.h"
|
||||
#include "s1ap-handler.h"
|
||||
#include "mme-sm.h"
|
||||
#include "mme-gtp-path.h"
|
||||
|
||||
#define MAX_CELL_PER_ENB 8
|
||||
|
||||
|
@ -1870,6 +1871,8 @@ int mme_enb_set_enb_id(mme_enb_t *enb, uint32_t enb_id)
|
|||
{
|
||||
ogs_assert(enb);
|
||||
|
||||
ogs_hash_set(self.enb_id_hash, &enb_id, sizeof(enb_id), NULL);
|
||||
|
||||
enb->enb_id = enb_id;
|
||||
ogs_hash_set(self.enb_id_hash, &enb->enb_id, sizeof(enb->enb_id), enb);
|
||||
|
||||
|
@ -2151,6 +2154,19 @@ mme_ue_t *mme_ue_add(enb_ue_t *enb_ue)
|
|||
return mme_ue;
|
||||
}
|
||||
|
||||
void mme_ue_hash_remove(mme_ue_t *mme_ue)
|
||||
{
|
||||
ogs_assert(mme_ue);
|
||||
|
||||
if (mme_ue->imsi_len != 0)
|
||||
ogs_hash_set(mme_self()->imsi_ue_hash,
|
||||
mme_ue->imsi, mme_ue->imsi_len, NULL);
|
||||
|
||||
if (mme_ue->current.m_tmsi)
|
||||
ogs_hash_set(self.guti_ue_hash,
|
||||
&mme_ue->current.guti, sizeof(ogs_nas_eps_guti_t), NULL);
|
||||
}
|
||||
|
||||
void mme_ue_remove(mme_ue_t *mme_ue)
|
||||
{
|
||||
ogs_assert(mme_ue);
|
||||
|
@ -2159,17 +2175,12 @@ void mme_ue_remove(mme_ue_t *mme_ue)
|
|||
|
||||
mme_ue_fsm_fini(mme_ue);
|
||||
|
||||
if (mme_ue->current.m_tmsi) {
|
||||
ogs_hash_set(self.guti_ue_hash,
|
||||
&mme_ue->current.guti, sizeof(ogs_nas_eps_guti_t), NULL);
|
||||
if (mme_ue->current.m_tmsi)
|
||||
ogs_assert(mme_m_tmsi_free(mme_ue->current.m_tmsi) == OGS_OK);
|
||||
}
|
||||
if (mme_ue->next.m_tmsi) {
|
||||
|
||||
if (mme_ue->next.m_tmsi)
|
||||
ogs_assert(mme_m_tmsi_free(mme_ue->next.m_tmsi) == OGS_OK);
|
||||
}
|
||||
if (mme_ue->imsi_len != 0)
|
||||
ogs_hash_set(self.imsi_ue_hash, mme_ue->imsi, mme_ue->imsi_len, NULL);
|
||||
|
||||
|
||||
/* Clear the saved PDN Connectivity Request */
|
||||
OGS_NAS_CLEAR_DATA(&mme_ue->pdn_connectivity_request);
|
||||
|
||||
|
@ -2212,6 +2223,7 @@ void mme_ue_remove_all(void)
|
|||
|
||||
if (enb_ue) enb_ue_remove(enb_ue);
|
||||
|
||||
mme_ue_hash_remove(mme_ue);
|
||||
mme_ue_remove(mme_ue);
|
||||
}
|
||||
}
|
||||
|
@ -2463,10 +2475,34 @@ int mme_ue_set_imsi(mme_ue_t *mme_ue, char *imsi_bcd)
|
|||
old_mme_ue->enb_ue->mme_ue_s1ap_id);
|
||||
enb_ue_remove(old_mme_ue->enb_ue);
|
||||
}
|
||||
mme_ue_remove(old_mme_ue);
|
||||
|
||||
/*
|
||||
* We should delete the MME-Session Context in the MME-UE Context.
|
||||
* Otherwise, all unnecessary SESSIONs remain in SMF/SGW-C/SGW-U/UPF.
|
||||
*
|
||||
* Hash deletion is separated from mme_ue_remove(). Otherwise,
|
||||
* hash deletion occurs simultaneously in mme_ue_remove()
|
||||
* after mme_gtp_send_delete_all_session(). This will delete the Hash
|
||||
* we added immediately below, so we can't find this IMSI.
|
||||
*
|
||||
* Note that we should not use the session movement method in AMF.
|
||||
* This is because the MME-S11-TEID in the Delete Session Response
|
||||
* uses the OLD MME.
|
||||
*/
|
||||
mme_ue_hash_remove(old_mme_ue);
|
||||
|
||||
if (SESSION_CONTEXT_IS_AVAILABLE(old_mme_ue)) {
|
||||
ogs_warn("[%s] Trigger OLD Session Remove", mme_ue->imsi_bcd);
|
||||
mme_gtp_send_delete_all_sessions(old_mme_ue,
|
||||
OGS_GTP_DELETE_UE_CONTEXT_REMOVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mme_ue->imsi_len != 0)
|
||||
ogs_hash_set(mme_self()->imsi_ue_hash,
|
||||
mme_ue->imsi, mme_ue->imsi_len, NULL);
|
||||
|
||||
ogs_hash_set(self.imsi_ue_hash, mme_ue->imsi, mme_ue->imsi_len, mme_ue);
|
||||
|
||||
return OGS_OK;
|
||||
|
|
|
@ -704,6 +704,7 @@ void mme_ue_new_guti(mme_ue_t *mme_ue);
|
|||
void mme_ue_confirm_guti(mme_ue_t *mme_ue);
|
||||
|
||||
mme_ue_t *mme_ue_add(enb_ue_t *enb_ue);
|
||||
void mme_ue_hash_remove(mme_ue_t *mme_ue);
|
||||
void mme_ue_remove(mme_ue_t *mme_ue);
|
||||
void mme_ue_remove_all(void);
|
||||
|
||||
|
|
|
@ -406,6 +406,12 @@ void mme_s11_handle_delete_session_response(
|
|||
}
|
||||
}
|
||||
|
||||
} else if (action == OGS_GTP_DELETE_UE_CONTEXT_REMOVE) {
|
||||
|
||||
/* Remove MME-UE Context with Session Context since IMSI duplicated */
|
||||
mme_ue_remove(mme_ue);
|
||||
return;
|
||||
|
||||
} else {
|
||||
ogs_fatal("Invalid action = %d", action);
|
||||
ogs_assert_if_reached();
|
||||
|
|
|
@ -1477,6 +1477,8 @@ void s1ap_handle_ue_context_release_action(enb_ue_t *enb_ue)
|
|||
ogs_debug(" Action: UE context remove");
|
||||
enb_ue_remove(enb_ue);
|
||||
ogs_expect_or_return(mme_ue);
|
||||
|
||||
mme_ue_hash_remove(mme_ue);
|
||||
mme_ue_remove(mme_ue);
|
||||
break;
|
||||
case S1AP_UE_CTX_REL_S1_HANDOVER_COMPLETE:
|
||||
|
|
Loading…
Reference in New Issue