From 817007d0aef0d0ae53e506298d71c4476c118b0c Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Sun, 4 Dec 2022 14:32:19 +0900 Subject: [PATCH] [AMF] Wrongly sending PDU Session Release (#1925) --- src/amf/context.h | 4 + src/amf/namf-handler.c | 69 ++--- src/amf/nas-path.c | 197 ++++++++++++-- src/amf/nas-path.h | 3 +- src/amf/ngap-handler.c | 28 +- src/amf/ngap-path.c | 37 --- src/amf/ngap-path.h | 2 - tests/registration/crash-test.c | 3 + tests/registration/dereg-test.c | 388 +++++++++++++++++++++++++++ tests/registration/paging-test.c | 3 + tests/registration/ue-context-test.c | 6 + tests/vonr/af-test.c | 9 + tests/vonr/session-test.c | 3 + 13 files changed, 636 insertions(+), 116 deletions(-) diff --git a/src/amf/context.h b/src/amf/context.h index 2317e17fd..32403fbba 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -196,6 +196,10 @@ struct ran_ue_s { bool part_of_ng_reset_requested; + struct { + uint16_t activated; /* Activated PSI Mask */ + } psimask; + /* Related Context */ amf_gnb_t *gnb; amf_ue_t *amf_ue; diff --git a/src/amf/namf-handler.c b/src/amf/namf-handler.c index 474d07d40..f4fdb743a 100644 --- a/src/amf/namf-handler.c +++ b/src/amf/namf-handler.c @@ -30,6 +30,7 @@ int amf_namf_comm_handle_n1_n2_message_transfer( int status; amf_ue_t *amf_ue = NULL; + ran_ue_t *ran_ue = NULL; amf_sess_t *sess = NULL; ogs_pkbuf_t *n1buf = NULL; @@ -172,33 +173,31 @@ int amf_namf_comm_handle_n1_n2_message_transfer( } if (gmmbuf) { - ran_ue_t *ran_ue = NULL; - /*********************************** * 4.3.2 PDU Session Establishment * ***********************************/ ran_ue = ran_ue_cycle(amf_ue->ran_ue); - ogs_assert(ran_ue); + if (ran_ue) { + if (sess->pdu_session_establishment_accept) { + ogs_pkbuf_free(sess->pdu_session_establishment_accept); + sess->pdu_session_establishment_accept = NULL; + } - if (sess->pdu_session_establishment_accept) { - ogs_pkbuf_free(sess->pdu_session_establishment_accept); - sess->pdu_session_establishment_accept = NULL; - } + if (ran_ue->initial_context_setup_request_sent == true) { + ngapbuf = + ngap_sess_build_pdu_session_resource_setup_request( + sess, gmmbuf, n2buf); + ogs_assert(ngapbuf); + } else { + ngapbuf = ngap_sess_build_initial_context_setup_request( + sess, gmmbuf, n2buf); + ogs_assert(ngapbuf); - if (ran_ue->initial_context_setup_request_sent == true) { - ngapbuf = ngap_sess_build_pdu_session_resource_setup_request( - sess, gmmbuf, n2buf); - ogs_assert(ngapbuf); - } else { - ngapbuf = ngap_sess_build_initial_context_setup_request( - sess, gmmbuf, n2buf); - ogs_assert(ngapbuf); + ran_ue->initial_context_setup_request_sent = true; + } - ran_ue->initial_context_setup_request_sent = true; - } - - if (SESSION_CONTEXT_IN_SMF(sess)) { + if (SESSION_CONTEXT_IN_SMF(sess)) { /* * [1-CLIENT] /nsmf-pdusession/v1/sm-contexts * [2-SERVER] /namf-comm/v1/ue-contexts/{supi}/n1-n2-messages @@ -207,10 +206,13 @@ int amf_namf_comm_handle_n1_n2_message_transfer( * sm-context-ref is created in [1-CLIENT]. * So, the PDU session establishment accpet can be transmitted. */ - if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK) - ogs_error("nas_5gs_send_to_gnb() failed"); + ogs_expect(OGS_OK == ngap_send_to_ran_ue(ran_ue, ngapbuf)); + } else { + sess->pdu_session_establishment_accept = ngapbuf; + } } else { - sess->pdu_session_establishment_accept = ngapbuf; + ogs_warn("[%s] RAN-NG Context has already been removed", + amf_ue->supi); } } else { @@ -283,7 +285,7 @@ int amf_namf_comm_handle_n1_n2_message_transfer( } else if (CM_CONNECTED(amf_ue)) { ogs_assert(OGS_OK == - ngap_send_pdu_resource_setup_request(sess, n2buf)); + nas_send_pdu_session_setup_request(sess, NULL, n2buf)); } else { @@ -341,16 +343,8 @@ int amf_namf_comm_handle_n1_n2_message_transfer( ogs_assert(OGS_OK == ngap_send_paging(amf_ue)); } else if (CM_CONNECTED(amf_ue)) { - gmmbuf = gmm_build_dl_nas_transport(sess, - OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1buf, 0, 0); - ogs_assert(gmmbuf); - - ngapbuf = ngap_build_pdu_session_resource_modify_request( - sess, gmmbuf, n2buf); - ogs_assert(ngapbuf); - - if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK) - ogs_error("nas_5gs_send_to_gnb() failed"); + ogs_expect(OGS_OK == + nas_send_pdu_session_modification_command(sess, n1buf, n2buf)); } else { ogs_fatal("[%s] Invalid AMF-UE state", amf_ue->supi); @@ -382,13 +376,8 @@ int amf_namf_comm_handle_n1_n2_message_transfer( } } else if (CM_CONNECTED(amf_ue)) { - ngapbuf = ngap_build_pdu_session_resource_release_command( - sess, NULL, n2buf); - ogs_assert(ngapbuf); - - if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK) - ogs_error("nas_5gs_send_to_gnb() failed"); - + ogs_expect(OGS_OK == + nas_send_pdu_session_release_command(sess, NULL, n2buf)); } else { ogs_fatal("[%s] Invalid AMF-UE state", amf_ue->supi); ogs_assert_if_reached(); diff --git a/src/amf/nas-path.c b/src/amf/nas-path.c index f7b110b55..a30420350 100644 --- a/src/amf/nas-path.c +++ b/src/amf/nas-path.c @@ -458,29 +458,129 @@ int nas_5gs_send_configuration_update_command( return rv; } +int nas_send_pdu_session_setup_request(amf_sess_t *sess, + ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf) +{ + int rv; + + amf_ue_t *amf_ue = NULL; + ran_ue_t *ran_ue = NULL; + + ogs_pkbuf_t *gmmbuf = NULL; + ogs_pkbuf_t *ngapbuf = NULL; + + ogs_assert(sess); + amf_ue = amf_ue_cycle(sess->amf_ue); + if (!amf_ue) { + ogs_warn("UE(amf-ue) context has already been removed"); + if (n1smbuf) ogs_pkbuf_free(n1smbuf); + ogs_pkbuf_free(n2smbuf); + return OGS_ERROR; + } + ran_ue = ran_ue_cycle(amf_ue->ran_ue); + if (!ran_ue) { + ogs_warn("NG context has already been removed"); + if (n1smbuf) ogs_pkbuf_free(n1smbuf); + ogs_pkbuf_free(n2smbuf); + return OGS_ERROR; + } + + if (n1smbuf) { + gmmbuf = gmm_build_dl_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0); + if (!gmmbuf) { + ogs_error("gmm_build_dl_nas_transport() failed"); + return OGS_ERROR; + } + } + + if (ran_ue->ue_context_requested == true && + ran_ue->initial_context_setup_request_sent == false) { + ngapbuf = ngap_sess_build_initial_context_setup_request( + sess, gmmbuf, n2smbuf); + if (!ngapbuf) { + ogs_error("ngap_sess_build_initial_context_setup_request() failed"); + return OGS_ERROR; + } + + rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf); + if (rv != OGS_OK) { + ogs_error("nas_5gs_send_to_gnb() failed"); + return OGS_ERROR; + } + + ran_ue->initial_context_setup_request_sent = true; + } else { + ngapbuf = ngap_sess_build_pdu_session_resource_setup_request( + sess, gmmbuf, n2smbuf); + if (!ngapbuf) { + ogs_error("ngap_sess_build_initial_context_setup_request() failed"); + return OGS_ERROR; + } + + rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf); + if (rv != OGS_OK) { + ogs_error("nas_5gs_send_to_gnb() failed"); + return OGS_ERROR; + } + } + + return rv; +} + int nas_send_pdu_session_modification_command(amf_sess_t *sess, ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf) { int rv; amf_ue_t *amf_ue = NULL; + ran_ue_t *ran_ue = NULL; ogs_pkbuf_t *gmmbuf = NULL; ogs_pkbuf_t *ngapbuf = NULL; ogs_assert(sess); - amf_ue = sess->amf_ue; - ogs_assert(amf_ue); - ogs_assert(n1smbuf); - ogs_assert(n2smbuf); + amf_ue = amf_ue_cycle(sess->amf_ue); + if (!amf_ue) { + ogs_warn("UE(amf-ue) context has already been removed"); + if (n1smbuf) ogs_pkbuf_free(n1smbuf); + ogs_pkbuf_free(n2smbuf); + return OGS_ERROR; + } + ran_ue = ran_ue_cycle(amf_ue->ran_ue); + if (!ran_ue) { + ogs_warn("NG context has already been removed"); + if (n1smbuf) ogs_pkbuf_free(n1smbuf); + ogs_pkbuf_free(n2smbuf); + return OGS_ERROR; + } - gmmbuf = gmm_build_dl_nas_transport(sess, - OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0); - ogs_expect_or_return_val(gmmbuf, OGS_ERROR); + if (n1smbuf) { + gmmbuf = gmm_build_dl_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0); + if (!gmmbuf) { + ogs_error("gmm_build_dl_nas_transport() failed"); + return OGS_ERROR; + } + } + /* + * Issues #1925 + * + * We should not check an activated PSI mask to send DownlinkNASTransport. + * + * PDUSessionResourceModifyRequest needs to activate QoSFlow with + * AddOrModifyQosFlow in the message. + * + * So, we should always use PDUSessionResourceModifyRequest instead of + * send with DownlinkNASTransport. + */ ngapbuf = ngap_build_pdu_session_resource_modify_request( sess, gmmbuf, n2smbuf); - ogs_expect_or_return_val(ngapbuf, OGS_ERROR); + if (!ngapbuf) { + ogs_error("ngap_build_pdu_session_resource_modify_request() failed"); + return OGS_ERROR; + } rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf); ogs_expect(rv == OGS_OK); @@ -488,33 +588,88 @@ int nas_send_pdu_session_modification_command(amf_sess_t *sess, return rv; } - int nas_send_pdu_session_release_command(amf_sess_t *sess, ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf) { int rv; amf_ue_t *amf_ue = NULL; + ran_ue_t *ran_ue = NULL; ogs_pkbuf_t *gmmbuf = NULL; ogs_pkbuf_t *ngapbuf = NULL; - ogs_assert(sess); - amf_ue = sess->amf_ue; - ogs_assert(amf_ue); - ogs_assert(n1smbuf); ogs_assert(n2smbuf); + ogs_assert(sess); + amf_ue = amf_ue_cycle(sess->amf_ue); + if (!amf_ue) { + ogs_warn("UE(amf-ue) context has already been removed"); + if (n1smbuf) ogs_pkbuf_free(n1smbuf); + ogs_pkbuf_free(n2smbuf); + return OGS_ERROR; + } + ran_ue = ran_ue_cycle(amf_ue->ran_ue); + if (!ran_ue) { + ogs_warn("NG context has already been removed"); + if (n1smbuf) ogs_pkbuf_free(n1smbuf); + ogs_pkbuf_free(n2smbuf); + return OGS_ERROR; + } - gmmbuf = gmm_build_dl_nas_transport(sess, - OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0); - ogs_expect_or_return_val(gmmbuf, OGS_ERROR); + if (n1smbuf) { + gmmbuf = gmm_build_dl_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0); + if (!gmmbuf) { + ogs_error("gmm_build_dl_nas_transport() failed"); + return OGS_ERROR; + } + } - ngapbuf = ngap_build_pdu_session_resource_release_command( - sess, gmmbuf, n2smbuf); - ogs_expect_or_return_val(ngapbuf, OGS_ERROR); + /* + * Issues #1925 + * + * We should CHECK an activated PSI mask to send DownlinkNASTransport. + * + * - RAN removed the PDU Session Resource in the following process.. + * 1. UEContextReleaseRequest + * 2. UEContextReleaseCommand + * 3. UEContextReleaseComplete. + * + * - If Service Request has no UpdateDataStatus while waking up UE, + * 1. ServiceRequest + * 2. InitialContextSetupRequest + * 3. InitialContextSetupResponse + * + * - In this case, we should use the DownlinkNASTransport. + * instead of PDUSessionResourceReleaseCommand + */ + if (ran_ue->psimask.activated & (1 << sess->psi)) { + ngapbuf = ngap_build_pdu_session_resource_release_command( + sess, gmmbuf, n2smbuf); + if (!ngapbuf) { + ogs_error( + "ngap_build_pdu_session_resource_release_command() failed"); + return OGS_ERROR; + } - rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf); - ogs_expect(rv == OGS_OK); + rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf); + ogs_expect(rv == OGS_OK); + } else if (gmmbuf) { + ngapbuf = ngap_build_downlink_nas_transport( + ran_ue, gmmbuf, false, false); + if (!ngapbuf) { + ogs_error("ngap_build_downlink_nas_transport() failed"); + return OGS_ERROR; + } + + rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf); + ogs_expect(rv == OGS_OK); + } else { + ogs_error("ngap_build_pdu_session_resource_release_command() failed"); + ogs_error(" ACTIVATED[0x%x] SUPI[%s] PSI[%d]", + ran_ue->psimask.activated, amf_ue->supi, sess->psi); + return OGS_ERROR; + } return rv; } diff --git a/src/amf/nas-path.h b/src/amf/nas-path.h index f582a67c1..bf8848041 100644 --- a/src/amf/nas-path.h +++ b/src/amf/nas-path.h @@ -54,9 +54,10 @@ int nas_5gs_send_security_mode_command(amf_ue_t *amf_ue); int nas_5gs_send_configuration_update_command( amf_ue_t *amf_ue, gmm_configuration_update_command_param_t *param); +int nas_send_pdu_session_setup_request(amf_sess_t *sess, + ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf); int nas_send_pdu_session_modification_command(amf_sess_t *sess, ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf); - int nas_send_pdu_session_release_command(amf_sess_t *sess, ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf); diff --git a/src/amf/ngap-handler.c b/src/amf/ngap-handler.c index d45584d2f..e5a04e6cd 100644 --- a/src/amf/ngap-handler.c +++ b/src/amf/ngap-handler.c @@ -903,6 +903,11 @@ void ngap_handle_initial_context_setup_response( return; } + ogs_debug(" SUPI[%s] PSI[%d] OLD ACTIVATED[0x%x]", + amf_ue->supi, sess->psi, ran_ue->psimask.activated); + ran_ue->psimask.activated |= ((1 << sess->psi)); + ogs_debug(" NEW ACTIVATED[0x%x]", ran_ue->psimask.activated); + memset(¶m, 0, sizeof(param)); param.n2smbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN); ogs_assert(param.n2smbuf); @@ -941,26 +946,14 @@ void ngap_handle_initial_context_setup_response( * after the transport of the 5GSM downlink signalling. */ ogs_list_for_each(&amf_ue->sess_list, sess) { - ogs_pkbuf_t *ngapbuf = NULL; - ogs_pkbuf_t *gmmbuf = NULL; - /* There is no Downlink Signalling Pending in this sesssion */ if (sess->gsm_message.type == 0) continue; switch (sess->gsm_message.type) { case OGS_NAS_5GS_PDU_SESSION_MODIFICATION_COMMAND: - gmmbuf = gmm_build_dl_nas_transport(sess, - OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, - sess->gsm_message.n1buf, 0, 0); - ogs_assert(gmmbuf); - - ngapbuf = ngap_build_pdu_session_resource_modify_request( - sess, gmmbuf, sess->gsm_message.n2buf); - ogs_assert(ngapbuf); - - if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK) { - ogs_error("nas_5gs_send_to_gnb() failed"); - } + ogs_expect(OGS_OK == + nas_send_pdu_session_modification_command(sess, + sess->gsm_message.n1buf, sess->gsm_message.n2buf)); /* n1buf is de-allocated * in gmm_build_dl_nas_transport() */ @@ -1797,6 +1790,11 @@ void ngap_handle_pdu_session_resource_setup_response( return; } + ogs_debug(" SUPI[%s] PSI[%d] OLD ACTIVATED[0x%x]", + amf_ue->supi, sess->psi, ran_ue->psimask.activated); + ran_ue->psimask.activated |= ((1 << sess->psi)); + ogs_debug(" NEW ACTIVATED[0x%x]", ran_ue->psimask.activated); + memset(¶m, 0, sizeof(param)); param.n2smbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN); ogs_assert(param.n2smbuf); diff --git a/src/amf/ngap-path.c b/src/amf/ngap-path.c index 532881421..07c5e0307 100644 --- a/src/amf/ngap-path.c +++ b/src/amf/ngap-path.c @@ -400,43 +400,6 @@ int ngap_send_paging(amf_ue_t *amf_ue) return OGS_OK; } -int ngap_send_pdu_resource_setup_request( - amf_sess_t *sess, ogs_pkbuf_t *n2smbuf) -{ - int rv; - ran_ue_t *ran_ue = NULL; - amf_ue_t *amf_ue = NULL; - - ogs_pkbuf_t *ngapbuf = NULL; - - ogs_assert(sess); - amf_ue = sess->amf_ue; - ogs_assert(amf_ue); - ran_ue = ran_ue_cycle(amf_ue->ran_ue); - ogs_assert(ran_ue); - - if (ran_ue->ue_context_requested == true && - ran_ue->initial_context_setup_request_sent == false) { - ngapbuf = ngap_sess_build_initial_context_setup_request( - sess, NULL, n2smbuf); - ogs_expect_or_return_val(ngapbuf, OGS_ERROR); - - rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf); - ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR); - - ran_ue->initial_context_setup_request_sent = true; - } else { - ngapbuf = ngap_sess_build_pdu_session_resource_setup_request( - sess, NULL, n2smbuf); - ogs_expect_or_return_val(ngapbuf, OGS_ERROR); - - rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf); - ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR); - } - - return OGS_OK; -} - int ngap_send_downlink_ran_configuration_transfer( amf_gnb_t *target_gnb, NGAP_SONConfigurationTransfer_t *transfer) { diff --git a/src/amf/ngap-path.h b/src/amf/ngap-path.h index a05a7271e..1ad54ef9e 100644 --- a/src/amf/ngap-path.h +++ b/src/amf/ngap-path.h @@ -62,8 +62,6 @@ int ngap_send_amf_ue_context_release_command( uint8_t action, ogs_time_t duration); int ngap_send_paging(amf_ue_t *amf_ue); -int ngap_send_pdu_resource_setup_request( - amf_sess_t *sess, ogs_pkbuf_t *n2smbuf); int ngap_send_downlink_ran_configuration_transfer( amf_gnb_t *target_gnb, NGAP_SONConfigurationTransfer_t *transfer); diff --git a/tests/registration/crash-test.c b/tests/registration/crash-test.c index 84279cb21..6e1643db7 100644 --- a/tests/registration/crash-test.c +++ b/tests/registration/crash-test.c @@ -267,6 +267,9 @@ static void test1_func(abts_case *tc, void *data) recvbuf = testgnb_ngap_read(ngap); ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceRelease, + test_ue->ngap_procedure_code); /* Send PDUSessionResourceReleaseResponse */ sendbuf = testngap_build_pdu_session_resource_release_response(sess); diff --git a/tests/registration/dereg-test.c b/tests/registration/dereg-test.c index 4bf9daf58..ea90fbaf6 100644 --- a/tests/registration/dereg-test.c +++ b/tests/registration/dereg-test.c @@ -711,6 +711,9 @@ static void test3_func(abts_case *tc, void *data) recvbuf = testgnb_ngap_read(ngap); ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceRelease, + test_ue->ngap_procedure_code); /* Send PDUSessionResourceReleaseResponse */ sendbuf = testngap_build_pdu_session_resource_release_response(sess); @@ -1157,6 +1160,9 @@ static void test4_func(abts_case *tc, void *data) recvbuf = testgnb_ngap_read(ngap); ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceRelease, + test_ue->ngap_procedure_code); /* Send PDUSessionResourceReleaseResponse */ sendbuf = testngap_build_pdu_session_resource_release_response(sess); @@ -1222,6 +1228,387 @@ static void test4_func(abts_case *tc, void *data) test_ue_remove(test_ue); } +static void test5_func(abts_case *tc, void *data) +{ + int rv; + ogs_socknode_t *ngap; + ogs_socknode_t *gtpu; + ogs_pkbuf_t *gmmbuf; + ogs_pkbuf_t *gsmbuf; + ogs_pkbuf_t *nasbuf; + ogs_pkbuf_t *sendbuf; + ogs_pkbuf_t *recvbuf; + ogs_ngap_message_t message; + int i; + + ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci; + test_ue_t *test_ue = NULL; + test_sess_t *sess = NULL; + test_bearer_t *qos_flow = NULL; + + bson_t *doc = NULL; + + /* Setup Test UE & Session Context */ + memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci)); + + mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI; + mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI; + mobile_identity_suci.routing_indicator1 = 0; + mobile_identity_suci.routing_indicator2 = 0xf; + mobile_identity_suci.routing_indicator3 = 0xf; + mobile_identity_suci.routing_indicator4 = 0xf; + mobile_identity_suci.protection_scheme_id = OGS_NAS_5GS_NULL_SCHEME; + mobile_identity_suci.home_network_pki_value = 0; + mobile_identity_suci.scheme_output[0] = 0; + mobile_identity_suci.scheme_output[1] = 0; + mobile_identity_suci.scheme_output[2] = 0x20; + mobile_identity_suci.scheme_output[3] = 0x31; + mobile_identity_suci.scheme_output[4] = 0x90; + + test_ue = test_ue_add_by_suci(&mobile_identity_suci, 13); + ogs_assert(test_ue); + + test_ue->nr_cgi.cell_id = 0x40001; + + test_ue->nas.registration.tsc = 0; + test_ue->nas.registration.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE; + test_ue->nas.registration.follow_on_request = 1; + test_ue->nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL; + + test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; + test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca"; + + /* gNB connects to AMF */ + ngap = testngap_client(AF_INET); + ABTS_PTR_NOTNULL(tc, ngap); + + /* gNB connects to UPF */ + gtpu = test_gtpu_server(1, AF_INET); + ABTS_PTR_NOTNULL(tc, gtpu); + + /* Send NG-Setup Reqeust */ + sendbuf = testngap_build_ng_setup_request(0x4000, 26); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive NG-Setup Response */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /********** Insert Subscriber in Database */ + doc = test_db_new_simple(test_ue); + ABTS_PTR_NOTNULL(tc, doc); + ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue, doc)); + + /* Send Registration request */ + gmmbuf = testgmm_build_registration_request(test_ue, NULL, false, false); + ABTS_PTR_NOTNULL(tc, gmmbuf); + + test_ue->registration_request_param.gmm_capability = 1; + test_ue->registration_request_param.s1_ue_network_capability = 1; + test_ue->registration_request_param.requested_nssai = 1; + test_ue->registration_request_param.last_visited_registered_tai = 1; + test_ue->registration_request_param.ue_usage_setting = 1; + nasbuf = testgmm_build_registration_request(test_ue, NULL, false, false); + ABTS_PTR_NOTNULL(tc, nasbuf); + + sendbuf = testngap_build_initial_ue_message(test_ue, gmmbuf, + NGAP_RRCEstablishmentCause_mo_Signalling, false, true); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Authentication request */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send Authentication response */ + gmmbuf = testgmm_build_authentication_response(test_ue); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send Security mode complete */ + gmmbuf = testgmm_build_security_mode_complete(test_ue, nasbuf); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive InitialContextSetupRequest + + * Registration accept */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_InitialContextSetup, + test_ue->ngap_procedure_code); + + /* Send UERadioCapabilityInfoIndication */ + sendbuf = testngap_build_ue_radio_capability_info_indication(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send InitialContextSetupResponse */ + sendbuf = testngap_build_initial_context_setup_response(test_ue, false); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Registration complete */ + gmmbuf = testgmm_build_registration_complete(test_ue); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Configuration update command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send PDU session establishment request */ + sess = test_sess_add_by_dnn_and_psi(test_ue, "internet", 5); + ogs_assert(sess); + + sess->ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + sess->ul_nas_transport_param.dnn = 1; + sess->ul_nas_transport_param.s_nssai = 1; + + sess->pdu_session_establishment_param.ssc_mode = 1; + sess->pdu_session_establishment_param.epco = 1; + + gsmbuf = testgsm_build_pdu_session_establishment_request(sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive PDUSessionResourceSetupRequest + + * DL NAS transport + + * PDU session establishment accept */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceSetup, + test_ue->ngap_procedure_code); + + /* Send GTP-U ICMP Packet */ + qos_flow = test_qos_flow_find_by_qfi(sess, 1); + ogs_assert(qos_flow); + rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send PDUSessionResourceSetupResponse */ + sendbuf = testngap_sess_build_pdu_session_resource_setup_response(sess); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send GTP-U ICMP Packet */ + rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send UEContextReleaseRequest */ + sendbuf = testngap_build_ue_context_release_request(test_ue, + NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_user_inactivity, + true); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive UEContextReleaseCommand */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_UEContextRelease, + test_ue->ngap_procedure_code); + + /* Send UEContextReleaseComplete */ + sendbuf = testngap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* + * Send InitialUEMessage + + * Service request + * - PDU Session Status + */ + test_ue->service_request_param.pdu_session_status = 1; + test_ue->service_request_param.psimask.pdu_session_status = 1 << sess->psi; + nasbuf = testgmm_build_service_request( + test_ue, OGS_NAS_SERVICE_TYPE_SIGNALLING, NULL, false, false); + ABTS_PTR_NOTNULL(tc, nasbuf); + + test_ue->service_request_param.pdu_session_status = 0; + gmmbuf = testgmm_build_service_request( + test_ue, OGS_NAS_SERVICE_TYPE_SIGNALLING, nasbuf, true, false); + ABTS_PTR_NOTNULL(tc, gmmbuf); + + sendbuf = testngap_build_initial_ue_message(test_ue, gmmbuf, + NGAP_RRCEstablishmentCause_mo_Signalling, false, true); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive InitialContextSetupRequest + + * Service accept */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_InitialContextSetup, + test_ue->ngap_procedure_code); + ABTS_INT_EQUAL(tc, 0x2000, test_ue->pdu_session_status); + ABTS_INT_EQUAL(tc, 0x0000, test_ue->pdu_session_reactivation_result); + + /* Send InitialContextSetupResponse */ + sendbuf = testngap_build_initial_context_setup_response(test_ue, false); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Wait to setup N3 data connection. + * Otherwise, network-triggered service request is initiated */ + ogs_msleep(100); + + /* Send PDU Session release request */ + sess->ul_nas_transport_param.request_type = 0; + sess->ul_nas_transport_param.dnn = 0; + sess->ul_nas_transport_param.s_nssai = 0; + + sess->pdu_session_establishment_param.ssc_mode = 0; + sess->pdu_session_establishment_param.epco = 0; + + gsmbuf = testgsm_build_pdu_session_release_request(sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive PDUSessionResourceReleaseCommand + + * DL NAS transport + + * PDU session release command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_DownlinkNASTransport, + test_ue->ngap_procedure_code); + + /* Send PDUSessionResourceReleaseResponse */ + sendbuf = testngap_build_pdu_session_resource_release_response(sess); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send UplinkNASTransport + + * UL NAS trasnport + + * PDU session resource release complete */ + sess->ul_nas_transport_param.request_type = 0; + sess->ul_nas_transport_param.dnn = 0; + sess->ul_nas_transport_param.s_nssai = 0; + + sess->pdu_session_establishment_param.ssc_mode = 0; + sess->pdu_session_establishment_param.epco = 0; + + gsmbuf = testgsm_build_pdu_session_release_complete(sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send De-registration request */ + gmmbuf = testgmm_build_de_registration_request(test_ue, 1, true, false); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_initial_ue_message(test_ue, gmmbuf, + NGAP_RRCEstablishmentCause_mo_Signalling, false, false); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive OLD UEContextReleaseCommand */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_UEContextRelease, + test_ue->ngap_procedure_code); + + /* Send OLD UEContextReleaseComplete */ + sendbuf = testngap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive UEContextReleaseCommand */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_UEContextRelease, + test_ue->ngap_procedure_code); + + /* Send UEContextReleaseComplete */ + sendbuf = testngap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(300); + + /********** Remove Subscriber in Database */ + ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue)); + + /* gNB disonncect from UPF */ + testgnb_gtpu_close(gtpu); + + /* gNB disonncect from AMF */ + testgnb_ngap_close(ngap); + + /* Clear Test UE Context */ + test_ue_remove(test_ue); +} + abts_suite *test_dereg(abts_suite *suite) { suite = ADD_SUITE(suite) @@ -1230,6 +1617,7 @@ abts_suite *test_dereg(abts_suite *suite) abts_run_test(suite, test2_func, NULL); abts_run_test(suite, test3_func, NULL); abts_run_test(suite, test4_func, NULL); + abts_run_test(suite, test5_func, NULL); return suite; } diff --git a/tests/registration/paging-test.c b/tests/registration/paging-test.c index 83a5a5012..10b102350 100644 --- a/tests/registration/paging-test.c +++ b/tests/registration/paging-test.c @@ -2381,6 +2381,9 @@ static void vonr_session_test2_func(abts_case *tc, void *data) recvbuf = testgnb_ngap_read(ngap); ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceRelease, + test_ue->ngap_procedure_code); /* Send PDUSessionResourceReleaseResponse */ sendbuf = testngap_build_pdu_session_resource_release_response(sess); diff --git a/tests/registration/ue-context-test.c b/tests/registration/ue-context-test.c index 701bf2bcc..b6c0fbaa1 100644 --- a/tests/registration/ue-context-test.c +++ b/tests/registration/ue-context-test.c @@ -791,6 +791,9 @@ static void test3_func(abts_case *tc, void *data) recvbuf = testgnb_ngap_read(ngap); ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceRelease, + test_ue->ngap_procedure_code); /* Send PDUSessionResourceReleaseResponse */ sendbuf = testngap_build_pdu_session_resource_release_response(sess); @@ -1533,6 +1536,9 @@ static void test5_func(abts_case *tc, void *data) recvbuf = testgnb_ngap_read(ngap); ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceRelease, + test_ue->ngap_procedure_code); /* Send PDUSessionResourceReleaseResponse */ sendbuf = testngap_build_pdu_session_resource_release_response(sess); diff --git a/tests/vonr/af-test.c b/tests/vonr/af-test.c index 959ef9d00..93fca9d59 100644 --- a/tests/vonr/af-test.c +++ b/tests/vonr/af-test.c @@ -1112,6 +1112,9 @@ static void test2_func(abts_case *tc, void *data) recvbuf = testgnb_ngap_read(ngap); ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceRelease, + test_ue->ngap_procedure_code); /* Send PDUSessionResourceReleaseResponse */ sendbuf = testngap_build_pdu_session_resource_release_response(sess); @@ -1517,6 +1520,9 @@ static void test3_func(abts_case *tc, void *data) recvbuf = testgnb_ngap_read(ngap); ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceRelease, + test_ue->ngap_procedure_code); /* Send PDUSessionResourceReleaseResponse */ sendbuf = testngap_build_pdu_session_resource_release_response(sess); @@ -1912,6 +1918,9 @@ static void test4_func(abts_case *tc, void *data) recvbuf = testgnb_ngap_read(ngap); ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceRelease, + test_ue->ngap_procedure_code); /* Send PDUSessionResourceReleaseResponse */ sendbuf = testngap_build_pdu_session_resource_release_response(sess); diff --git a/tests/vonr/session-test.c b/tests/vonr/session-test.c index 126bc58cb..8ace2b316 100644 --- a/tests/vonr/session-test.c +++ b/tests/vonr/session-test.c @@ -430,6 +430,9 @@ static void test1_func(abts_case *tc, void *data) recvbuf = testgnb_ngap_read(ngap); ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + NGAP_ProcedureCode_id_PDUSessionResourceRelease, + test_ue->ngap_procedure_code); /* Send PDUSessionResourceReleaseResponse */ sendbuf = testngap_build_pdu_session_resource_release_response(sess);