pespin submitted this change.
5gc: keep NUS after UeContextRelease
Since open5gs.git b9823196b5de3394b7a144569f186d7d62fad6f9, open5gs
properly validates received seq_nr (ul_count) of integrity protected
NG-NAS message to make sure it increases with each new UL message, in
order to protect against accepting replayed messages.
This means that tests going over UeContextRelease procedure need to keep
a copy of the NUS (NAS state) because the UeContextreleaseCommand erases
the NGAP entry in the NGAP_Emulation table, together with the associated
NUS.
We need the copy of NUS because we need to keep reusing the NAS state,
increasing the previous ul_count.
This fixes tests TC_ue_service_request_cm_* as well as
TC_net_triggered_service_req.
Change-Id: I84b91bf00491a1ba0c2ee8d57e61996a88fe12d3
---
M 5gc/C5G_Tests.ttcn
M 5gc/ConnHdlr.ttcn
M library/NGAP_Emulation.ttcn
3 files changed, 80 insertions(+), 27 deletions(-)
diff --git a/5gc/C5G_Tests.ttcn b/5gc/C5G_Tests.ttcn
index 2be26ff..0edd792 100644
--- a/5gc/C5G_Tests.ttcn
+++ b/5gc/C5G_Tests.ttcn
@@ -576,13 +576,19 @@
* UE signals the active session as active, and it has UL data for it */
private function f_TC_ue_service_request_cm_idle_ul_data() runs on ConnHdlr {
var PDU_SessionStatus pdu_session_status;
+ var NG_NAS_UE_State nus;
f_register();
f_pdu_sess_establish(configure_userplane := false);
f_sleep(1.0);
+ /* UECtx State in NGAP_Emulation will be destroyed upon rx of NGAP UeContextReleaseCmd.
+ * We need to store the NAS state here and feed it back to NGAP_Emulation so it is available for InitialUE(Service Request),
+ * since the NAS state is still the same one and needs to be used. */
+ nus := f_ngap_obtain_nus(g_pars.ue_pars.ran_id);
f_ue_context_release();
f_sleep(1.0);
pdu_session_status := f_PDU_SessionStatus();
+ f_ngap_set_nus(g_pars.ue_pars.ran_id, nus, create_nonexist := true);
f_service_request_cm_idle(ul_data_status := pdu_session_status,
pdu_sess_status := pdu_session_status);
@@ -606,12 +612,18 @@
* UE signals that the active session is now inactive. AMF sends a PFCP Session Delete to SMF. */
private function f_TC_ue_service_request_cm_idle_inact_sess() runs on ConnHdlr {
var NGAP_PDU rx_ngap;
+ var NG_NAS_UE_State nus;
f_register();
f_pdu_sess_establish(configure_userplane := false);
f_sleep(1.0);
+ /* UECtx State in NGAP_Emulation will be destroyed upon rx of NGAP UeContextReleaseCmd.
+ * We need to store the NAS state here and feed it back to NGAP_Emulation so it is available for InitialUE(Service Request),
+ * since the NAS state is still the same one and needs to be used. */
+ nus := f_ngap_obtain_nus(g_pars.ue_pars.ran_id);
f_ue_context_release();
f_sleep(1.0);
+ f_ngap_set_nus(g_pars.ue_pars.ran_id, nus, create_nonexist := true);
f_service_request_cm_idle(pdu_sess_status := cs_PDU_SessionStatus('00000000'B, '00000000'B));
NGAP.receive(cr_NG_SERVICE_ACCEPT(p_PDU_SessionStatus := cr_PDU_SessionStatus('00000000'B, '00000000'B)));
g_pars.ue_pars.amf_id := f_ngap_obtain_amf_id();
@@ -630,10 +642,17 @@
/* 3GPP TS 23.502 4.2.3.2 UE Triggered Service Request.
* UE signals that a session unknown to network is active: */
private function f_TC_ue_service_request_cm_idle_unknown_sess_active() runs on ConnHdlr {
+ var NG_NAS_UE_State nus;
+
f_register();
f_sleep(1.0);
+ /* UECtx State in NGAP_Emulation will be destroyed upon rx of NGAP UeContextReleaseCmd.
+ * We need to store the NAS state here and feed it back to NGAP_Emulation so it is available for InitialUE(Service Request),
+ * since the NAS state is still the same one and needs to be used. */
+ nus := f_ngap_obtain_nus(g_pars.ue_pars.ran_id);
f_ue_context_release();
f_sleep(1.0);
+ f_ngap_set_nus(g_pars.ue_pars.ran_id, nus, create_nonexist := true);
f_service_request_cm_idle(pdu_sess_status := cs_PDU_SessionStatus('00000010'B, '00000000'B));
NGAP.receive(cr_NG_SERVICE_ACCEPT(p_PDU_SessionStatus := cr_PDU_SessionStatus('00000000'B, '00000000'B)));
g_pars.ue_pars.amf_id := f_ngap_obtain_amf_id();
@@ -674,13 +693,19 @@
/* 3GPP TS 23.502 4.2.3.3 Network Triggered Service Request */
private function f_TC_net_triggered_service_req() runs on ConnHdlr {
var PDU_SessionStatus pdu_session_status;
+ var NG_NAS_UE_State nus;
f_register();
f_pdu_sess_establish();
f_sleep(1.0);
+ /* UECtx State in NGAP_Emulation will be destroyed upon rx of NGAP UeContextReleaseCmd.
+ * We need to store the NAS state here and feed it back to NGAP_Emulation so it is available for InitialUE(Service Request),
+ * since the NAS state is still the same one and needs to be used. */
+ nus := f_ngap_obtain_nus(g_pars.ue_pars.ran_id);
f_ue_context_release();
f_sleep(1.0);
f_create_ngap_expect_proc(id_Paging, self);
+ f_ngap_set_nus(g_pars.ue_pars.ran_id, nus, create_nonexist := true);
/* NOTE: In theory we should generate DL-originated traffic here, but since
* UPF let our UL traffic pass (bug?), make use of it to generate some DL
diff --git a/5gc/ConnHdlr.ttcn b/5gc/ConnHdlr.ttcn
index 8f5e5c5..6125489 100644
--- a/5gc/ConnHdlr.ttcn
+++ b/5gc/ConnHdlr.ttcn
@@ -879,6 +879,34 @@
NGAP.send(nas_ul_msg);
}
+private function f_encode_nas(NG_NAS_UL_Message_Type nas_ul_msg) runs on ConnHdlr return NAS_PDU {
+ var NAS_PDU nas_pdu;
+ var NG_NAS_UE_State nus;
+ var BIT4 sec_hdr_t := '0001'B;
+ var OCT1 seq_nr;
+ var OCT4 mac;
+ var NG_NAS_UL_Message_Type nas_out;
+
+ nus := f_ngap_obtain_nus(g_pars.ue_pars.ran_id);
+
+ nus.tx_count := nus.tx_count + 1;
+ seq_nr := int2oct(nus.tx_count, 1);
+ nas_pdu := enc_NG_NAS_UL_Message_Type(valueof(nas_ul_msg));
+ mac := f_NG_NAS_mac_calc(NG_NAS_ALG_IP_NIA1, f_kdf_ng_nas_int(g_keys.kamf, NG_NAS_ALG_IP_NIA1),
+ nus.tx_count,
+ bit2int(tsc_NG_RegResult_3GPP),
+ false, seq_nr & nas_pdu);
+ nas_out := valueof(cs_NG_SECURITY_PROTECTED_NAS_MESSAGE(tsc_EPD_GMM,
+ sec_hdr_t,
+ mac,
+ seq_nr,
+ nas_pdu));
+ nas_pdu := enc_NG_NAS_UL_Message_Type(valueof(nas_out));
+
+ f_ngap_set_nus(g_pars.ue_pars.ran_id, nus);
+ return nas_pdu;
+}
+
/* 3GPP TS 24.501 5.6.1 Service request procedure
* 3GPP TS 23.502 4.2.3.2 UE Triggered Service Request */
function f_service_request_cm_idle(template (omit) ULDataStatus ul_data_status := omit,
@@ -898,21 +926,8 @@
f_NG_MobileIdentity_STMSI(),
p_Msg := cs_ReplayedNASMessageContainerTLV(nas_pdu));
- //TODO: add a function to send a NAS_UL_MSG and receive the encoded one.
- var BIT4 sec_hdr_t := '0001'B;
- var integer tx_count := 0;
- nas_pdu := enc_NG_NAS_UL_Message_Type(valueof(nas_ul_msg));
- var OCT4 mac := f_NG_NAS_mac_calc(NG_NAS_ALG_IP_NIA1, f_kdf_ng_nas_int(g_keys.kamf, NG_NAS_ALG_IP_NIA1),
- tx_count,
- bit2int(tsc_NG_RegResult_3GPP),
- false, '00'O & nas_pdu);
- var NG_NAS_UL_Message_Type nas_out;
- nas_out := valueof(cs_NG_SECURITY_PROTECTED_NAS_MESSAGE(tsc_EPD_GMM,
- sec_hdr_t,
- mac,
- int2oct(tx_count, 1),
- nas_pdu));
- nas_pdu := enc_NG_NAS_UL_Message_Type(valueof(nas_out));
+ nas_pdu := f_encode_nas(valueof(nas_ul_msg));
+
tx_pdu := m_ngap_initMsg(m_n2_initialUeMessage(g_pars.ue_pars.ran_id,
nas_pdu, /* Service request */
f_ULI(),
diff --git a/library/NGAP_Emulation.ttcn b/library/NGAP_Emulation.ttcn
index ea23a35..ba2b7d2 100644
--- a/library/NGAP_Emulation.ttcn
+++ b/library/NGAP_Emulation.ttcn
@@ -118,7 +118,7 @@
signature NGAPEM_register_proc(in integer procedureCode, in NGAP_ConnHdlr hdlr);
signature NGAPEM_obtain_amf_id() return AMF_UE_NGAP_ID;
signature NGAPEM_obtain_nus(in RAN_UE_NGAP_ID ran_id) return NG_NAS_UE_State;
-signature NGAPEM_set_nus(in RAN_UE_NGAP_ID ran_id, in NG_NAS_UE_State nus);
+signature NGAPEM_set_nus(in RAN_UE_NGAP_ID ran_id, in NG_NAS_UE_State nus, in boolean create_nonexist);
//signature NGAPEM_derive_nas_token(in octetstring kasme, in NGAP_ConnHdlr hdlr, out OCT32 nas_token);
type port NGAPEM_PROC_PT procedure {
@@ -304,7 +304,7 @@
return -1; /* make ttcn3 compiler happy */
}
-private function f_assoc_id_by_comp(NGAP_ConnHdlr client, template (omit) RAN_UE_NGAP_ID ran_id := omit)
+private function f_assoc_id_by_comp(NGAP_ConnHdlr client, template (omit) RAN_UE_NGAP_ID ran_id := omit, boolean fail_notfound := true)
runs on NGAP_Emulation_CT return integer {
var integer i;
for (i := 0; i < sizeof(NGapAssociationTable); i := i+1) {
@@ -317,8 +317,11 @@
}
return i;
}
- setverdict(fail, "NGAP Association Table not found by component ", client, " RAN-ID=", ran_id);
- mtc.stop;
+ if (fail_notfound) {
+ setverdict(fail, "NGAP Association Table not found by component ", client, " RAN-ID=", ran_id);
+ mtc.stop;
+ }
+ return -1;
}
private function f_assoc_by_comp(NGAP_ConnHdlr client)
@@ -531,6 +534,7 @@
var integer ai;
var octetstring kasme;
var NG_NAS_UE_State nus;
+ var boolean create_nonexist;
alt {
/* Configuration primitive from client */
@@ -561,8 +565,14 @@
}
/* NGAP from client: InitialUE */
[] NGAP_CLIENT.receive(mw_ngap_initMsg(mw_n2_initialUeMessage)) -> value msg sender vc_conn {
- /* create a table entry about this connection */
- ai := f_ngap_id_table_add(vc_conn, omit, valueof(f_NGAP_get_RAN_UE_NGAP_ID(msg)));
+ /* create a table entry about this connection if not yet existing. */
+ ran_id := valueof(f_NGAP_get_RAN_UE_NGAP_ID(msg));
+ ai := f_assoc_id_by_comp(vc_conn, ran_id, fail_notfound := false);
+ if (ai >= 0) {
+ NGapAssociationTable[ai].amf_ue_ngap_id := omit;
+ } else {
+ ai := f_ngap_id_table_add(vc_conn, omit, ran_id);
+ }
/* Store ULI so we can use it for generating UlNasTransport from NAS */
NGapAssociationTable[ai].uli := msg.initiatingMessage.value_.InitialUEMessage.protocolIEs[2].value_.userLocationInformation;
/* Pass message through */
@@ -692,10 +702,13 @@
var integer i := f_assoc_id_by_comp(vc_conn, ran_id);
NGAP_PROC.reply(NGAPEM_obtain_nus:{ran_id} value NGapAssociationTable[i].nus) to vc_conn;
}
- [] NGAP_PROC.getcall(NGAPEM_set_nus:{?, ?}) -> param(ran_id, nus) sender vc_conn {
- var integer i := f_assoc_id_by_comp(vc_conn, ran_id);
+ [] NGAP_PROC.getcall(NGAPEM_set_nus:{?, ?, ?}) -> param(ran_id, nus, create_nonexist) sender vc_conn {
+ var integer i := f_assoc_id_by_comp(vc_conn, ran_id, fail_notfound := not create_nonexist);
+ if (i < 0) {
+ i := f_ngap_id_table_add(vc_conn, omit, ran_id);
+ }
NGapAssociationTable[i].nus := nus;
- NGAP_PROC.reply(NGAPEM_set_nus:{ran_id, nus}) to vc_conn;
+ NGAP_PROC.reply(NGAPEM_set_nus:{ran_id, nus, create_nonexist}) to vc_conn;
}
// [] NGAP_PROC.getcall(NGAPEM_derive_nas_token:{?, ?, -}) -> param(kasme, vc_conn) {
// var integer assoc_id := f_assoc_id_by_comp(vc_conn);
@@ -815,9 +828,9 @@
}
}
-function f_ngap_set_nus(RAN_UE_NGAP_ID ran_id, NG_NAS_UE_State nus) runs on NGAP_ConnHdlr {
- NGAP_PROC.call(NGAPEM_set_nus:{ran_id, nus}) {
- [] NGAP_PROC.getreply(NGAPEM_set_nus:{ran_id, nus});
+function f_ngap_set_nus(RAN_UE_NGAP_ID ran_id, NG_NAS_UE_State nus, boolean create_nonexist := false) runs on NGAP_ConnHdlr {
+ NGAP_PROC.call(NGAPEM_set_nus:{ran_id, nus, create_nonexist}) {
+ [] NGAP_PROC.getreply(NGAPEM_set_nus:{ran_id, nus, create_nonexist});
}
}
To view, visit change 43214. To unsubscribe, or for help writing mail filters, visit settings.