pespin submitted this change.

View Change

Approvals: pespin: Looks good to me, approved fixeria: Looks good to me, but someone else must approve Jenkins Builder: Verified
smf,pgw: Fix missing s6b STR handling during release of s2b sessions

Sesions created over s2b (EPDG) also create a session on the AAA over
s6b. When the s2b session is released, a Diameter STR message is sent
towards the AAA, which should answer with STA so that the session is
properly terminated.

Change-Id: I9bc54205eaa3b26a5ec9a3666172ee35d3b98b0e
---
M library/DIAMETER_ts29_273_Templates.ttcn
M pgw/PGW_Session_CT.ttcn
M pgw/PGW_Tests.ttcn
M smf/SMF_Session_CT_4G.ttcn
M smf/SMF_Tests.ttcn
5 files changed, 186 insertions(+), 18 deletions(-)

diff --git a/library/DIAMETER_ts29_273_Templates.ttcn b/library/DIAMETER_ts29_273_Templates.ttcn
index a9f1769..d3915b0 100644
--- a/library/DIAMETER_ts29_273_Templates.ttcn
+++ b/library/DIAMETER_ts29_273_Templates.ttcn
@@ -505,6 +505,32 @@

/* TS 29.273 9.2.2.3.1 Session-Termination-Request (STR) Command,
* Table 9.1.2.3.1/1: S6b Session Termination Request (STR), based on RFC 6733 8.4.1 */
+template (present) PDU_DIAMETER
+tr_DIA_S6b_STR(template (present) hexstring imsi := ?,
+ template (present) BASE_NONE_Termination_Cause term_cause := ?,
+ template (present) octetstring sess_id := ?,
+ template (present) charstring orig_host := ?,
+ template (present) charstring orig_realm := ?,
+ template (present) charstring dest_realm := ?,
+ template (present) UINT32 hbh_id := ?,
+ template (present) UINT32 ete_id := ?) :=
+ tr_DIAMETER(flags := '1???????'B,
+ cmd_code := Session_Termination,
+ app_id := int2oct(c_DIAMETER_3GPP_S6b_AID, 4),
+ hbh_id := hbh_id,
+ ete_id := ete_id,
+ avps := superset(
+ tr_AVP_SessionId(sess_id),
+ /* Optional: DRMP */
+ tr_AVP_AuthAppId(int2oct(c_DIAMETER_3GPP_S6b_AID, 4)),
+ tr_AVP_OriginHost(orig_host),
+ tr_AVP_OriginRealm(orig_realm),
+ tr_AVP_DestinationRealm(dest_realm),
+ tr_AVP_TerminationCause(term_cause),
+ tr_AVP_UserNameImsi(imsi)
+ /* Optional: OC-Supported-Features */
+ ));
+
template (value) PDU_DIAMETER
ts_DIA_S6b_STR(template (value) hexstring imsi,
template (value) BASE_NONE_Termination_Cause term_cause := DIAMETER_LOGOUT,
@@ -554,6 +580,28 @@
/* Lots other Optional */
));

+template (value) PDU_DIAMETER
+ts_DIA_S6b_STA(template (value) DIAMETER_Resultcode res_code := DIAMETER_SUCCESS,
+ template (value) octetstring sess_id := c_def_sess_id,
+ template (value) charstring orig_host := "aaa.localdomain",
+ template (value) charstring orig_realm := "localdomain",
+ template (value) charstring dest_realm := "localdomain",
+ template (value) UINT32 hbh_id := '00000000'O,
+ template (value) UINT32 ete_id := '00000000'O) :=
+ ts_DIAMETER(flags := '01000000'B,
+ cmd_code := Session_Termination,
+ app_id := int2oct(c_DIAMETER_3GPP_S6b_AID, 4),
+ hbh_id := hbh_id,
+ ete_id := ete_id,
+ avps := {
+ ts_AVP_SessionId(sess_id),
+ /* Optional: DRMP */
+ ts_AVP_ResultCode(res_code),
+ ts_AVP_ResultCode(res_code),
+ ts_AVP_OriginHost(orig_host),
+ ts_AVP_OriginRealm(orig_realm)
+ /* Lots other Optional */
+ });

/* TS 29.273 9.2.2.4.1 Abort-Session-Request (ASR) */
template (present) PDU_DIAMETER
@@ -697,4 +745,29 @@
return tx_dia;
}

