[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 */
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;
};

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);
}
ogs_pkbuf_t *gmm_build_de_registration_request(amf_ue_t *amf_ue,
OpenAPI_deregistration_reason_e dereg_reason)
ogs_pkbuf_t *gmm_build_de_registration_request(
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_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_req->de_registration_type.access_type = OGS_ACCESS_TYPE_3GPP;
dereg_req->presencemask |=
OGS_NAS_5GS_DEREGISTRATION_REQUEST_TO_UE_5GMM_CAUSE_PRESENT;
dereg_req->gmm_cause =
(dereg_reason == OpenAPI_deregistration_reason_REREGISTRATION_REQUIRED
? OGS_5GMM_CAUSE_IMPLICITLY_DE_REGISTERED
: OGS_5GMM_CAUSE_5GS_SERVICES_NOT_ALLOWED);
if (gmm_cause) {
dereg_req->presencemask |=
OGS_NAS_5GS_DEREGISTRATION_REQUEST_TO_UE_5GMM_CAUSE_PRESENT;
dereg_req->gmm_cause = gmm_cause;
}
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);
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,
OpenAPI_deregistration_reason_e dereg_reason);
ogs_pkbuf_t *gmm_build_de_registration_request(
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_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 {
amf_ue->t3522.retry_count++;
r = nas_5gs_send_de_registration_request(amf_ue,
OpenAPI_deregistration_reason_NULL);
OpenAPI_deregistration_reason_NULL, 0);
ogs_expect(r == OGS_OK);
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;
}
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);
if ((ogs_list_count(&amf_ue->sess_list) == 0) &&
(PCF_AM_POLICY_ASSOCIATED(amf_ue))) {
@ -292,10 +295,27 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
break;
CASE(OGS_SBI_HTTP_METHOD_DELETE)
if (state == AMF_NETWORK_INITIATED_DE_REGISTERED) {
ogs_warn("[%s] AMF-UE Context Removed", amf_ue->supi);
if (state == AMF_NETWORK_INITIATED_IMPLICIT_DE_REGISTERED) {
ogs_warn("[%s] Implicit De-registered", amf_ue->supi);
OGS_FSM_TRAN(&amf_ue->sm,
&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 {
r = nas_5gs_send_de_registration_accept(amf_ue);
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_SBI_SERVICE_TYPE_NUDM_SDM, NULL,
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);
break;
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);
CLEAR_AMF_UE_TIMER(amf_ue->t3522);
/* De-associate NG with NAS/EMM */
ran_ue_deassociate(amf_ue->ran_ue);
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_NG_CONTEXT_REMOVE, 0);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
OGS_FSM_TRAN(s, &gmm_state_de_registered);
if (amf_ue->explict_de_registered.sbi_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);
}
break;
case OGS_NAS_5GS_CONFIGURATION_UPDATE_COMPLETE:

View File

@ -518,47 +518,10 @@ cleanup:
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(
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;
@ -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
* 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(
amf_ue, DeregistrationData->dereg_reason) != OGS_OK) {
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
ogs_error("[%s] Deregistration notification for UE in wrong state",
amf_ue->supi);
goto cleanup;
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_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();
}
cleanup:
@ -900,17 +880,31 @@ int amf_namf_callback_handle_sdm_data_change_notify(
}
if (amf_ue_is_rat_restricted(amf_ue)) {
if (do_network_initiated_de_register(amf_ue,
OpenAPI_deregistration_reason_REREGISTRATION_REQUIRED) != OGS_OK) {
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
ogs_error("[%s] Deregistration notification for UE in wrong state",
amf_ue->supi);
goto cleanup;
}
ogs_assert(true ==
amf_ue_sbi_discover_and_send(
if (CM_CONNECTED(amf_ue)) {
r = nas_5gs_send_de_registration_request(
amf_ue,
OpenAPI_deregistration_reason_REREGISTRATION_REQUIRED, 0);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
ogs_assert(true == amf_ue_sbi_discover_and_send(
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) {
ogs_pkbuf_t *ngapbuf;

View File

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

View File

@ -911,7 +911,8 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state)
ogs_assert_if_reached();
} 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 */
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(
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_SETUP_FAIL 12
#define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 13
#define AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST 14
#define AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST 15
#define AMF_UPDATE_SM_CONTEXT_MODIFIED 16
#define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 17
#define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 18
#define AMF_UPDATE_SM_CONTEXT_ACTIVATED 11
#define AMF_UPDATE_SM_CONTEXT_SETUP_FAIL 12
#define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 13
#define AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST 14
#define AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST 15
#define AMF_UPDATE_SM_CONTEXT_MODIFIED 16
#define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 17
#define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 18
#define AMF_UPDATE_SM_CONTEXT_DUPLICATED_PDU_SESSION_ID 19
#define AMF_UPDATE_SM_CONTEXT_PATH_SWITCH_REQUEST 20
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_REQUIRED 21
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_REQ_ACK 22
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_NOTIFY 23
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_CANCEL 24
#define AMF_RELEASE_SM_CONTEXT_NO_STATE 31
#define AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE 32
#define AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT 33
#define AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT 34
#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_PARTIAL 53
#define AMF_UPDATE_SM_CONTEXT_PATH_SWITCH_REQUEST 20
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_REQUIRED 21
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_REQ_ACK 22
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_NOTIFY 23
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_CANCEL 24
#define AMF_RELEASE_SM_CONTEXT_NO_STATE 31
#define AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE 32
#define AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT 33
#define AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT 34
#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_PARTIAL 53
bool amf_ue_sbi_discover_and_send(
ogs_sbi_service_type_e service_type,