[AMF] Network Initiated De-Register (#2014, #2021)

Resolved Network Initiated Implicit/Explicit De-Registration
This commit is contained in:
Sukchan Lee 2023-01-29 22:44:44 +09:00
parent 131ecb4a44
commit 8a6c36daca
9 changed files with 149 additions and 106 deletions

View File

@ -406,6 +406,24 @@ struct amf_ue_s {
/* SubscriptionId of Subscription to Data Change Notification to UDM */ /* SubscriptionId of Subscription to Data Change Notification to UDM */
char *data_change_subscription_id; char *data_change_subscription_id;
struct {
/*
* De-Registered Request
* De-Registered Accept
*/
bool n1_done;
/*
* Nudm_SDM_Unsubscribe
* PATCH Nudm_UECM/registration/amf-3gpp-access
* PDU Session Release
* N4 Release
* DELETE Nbpsf-management
* DELETE Npcf-am_policy-control
*/
bool sbi_done;
} explict_de_registered;
ogs_list_t sess_list; ogs_list_t sess_list;
}; };

View File

@ -283,8 +283,10 @@ ogs_pkbuf_t *gmm_build_de_registration_accept(amf_ue_t *amf_ue)
return nas_5gs_security_encode(amf_ue, &message); return nas_5gs_security_encode(amf_ue, &message);
} }
ogs_pkbuf_t *gmm_build_de_registration_request(amf_ue_t *amf_ue, ogs_pkbuf_t *gmm_build_de_registration_request(
OpenAPI_deregistration_reason_e dereg_reason) amf_ue_t *amf_ue,
OpenAPI_deregistration_reason_e dereg_reason,
ogs_nas_5gmm_cause_t gmm_cause)
{ {
ogs_nas_5gs_message_t message; ogs_nas_5gs_message_t message;
ogs_nas_5gs_deregistration_request_to_ue_t *dereg_req = ogs_nas_5gs_deregistration_request_to_ue_t *dereg_req =
@ -307,12 +309,11 @@ ogs_pkbuf_t *gmm_build_de_registration_request(amf_ue_t *amf_ue,
dereg_reason == OpenAPI_deregistration_reason_REREGISTRATION_REQUIRED; dereg_reason == OpenAPI_deregistration_reason_REREGISTRATION_REQUIRED;
dereg_req->de_registration_type.access_type = OGS_ACCESS_TYPE_3GPP; dereg_req->de_registration_type.access_type = OGS_ACCESS_TYPE_3GPP;
dereg_req->presencemask |= if (gmm_cause) {
OGS_NAS_5GS_DEREGISTRATION_REQUEST_TO_UE_5GMM_CAUSE_PRESENT; dereg_req->presencemask |=
dereg_req->gmm_cause = OGS_NAS_5GS_DEREGISTRATION_REQUEST_TO_UE_5GMM_CAUSE_PRESENT;
(dereg_reason == OpenAPI_deregistration_reason_REREGISTRATION_REQUIRED dereg_req->gmm_cause = gmm_cause;
? OGS_5GMM_CAUSE_IMPLICITLY_DE_REGISTERED }
: OGS_5GMM_CAUSE_5GS_SERVICES_NOT_ALLOWED);
return nas_5gs_security_encode(amf_ue, &message); return nas_5gs_security_encode(amf_ue, &message);
} }

View File

@ -34,8 +34,10 @@ ogs_pkbuf_t *gmm_build_service_reject(
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause); amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause);
ogs_pkbuf_t *gmm_build_de_registration_accept(amf_ue_t *amf_ue); ogs_pkbuf_t *gmm_build_de_registration_accept(amf_ue_t *amf_ue);
ogs_pkbuf_t *gmm_build_de_registration_request(amf_ue_t *amf_ue, ogs_pkbuf_t *gmm_build_de_registration_request(
OpenAPI_deregistration_reason_e dereg_reason); amf_ue_t *amf_ue,
OpenAPI_deregistration_reason_e dereg_reason,
ogs_nas_5gmm_cause_t gmm_cause);
ogs_pkbuf_t *gmm_build_identity_request(amf_ue_t *amf_ue); ogs_pkbuf_t *gmm_build_identity_request(amf_ue_t *amf_ue);
ogs_pkbuf_t *gmm_build_security_mode_command(amf_ue_t *amf_ue); ogs_pkbuf_t *gmm_build_security_mode_command(amf_ue_t *amf_ue);

View File