+/* generate a send template successful answer based on received STR */
+function f_ts_DIA_S6b_STA(PDU_DIAMETER rx_s6b,
+ template (value) DIAMETER_Resultcode res_code := DIAMETER_SUCCESS,
+ template (value) charstring orig_host := "aaa.localdomain",
+ template (value) charstring orig_realm := "localdomain",
+ template (value) charstring dest_realm := "localdomain")
+return template (value) PDU_DIAMETER
+{
+ var template (value) PDU_DIAMETER tx_dia;
+ var template (omit) AVP avp;
+ var octetstring sess_id;
+
+ avp := f_DIAMETER_get_avp(rx_s6b, c_AVP_Code_BASE_NONE_Session_Id);
+ sess_id := valueof(avp.avp_data.avp_BASE_NONE_Session_Id);
+
+ tx_dia := ts_DIA_S6b_STA(res_code,
+ sess_id,
+ orig_host,
+ orig_realm,
+ dest_realm,
+ rx_s6b.hop_by_hop_id,
+ rx_s6b.end_to_end_id);
+ return tx_dia;
+}
+
}
diff --git a/pgw/PGW_Session_CT.ttcn b/pgw/PGW_Session_CT.ttcn
index 3de8d54..74aadfb 100644
--- a/pgw/PGW_Session_CT.ttcn
+++ b/pgw/PGW_Session_CT.ttcn
@@ -173,6 +173,24 @@
}
}

+private altstep as_DIA_S6b_STR() runs on PGW_Session_CT {
+ var PDU_DIAMETER rx_dia;
+ [] DIAMETER[DIA_S6b].receive(tr_DIA_S6b_STR()) -> value rx_dia {
+ var template (value) PDU_DIAMETER tx_dia;
+ tx_dia := f_ts_DIA_S6b_STA(rx_dia,
+ DIAMETER_SUCCESS,
+ "aaa." & mp_diam_realm,
+ mp_diam_realm,
+ mp_diam_realm);
+ DIAMETER[DIA_S6b].send(tx_dia);
+ setverdict(pass);
+ }
+ [] DIAMETER[DIA_S6b].receive(PDU_DIAMETER:?) -> value rx_dia {
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+ log2str("Received unexpected DIAMETER ", rx_dia));
+ }
+}
+
/* Gx emulation (PCRF)*/
altstep as_DIA_Gx_CCR(DCC_NONE_CC_Request_Type req_type) runs on PGW_Session_CT {
var PDU_DIAMETER rx_dia;
@@ -467,18 +485,21 @@
}

/* delete the session from the PGW */
-function f_delete_session(template (omit) GTP2C_Cause tx_cause := omit,
+function f_delete_session(template (value) FullyQualifiedTEID fteid_c_ie,
+ template (omit) GTP2C_Cause tx_cause := omit,
template (present) GTP2C_Cause exp_cause,
- boolean expect_diameter := true) runs on PGW_Session_CT {
- var template (value) FullyQualifiedTEID fteid_c_ie
- fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPC, g_pars.teic_local, 0,
- f_inet_addr(mp_local_hostname_c), omit);
+ boolean expect_diameter := true)
+runs on PGW_Session_CT {
+
var template PDU_GTPCv2 g2c :=
ts_GTP2C_DeleteSessionReq(d_teid := g_pars.teic_remote, cause := tx_cause,
sender_fteid := fteid_c_ie,
teid_list := {}, bearer_id := g_pars.bearer.ebi);

GTP2.send(g2c);
+ if (is_s2b_iface() and DIAMETER[DIA_S6b].checkstate("Connected") and expect_diameter) {
+ as_DIA_S6b_STR();
+ }
if (DIAMETER[DIA_Gx].checkstate("Connected") and expect_diameter) {
as_DIA_Gx_CCR(TERMINATION_REQUEST);
}
@@ -511,6 +532,28 @@
}
}

+function f_s5s8_delete_session(template (omit) GTP2C_Cause tx_cause := omit,
+ template (present) GTP2C_Cause exp_cause,
+ boolean expect_diameter := true)
+runs on PGW_Session_CT {
+ var template (value) FullyQualifiedTEID fteid_c_ie;
+
+ fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPC, g_pars.teic_local, 0,
+ f_inet_addr(mp_local_hostname_c), omit);
+ f_delete_session(fteid_c_ie, tx_cause, exp_cause, expect_diameter);
+}
+
+function f_s2b_delete_session(template (omit) GTP2C_Cause tx_cause := omit,
+ template (present) GTP2C_Cause exp_cause,
+ boolean expect_diameter := true)
+runs on PGW_Session_CT {
+ var template (value) FullyQualifiedTEID fteid_c_ie;
+
+ fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S2b_ePDG_GTPC, g_pars.teic_local, 0,
+ f_inet_addr(mp_local_hostname_c), omit);
+
+ f_delete_session(fteid_c_ie, tx_cause, exp_cause, expect_diameter);
+}

