[SMF] Fix crash on double policy deletion (#2489)

This commit is contained in:
Sukchan Lee 2023-08-10 22:14:48 +09:00
parent 93e05f481b
commit e7f7c4274e
7 changed files with 51 additions and 34 deletions

View File

@ -761,7 +761,7 @@ amf_sess_t *amf_sess_add(amf_ue_t *amf_ue, uint8_t psi);
do { \ do { \
ogs_sbi_object_t *sbi_object = NULL; \ ogs_sbi_object_t *sbi_object = NULL; \
ogs_assert(__sESS); \ ogs_assert(__sESS); \
sbi_object = &sess->sbi; \ sbi_object = &(__sESS)->sbi; \
ogs_assert(sbi_object); \ ogs_assert(sbi_object); \
\ \
ogs_error("AMF_SESS_CLEAR"); \ ogs_error("AMF_SESS_CLEAR"); \

View File

@ -677,14 +677,14 @@ struct mme_ue_s {
do { \ do { \
mme_ue_t *mme_ue = NULL; \ mme_ue_t *mme_ue = NULL; \
ogs_assert(__sESS); \ ogs_assert(__sESS); \
mme_ue = __sESS->mme_ue; \ mme_ue = (__sESS)->mme_ue; \
ogs_assert(mme_ue); \ ogs_assert(mme_ue); \
ogs_info("Removed Session: UE IMSI:[%s] APN:[%s]", \ ogs_info("Removed Session: UE IMSI:[%s] APN:[%s]", \
mme_ue->imsi_bcd, \ mme_ue->imsi_bcd, \
sess->session ? sess->session->name : "Unknown"); \ (__sESS)->session ? (__sESS)->session->name : "Unknown"); \
if (mme_sess_count(mme_ue) == 1) /* Last Session */ \ if (mme_sess_count(mme_ue) == 1) /* Last Session */ \
CLEAR_SESSION_CONTEXT(mme_ue); \ CLEAR_SESSION_CONTEXT(mme_ue); \
mme_sess_remove(sess); \ mme_sess_remove(__sESS); \
} while(0) } while(0)
#define ACTIVE_EPS_BEARERS_IS_AVAIABLE(__mME) \ #define ACTIVE_EPS_BEARERS_IS_AVAIABLE(__mME) \

View File

@ -138,8 +138,10 @@ typedef struct smf_ue_s {
do { \ do { \
smf_ue_t *smf_ue = NULL; \ smf_ue_t *smf_ue = NULL; \
ogs_assert(__sESS); \ ogs_assert(__sESS); \
smf_ue = __sESS->smf_ue; \ smf_ue = (__sESS)->smf_ue; \
ogs_assert(smf_ue); \ ogs_assert(smf_ue); \
smf_metrics_inst_by_slice_add(&(__sESS)->plmn_id, \
&(__sESS)->s_nssai, SMF_METR_GAUGE_SM_SESSIONNBR, -1); \
if (SMF_UE_IS_LAST_SESSION(smf_ue)) \ if (SMF_UE_IS_LAST_SESSION(smf_ue)) \
smf_ue_remove(smf_ue); \ smf_ue_remove(smf_ue); \
else \ else \

View File

@ -1830,8 +1830,6 @@ void smf_gsm_state_session_will_release(ogs_fsm_t *s, smf_event_t *e)
switch (e->h.id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
smf_metrics_inst_by_slice_add(&sess->plmn_id, &sess->s_nssai,
SMF_METR_GAUGE_SM_SESSIONNBR, -1);
SMF_SESS_CLEAR(sess); SMF_SESS_CLEAR(sess);
break; break;
@ -1862,8 +1860,6 @@ void smf_gsm_state_exception(ogs_fsm_t *s, smf_event_t *e)
switch (e->h.id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
ogs_error("[%s:%d] State machine exception", smf_ue->supi, sess->psi); ogs_error("[%s:%d] State machine exception", smf_ue->supi, sess->psi);
smf_metrics_inst_by_slice_add(&sess->plmn_id, &sess->s_nssai,
SMF_METR_GAUGE_SM_SESSIONNBR, -1);
SMF_SESS_CLEAR(sess); SMF_SESS_CLEAR(sess);
break; break;

View File

@ -713,13 +713,19 @@ bool smf_npcf_smpolicycontrol_handle_terminate_notify(
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream)); ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
memset(&param, 0, sizeof(param)); if (sess->policy_association_id) {
r = smf_sbi_discover_and_send( memset(&param, 0, sizeof(param));
OGS_SBI_SERVICE_TYPE_NPCF_SMPOLICYCONTROL, NULL, r = smf_sbi_discover_and_send(
smf_npcf_smpolicycontrol_build_delete, OGS_SBI_SERVICE_TYPE_NPCF_SMPOLICYCONTROL, NULL,
sess, NULL, OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED, &param); smf_npcf_smpolicycontrol_build_delete,
ogs_expect(r == OGS_OK); sess, NULL, OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED, &param);
ogs_assert(r != OGS_ERROR); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
} else {
ogs_error("[%s:%d] No PolicyAssociationId. Forcibly remove SESSION",
smf_ue->supi, sess->psi);
SMF_SESS_CLEAR(sess);
}
return true; return true;
} }

View File

@ -682,10 +682,12 @@ bool smf_nsmf_handle_update_sm_context(
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
} else { } else {
ogs_error("No PolicyAssociationId"); ogs_error("[%s:%d] No PolicyAssociationId. Forcibly remove SESSION",
smf_ue->supi, sess->psi);
smf_sbi_send_sm_context_update_error_log( smf_sbi_send_sm_context_update_error_log(
stream, OGS_SBI_HTTP_STATUS_NOT_FOUND, stream, OGS_SBI_HTTP_STATUS_NOT_FOUND,
"No PolicyAssociationId", NULL); "No PolicyAssociationId", NULL);
SMF_SESS_CLEAR(sess);
} }
} else if (SmContextUpdateData->serving_nf_id) { } else if (SmContextUpdateData->serving_nf_id) {
ogs_debug("Old serving_nf_id: %s, new serving_nf_id: %s", ogs_debug("Old serving_nf_id: %s, new serving_nf_id: %s",
@ -717,12 +719,15 @@ bool smf_nsmf_handle_release_sm_context(
{ {
int r; int r;
smf_npcf_smpolicycontrol_param_t param; smf_npcf_smpolicycontrol_param_t param;
smf_ue_t *smf_ue = NULL;
OpenAPI_sm_context_release_data_t *SmContextReleaseData = NULL; OpenAPI_sm_context_release_data_t *SmContextReleaseData = NULL;
ogs_assert(stream); ogs_assert(stream);
ogs_assert(message); ogs_assert(message);
ogs_assert(sess); ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
memset(&param, 0, sizeof(param)); memset(&param, 0, sizeof(param));
@ -774,11 +779,13 @@ bool smf_nsmf_handle_release_sm_context(
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
} else { } else {
ogs_error("No PolicyAssociationId"); ogs_error("[%s:%d] No PolicyAssociationId. Forcibly remove SESSION",
smf_ue->supi, sess->psi);
ogs_assert(true == ogs_assert(true ==
ogs_sbi_server_send_error( ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_NOT_FOUND, stream, OGS_SBI_HTTP_STATUS_NOT_FOUND,
NULL, "No PolicyAssociationId", NULL)); NULL, "No PolicyAssociationId", NULL));
SMF_SESS_CLEAR(sess);
} }
return true; return true;

View File

@ -499,30 +499,36 @@ static void reselect_upf(ogs_pfcp_node_t *node)
} }
ogs_list_for_each(&smf_self()->smf_ue_list, smf_ue) { ogs_list_for_each(&smf_self()->smf_ue_list, smf_ue) {
smf_sess_t *sess = NULL; smf_sess_t *sess = NULL, *next_sess = NULL;
ogs_assert(smf_ue);
ogs_list_for_each(&smf_ue->sess_list, sess) { ogs_list_for_each_safe(&smf_ue->sess_list, next_sess, sess) {
ogs_assert(sess);
if (node == sess->pfcp_node) { if (node == sess->pfcp_node) {
if (sess->epc) { if (sess->epc) {
ogs_error("[%s:%s] EPC restoration is not implemented", ogs_error("[%s:%s] EPC restoration is not implemented",
smf_ue->imsi_bcd, sess->session.name); smf_ue->imsi_bcd, sess->session.name);
} else { } else {
smf_npcf_smpolicycontrol_param_t param; if (sess->policy_association_id) {
smf_npcf_smpolicycontrol_param_t param;
ogs_info("[%s:%d] SMF-initiated Deletion", ogs_info("[%s:%d] SMF-initiated Deletion",
smf_ue->supi, sess->psi); smf_ue->supi, sess->psi);
ogs_assert(sess->sm_context_ref); ogs_assert(sess->sm_context_ref);
memset(&param, 0, sizeof(param)); memset(&param, 0, sizeof(param));
r = smf_sbi_discover_and_send( r = smf_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NPCF_SMPOLICYCONTROL, NULL, OGS_SBI_SERVICE_TYPE_NPCF_SMPOLICYCONTROL, NULL,
smf_npcf_smpolicycontrol_build_delete, smf_npcf_smpolicycontrol_build_delete,
sess, NULL, OGS_PFCP_DELETE_TRIGGER_SMF_INITIATED, sess, NULL,
&param); OGS_PFCP_DELETE_TRIGGER_SMF_INITIATED,
ogs_expect(r == OGS_OK); &param);
ogs_assert(r != OGS_ERROR); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
} else {
ogs_error("[%s:%d] No PolicyAssociationId. "
"Forcibly remove SESSION",
smf_ue->supi, sess->psi);
SMF_SESS_CLEAR(sess);
}
} }
} }
} }