@ -115,7 +115,7 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
} else { } else {
amf_ue->t3522.retry_count++; amf_ue->t3522.retry_count++;
r = nas_5gs_send_de_registration_request(amf_ue, r = nas_5gs_send_de_registration_request(amf_ue,
OpenAPI_deregistration_reason_NULL); OpenAPI_deregistration_reason_NULL, 0);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR); ogs_assert(r != OGS_ERROR);
} }
@ -206,7 +206,10 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
amf_ue->data_change_subscription_id = NULL; amf_ue->data_change_subscription_id = NULL;
} }
if (state == AMF_NETWORK_INITIATED_DE_REGISTERED) { if (state ==
AMF_NETWORK_INITIATED_IMPLICIT_DE_REGISTERED ||
state ==
AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED) {
amf_sbi_send_release_all_sessions(amf_ue, state); amf_sbi_send_release_all_sessions(amf_ue, state);
if ((ogs_list_count(&amf_ue->sess_list) == 0) && if ((ogs_list_count(&amf_ue->sess_list) == 0) &&
(PCF_AM_POLICY_ASSOCIATED(amf_ue))) { (PCF_AM_POLICY_ASSOCIATED(amf_ue))) {
@ -292,10 +295,27 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
break; break;
CASE(OGS_SBI_HTTP_METHOD_DELETE) CASE(OGS_SBI_HTTP_METHOD_DELETE)
if (state == AMF_NETWORK_INITIATED_DE_REGISTERED) { if (state == AMF_NETWORK_INITIATED_IMPLICIT_DE_REGISTERED) {
ogs_warn("[%s] AMF-UE Context Removed", amf_ue->supi); ogs_warn("[%s] Implicit De-registered", amf_ue->supi);
OGS_FSM_TRAN(&amf_ue->sm, OGS_FSM_TRAN(&amf_ue->sm,
&gmm_state_ue_context_will_remove); &gmm_state_ue_context_will_remove);
} else if (state ==
AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED) {
ogs_warn("[%s] Explicit De-registered", amf_ue->supi);
amf_ue->explict_de_registered.sbi_done = true;
if (amf_ue->explict_de_registered.n1_done == true) {
r = ngap_send_ran_ue_context_release_command(
amf_ue->ran_ue,
NGAP_Cause_PR_misc,
NGAP_CauseMisc_om_intervention,
NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
}
} else { } else {
r = nas_5gs_send_de_registration_accept(amf_ue); r = nas_5gs_send_de_registration_accept(amf_ue);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@ -501,7 +521,9 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(true == amf_ue_sbi_discover_and_send( ogs_assert(true == amf_ue_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL, OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
amf_nudm_sdm_build_subscription_delete, amf_nudm_sdm_build_subscription_delete,
amf_ue, AMF_NETWORK_INITIATED_DE_REGISTERED, NULL)); amf_ue,
AMF_NETWORK_INITIATED_IMPLICIT_DE_REGISTERED, NULL));
OGS_FSM_TRAN(s, &gmm_state_de_registered); OGS_FSM_TRAN(s, &gmm_state_de_registered);
break; break;
default: default:
@ -740,16 +762,15 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
ogs_info("[%s] Deregistration accept", amf_ue->supi); ogs_info("[%s] Deregistration accept", amf_ue->supi);
CLEAR_AMF_UE_TIMER(amf_ue->t3522); CLEAR_AMF_UE_TIMER(amf_ue->t3522);
/* De-associate NG with NAS/EMM */ amf_ue->explict_de_registered.n1_done = true;
ran_ue_deassociate(amf_ue->ran_ue);
r = ngap_send_ran_ue_context_release_command(amf_ue->ran_ue, if (amf_ue->explict_de_registered.sbi_done == true) {
NGAP_Cause_PR_misc, NGAP_CauseMisc_om_intervention, r = ngap_send_ran_ue_context_release_command(amf_ue->ran_ue,
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0); NGAP_Cause_PR_misc, NGAP_CauseMisc_om_intervention,
ogs_expect(r == OGS_OK); NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
ogs_assert(r != OGS_ERROR); ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
OGS_FSM_TRAN(s, &gmm_state_de_registered); }
break; break;
case OGS_NAS_5GS_CONFIGURATION_UPDATE_COMPLETE: case OGS_NAS_5GS_CONFIGURATION_UPDATE_COMPLETE:

View File

@ -518,47 +518,10 @@ cleanup:
return OGS_OK; return OGS_OK;
} }
static int do_network_initiated_de_register(
amf_ue_t *amf_ue, OpenAPI_deregistration_reason_e dereg_reason)
{
int r;
if ((CM_CONNECTED(amf_ue)) &&
(OGS_FSM_CHECK(&amf_ue->sm, gmm_state_registered))) {
r = nas_5gs_send_de_registration_request(amf_ue, dereg_reason);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
amf_sbi_send_release_all_sessions(
amf_ue, AMF_NETWORK_INITIATED_DE_REGISTERED);
if ((ogs_list_count(&amf_ue->sess_list) == 0) &&
(PCF_AM_POLICY_ASSOCIATED(amf_ue))) {
ogs_assert(true ==
amf_ue_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, NULL,
amf_npcf_am_policy_control_build_delete,
amf_ue, AMF_NETWORK_INITIATED_DE_REGISTERED, NULL));
}
OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_de_registered);
return OGS_OK;
} else if (CM_IDLE(amf_ue)) {
/* TODO: need to page UE */
ogs_error("Not implemented : need to page UE");
return OGS_ERROR;
} else {
ogs_fatal("Invalid State");
ogs_assert_if_reached();
return OGS_ERROR;
}
}
int amf_namf_callback_handle_dereg_notify( int amf_namf_callback_handle_dereg_notify(
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{ {
int status = OGS_SBI_HTTP_STATUS_NO_CONTENT; int r, status = OGS_SBI_HTTP_STATUS_NO_CONTENT;
amf_ue_t *amf_ue = NULL; amf_ue_t *amf_ue = NULL;
@ -609,13 +572,30 @@ int amf_namf_callback_handle_dereg_notify(
* Deregistration procedure. In this case, the AMF performs network requested PDU Session Release for any PDU * Deregistration procedure. In this case, the AMF performs network requested PDU Session Release for any PDU
* session associated with non-emergency service as described in clause 4.3.4. * session associated with non-emergency service as described in clause 4.3.4.
*/ */
if (CM_CONNECTED(amf_ue)) {
r = nas_5gs_send_de_registration_request(
amf_ue,
DeregistrationData->dereg_reason,
OGS_5GMM_CAUSE_5GS_SERVICES_NOT_ALLOWED);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
if (do_network_initiated_de_register( ogs_assert(true == amf_ue_sbi_discover_and_send(
amf_ue, DeregistrationData->dereg_reason) != OGS_OK) { OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; amf_nudm_sdm_build_subscription_delete,
ogs_error("[%s] Deregistration notification for UE in wrong state", amf_ue,
amf_ue->supi); AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED, NULL));
goto cleanup; } else if (CM_IDLE(amf_ue)) {
ogs_error("Not implemented : Use Implicit De-registration");
ogs_assert(true == amf_ue_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
amf_nudm_sdm_build_subscription_delete,
amf_ue,
AMF_NETWORK_INITIATED_IMPLICIT_DE_REGISTERED, NULL));
} else {
ogs_fatal("Invalid State");
ogs_assert_if_reached();
} }
cleanup: cleanup:
@ -900,17 +880,31 @@ int amf_namf_callback_handle_sdm_data_change_notify(
} }
if (amf_ue_is_rat_restricted(amf_ue)) { if (amf_ue_is_rat_restricted(amf_ue)) {
if (do_network_initiated_de_register(amf_ue, if (CM_CONNECTED(amf_ue)) {
OpenAPI_deregistration_reason_REREGISTRATION_REQUIRED) != OGS_OK) { r = nas_5gs_send_de_registration_request(
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; amf_ue,
ogs_error("[%s] Deregistration notification for UE in wrong state", OpenAPI_deregistration_reason_REREGISTRATION_REQUIRED, 0);
amf_ue->supi); ogs_expect(r == OGS_OK);
goto cleanup; ogs_assert(r != OGS_ERROR);
}
ogs_assert(true == ogs_assert(true == amf_ue_sbi_discover_and_send(
amf_ue_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL, OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
amf_nudm_sdm_build_subscription_delete, amf_ue, 0, NULL)); amf_nudm_sdm_build_subscription_delete,
amf_ue,
AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED, NULL));
} else if (CM_IDLE(amf_ue)) {
ogs_error("Not implemented : Use Implicit De-registration");
ogs_assert(true == amf_ue_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
amf_nudm_sdm_build_subscription_delete,
amf_ue,
AMF_NETWORK_INITIATED_IMPLICIT_DE_REGISTERED, NULL));
} else {
ogs_fatal("Invalid State");
ogs_assert_if_reached();
}
} else if (ambr_changed) { } else if (ambr_changed) {
ogs_pkbuf_t *ngapbuf; ogs_pkbuf_t *ngapbuf;

View File

@ -344,8 +344,10 @@ int nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue)
return rv; return rv;
} }
int nas_5gs_send_de_registration_request(amf_ue_t *amf_ue, int nas_5gs_send_de_registration_request(
OpenAPI_deregistration_reason_e dereg_reason) amf_ue_t *amf_ue,
OpenAPI_deregistration_reason_e dereg_reason,
ogs_nas_5gmm_cause_t gmm_cause)
{ {
int rv; int rv;
@ -364,7 +366,8 @@ int nas_5gs_send_de_registration_request(amf_ue_t *amf_ue,
if (amf_ue->t3522.pkbuf) { if (amf_ue->t3522.pkbuf) {
gmmbuf = amf_ue->t3522.pkbuf; gmmbuf = amf_ue->t3522.pkbuf;
} else { } else {
gmmbuf = gmm_build_de_registration_request(amf_ue, dereg_reason); gmmbuf = gmm_build_de_registration_request(
amf_ue, dereg_reason, gmm_cause);
if (!gmmbuf) { if (!gmmbuf) {
ogs_error("gmm_build_de_registration_request() failed"); ogs_error("gmm_build_de_registration_request() failed");
return OGS_ERROR; return OGS_ERROR;

View File

@ -41,8 +41,10 @@ int nas_5gs_send_service_reject(
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause); amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause);
int nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue); int nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue);
int nas_5gs_send_de_registration_request(amf_ue_t *amf_ue, int nas_5gs_send_de_registration_request(
OpenAPI_deregistration_reason_e dereg_reason); amf_ue_t *amf_ue,
OpenAPI_deregistration_reason_e dereg_reason,
ogs_nas_5gmm_cause_t gmm_cause);
int nas_5gs_send_identity_request(amf_ue_t *amf_ue); int nas_5gs_send_identity_request(amf_ue_t *amf_ue);

View File

@ -911,7 +911,8 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state)
ogs_assert_if_reached(); ogs_assert_if_reached();
} else if (state == AMF_RELEASE_SM_CONTEXT_NO_STATE || } else if (state == AMF_RELEASE_SM_CONTEXT_NO_STATE ||
state == AMF_NETWORK_INITIATED_DE_REGISTERED) { state == AMF_NETWORK_INITIATED_IMPLICIT_DE_REGISTERED ||
state == AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED) {
/* NO_STATE */ /* NO_STATE */
if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_authentication)) { if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_authentication)) {

View File

@ -37,31 +37,32 @@ void amf_sbi_close(void);
bool amf_sbi_send_request( bool amf_sbi_send_request(
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact); ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
#define AMF_CREATE_SM_CONTEXT_NO_STATE 0 #define AMF_CREATE_SM_CONTEXT_NO_STATE 0
#define AMF_NETWORK_INITIATED_DE_REGISTERED 1 #define AMF_NETWORK_INITIATED_IMPLICIT_DE_REGISTERED 1
#define AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED 2
#define AMF_UPDATE_SM_CONTEXT_ACTIVATED 11 #define AMF_UPDATE_SM_CONTEXT_ACTIVATED 11
#define AMF_UPDATE_SM_CONTEXT_SETUP_FAIL 12 #define AMF_UPDATE_SM_CONTEXT_SETUP_FAIL 12
#define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 13 #define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 13
#define AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST 14 #define AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST 14
#define AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST 15 #define AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST 15
#define AMF_UPDATE_SM_CONTEXT_MODIFIED 16 #define AMF_UPDATE_SM_CONTEXT_MODIFIED 16
#define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 17 #define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 17
#define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 18 #define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 18
#define AMF_UPDATE_SM_CONTEXT_DUPLICATED_PDU_SESSION_ID 19 #define AMF_UPDATE_SM_CONTEXT_DUPLICATED_PDU_SESSION_ID 19
#define AMF_UPDATE_SM_CONTEXT_PATH_SWITCH_REQUEST 20 #define AMF_UPDATE_SM_CONTEXT_PATH_SWITCH_REQUEST 20
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_REQUIRED 21 #define AMF_UPDATE_SM_CONTEXT_HANDOVER_REQUIRED 21
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_REQ_ACK 22 #define AMF_UPDATE_SM_CONTEXT_HANDOVER_REQ_ACK 22
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_NOTIFY 23 #define AMF_UPDATE_SM_CONTEXT_HANDOVER_NOTIFY 23
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_CANCEL 24 #define AMF_UPDATE_SM_CONTEXT_HANDOVER_CANCEL 24
#define AMF_RELEASE_SM_CONTEXT_NO_STATE 31 #define AMF_RELEASE_SM_CONTEXT_NO_STATE 31
#define AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE 32 #define AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE 32
#define AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT 33 #define AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT 33
#define AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT 34 #define AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT 34
#define AMF_REMOVE_S1_CONTEXT_BY_LO_CONNREFUSED 51 #define AMF_REMOVE_S1_CONTEXT_BY_LO_CONNREFUSED 51
#define AMF_REMOVE_S1_CONTEXT_BY_RESET_ALL 52 #define AMF_REMOVE_S1_CONTEXT_BY_RESET_ALL 52
#define AMF_REMOVE_S1_CONTEXT_BY_RESET_PARTIAL 53 #define AMF_REMOVE_S1_CONTEXT_BY_RESET_PARTIAL 53
bool amf_ue_sbi_discover_and_send( bool amf_ue_sbi_discover_and_send(
ogs_sbi_service_type_e service_type, ogs_sbi_service_type_e service_type,