private function f_run_prog_init(charstring command) runs on PGW_Session_CT return UECUPS_StartProgram
{
diff --git a/pgw/PGW_Tests.ttcn b/pgw/PGW_Tests.ttcn
index bd95090..ba660dd 100644
--- a/pgw/PGW_Tests.ttcn
+++ b/pgw/PGW_Tests.ttcn
@@ -375,7 +375,7 @@
/* create a session, then delete it again */
private function f_TC_createSession_deleteSession() runs on PGW_Session_CT {
f_s5s8_create_session();
- f_delete_session(omit, Request_accepted);
+ f_s5s8_delete_session(omit, Request_accepted);
setverdict(pass);
}
testcase TC_createSession_deleteSession() runs on PGW_Test_CT {
@@ -389,7 +389,7 @@
/* send a DeleteSessionReq for an unknown/invalid TEID */
private function f_TC_deleteSession_unknown() runs on PGW_Session_CT {
g_pars.teic_remote := f_rnd_octstring(4);
- f_delete_session(omit, Context_Not_Found, false);
+ f_s5s8_delete_session(omit, Context_Not_Found, false);
setverdict(pass);
}
testcase TC_deleteSession_unknown() runs on PGW_Test_CT {
@@ -420,7 +420,7 @@
as_DIA_Gy_CCR(UPDATE_REQUEST);
f_validate_gy_cc_report(g_rx_gy, VALIDITY_TIME, (3..4), ?, ?);

- f_delete_session(omit, Request_accepted);
+ f_s5s8_delete_session(omit, Request_accepted);
f_validate_gy_cc_report(g_rx_gy, FINAL, (0..1), 0, 0);
setverdict(pass);
}
@@ -466,6 +466,7 @@
var template (omit) APCO apco := omit;
var template APCO exp_apco := omit;
f_s2b_create_session(apco, exp_apco);
+ f_s2b_delete_session(omit, Request_accepted);
setverdict(pass);
}
testcase TC_s2b_createSession_v4_noapco() runs on PGW_Test_CT {
@@ -487,6 +488,7 @@
*, /* open5gs-smfd can contain several DNS servers */
tr_GTP2C_PCO_P_PCSCF_IPv4(?)});
f_s2b_create_session(apco, exp_apco);
+ f_s2b_delete_session(omit, Request_accepted);
setverdict(pass);
}
testcase TC_s2b_createSession_v4_apco() runs on PGW_Test_CT {
diff --git a/smf/SMF_Session_CT_4G.ttcn b/smf/SMF_Session_CT_4G.ttcn
index 9e84218..ba230cb 100644
--- a/smf/SMF_Session_CT_4G.ttcn
+++ b/smf/SMF_Session_CT_4G.ttcn
@@ -75,6 +75,24 @@
}
}

+private altstep as_DIA_S6b_STR() runs on SMF_Session_CT {
+ var PDU_DIAMETER rx_dia;
+ [] DIAMETER[DIA_S6b].receive(tr_DIA_S6b_STR()) -> value rx_dia {
+ var template (value) PDU_DIAMETER tx_dia;
+ tx_dia := f_ts_DIA_S6b_STA(rx_dia,
+ DIAMETER_SUCCESS,
+ "aaa." & mp_diam_realm,
+ mp_diam_realm,
+ mp_diam_realm);
+ DIAMETER[DIA_S6b].send(tx_dia);
+ setverdict(pass);
+ }
+ [] DIAMETER[DIA_S6b].receive(PDU_DIAMETER:?) -> value rx_dia {
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+ log2str("Received unexpected DIAMETER ", rx_dia));
+ }
+}
+
/* Gx emulation (PCRF)*/
altstep as_DIA_Gx_CCR(DCC_NONE_CC_Request_Type req_type) runs on SMF_Session_CT {
var PDU_DIAMETER rx_dia;
@@ -361,13 +379,13 @@
}

/* delete the session from the SMF */
-function f_delete_session(template (omit) GTP2C_Cause tx_cause := omit,
- template (present) GTP2C_Cause exp_cause,
- boolean expect_pfcp := true,
- boolean expect_diameter := true) runs on SMF_Session_CT {
- var template (value) FullyQualifiedTEID fteid_c_ie
- fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPC, g_pars.teic_local, 0,
- f_inet_addr(mp_local_hostname_c), omit);
+private function f_delete_session(template (value) FullyQualifiedTEID fteid_c_ie,
+ template (omit) GTP2C_Cause tx_cause := omit,
+ template (present) GTP2C_Cause exp_cause,
+ boolean expect_pfcp := true,
+ boolean expect_diameter := true)
+runs on SMF_Session_CT {
+
var template PDU_GTPCv2 g2c :=
ts_GTP2C_DeleteSessionReq(d_teid := g_pars.teic_remote, cause := tx_cause,
sender_fteid := fteid_c_ie,
@@ -379,6 +397,10 @@
as_pfcp_sess_del_req();
}

+ if (is_s2b_iface() and DIAMETER[DIA_S6b].checkstate("Connected") and expect_diameter) {
+ as_DIA_S6b_STR();
+ }
+
if (DIAMETER[DIA_Gx].checkstate("Connected") and expect_diameter) {
as_DIA_Gx_CCR(TERMINATION_REQUEST);
}
@@ -400,4 +422,30 @@
}
}

+function f_s5s8_delete_session(template (omit) GTP2C_Cause tx_cause := omit,
+ template (present) GTP2C_Cause exp_cause,
+ boolean expect_pfcp := true,
+ boolean expect_diameter := true)
+runs on SMF_Session_CT {
+ var template (value) FullyQualifiedTEID fteid_c_ie;
+
+ fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPC, g_pars.teic_local, 0,
+ f_inet_addr(mp_local_hostname_c), omit);
+
+ f_delete_session(fteid_c_ie, tx_cause, exp_cause, expect_pfcp, expect_diameter);
+}
+
+function f_s2b_delete_session(template (omit) GTP2C_Cause tx_cause := omit,
+ template (present) GTP2C_Cause exp_cause,
+ boolean expect_pfcp := true,
+ boolean expect_diameter := true)
+runs on SMF_Session_CT {
+ var template (value) FullyQualifiedTEID fteid_c_ie;
+
+ fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S2b_ePDG_GTPC, g_pars.teic_local, 0,
+ f_inet_addr(mp_local_hostname_c), omit);
+
+ f_delete_session(fteid_c_ie, tx_cause, exp_cause, expect_pfcp, expect_diameter);
+}
+
}
diff --git a/smf/SMF_Tests.ttcn b/smf/SMF_Tests.ttcn
index 609756a..4501520 100644
--- a/smf/SMF_Tests.ttcn
+++ b/smf/SMF_Tests.ttcn
@@ -337,7 +337,7 @@
/* create an IPv4 session, then delete it again */
private function f_TC_createSession_deleteSession() runs on SMF_Session_CT {
f_s5s8_create_session();
- f_delete_session(omit, Request_accepted);
+ f_s5s8_delete_session(omit, Request_accepted);
setverdict(pass);
}
testcase TC_createSession_deleteSession() runs on SMF_Test_CT {
@@ -399,7 +399,7 @@
/* send a DeleteSessionReq for an unknown/invalid TEID */
private function f_TC_deleteSession_unknown() runs on SMF_Session_CT {
g_pars.teic_remote := f_rnd_octstring(4);
- f_delete_session(omit, Context_Not_Found, false, false);
+ f_s5s8_delete_session(omit, Context_Not_Found, false, false);
setverdict(pass);
}
testcase TC_deleteSession_unknown() runs on SMF_Test_CT {
@@ -451,7 +451,7 @@
/* SMF updates new Volume quota obtained from OCS on UPF: */
as_pfcp_sess_mod_req();

- f_delete_session(omit, Request_accepted);
+ f_s5s8_delete_session(omit, Request_accepted);
f_validate_gy_cc_report(g_rx_gy, FINAL, (0..1), 0, 0);
setverdict(pass);
}
@@ -506,6 +506,7 @@
var template (omit) APCO apco := omit;
var template APCO exp_apco := omit;
f_s2b_create_session(apco, exp_apco);
+ f_s2b_delete_session(omit, Request_accepted);
setverdict(pass);
}
testcase TC_s2b_createSession_v4_noapco() runs on SMF_Test_CT {
@@ -525,6 +526,7 @@
*, /* open5gs-smfd can contain several DNS servers */
tr_GTP2C_PCO_P_PCSCF_IPv4(?)});
f_s2b_create_session(apco, exp_apco);
+ f_s2b_delete_session(omit, Request_accepted);
setverdict(pass);
}
testcase TC_s2b_createSession_v4_apco() runs on SMF_Test_CT {

To view, visit change 43740. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: merged
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: I9bc54205eaa3b26a5ec9a3666172ee35d3b98b0e
Gerrit-Change-Number: 43740
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>