aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2022-05-08 01:16:55 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2022-08-16 15:42:51 +0200
commita56e8fdc2d4740194ad4e9105f4eacc352c63a9d (patch)
tree75154d85fd4f2fa8f14540c87f6f6e85a8633940
parenta2d1d7a211cd387e4c5de9080db772bf340d26ca (diff)
hnbgw: test PS RAB GTP mapping
-rw-r--r--hnbgw/HNBGW_Tests.ttcn185
-rwxr-xr-xhnbgw/gen_links.sh6
-rw-r--r--hnbgw/osmo-hnbgw.cfg5
-rwxr-xr-xhnbgw/regen_makefile.sh1
-rw-r--r--library/ranap/RANAP_Templates.ttcn100
5 files changed, 294 insertions, 3 deletions
diff --git a/hnbgw/HNBGW_Tests.ttcn b/hnbgw/HNBGW_Tests.ttcn
index 81d9f1a0..7429c389 100644
--- a/hnbgw/HNBGW_Tests.ttcn
+++ b/hnbgw/HNBGW_Tests.ttcn
@@ -57,6 +57,11 @@ import from MGCP_Templates all;
import from MGCP_CodecPort all;
import from SDP_Types all;
+import from PFCP_Types all;
+import from PFCP_Emulation all;
+import from PFCP_Templates all;
+import from PFCP_CodecPort all;
+
modulepar {
/* IP address at which the HNodeB can be reached */
charstring mp_hnodeb_ip := "127.0.0.1";
@@ -91,6 +96,13 @@ modulepar {
sio := '83'O,
rctx := 2
};
+
+ /* IP address at which we listen for PFCP to emulate a UPF in ttcn3 */
+ charstring mp_pfcp_ip_local := "127.0.0.1";
+
+ /* IP address from which the SUT (osmo-hnbgw) sends PFCP requests, and to which the ttcn3 UPF emulation sends
+ * PFCP responses. */
+ charstring mp_pfcp_ip_remote := "127.0.0.2";
}
function MSC_UnitdataCallback(RANAP_PDU ranap) runs on RAN_Emulation_CT return template RANAP_PDU {
@@ -168,7 +180,8 @@ type record TestHdlrParams {
boolean ps_domain,
MgcpParameters mgcp_pars optional,
HnbConfig hnb optional,
- boolean separate_sccp_cr
+ boolean separate_sccp_cr,
+ charstring pfcp_local_addr
}
/* We extend:
@@ -176,7 +189,7 @@ type record TestHdlrParams {
* RAN_ConnHdlr (for the Iu side, emulating the MSC)
* MGCP_ConnHdlr (for the MGCP side, emulating the MGW)
*/
-type component ConnHdlr extends RAN_ConnHdlr, MGCP_ConnHdlr, RUA_ConnHdlr {
+type component ConnHdlr extends RAN_ConnHdlr, MGCP_ConnHdlr, RUA_ConnHdlr, PFCP_ConnHdlr {
var integer g_sccp_conn_id;
var TestHdlrParams g_pars;
timer g_Tguard;
@@ -267,6 +280,23 @@ function f_init_mgcp(charstring id) runs on test_CT {
vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
}
+function f_init_pfcp(charstring id) runs on ConnHdlr {
+ id := id & "-PFCP";
+
+ var PFCP_Emulation_Cfg pfcp_cfg := {
+ pfcp_bind_ip := mp_pfcp_ip_local,
+ pfcp_bind_port := PFCP_PORT,
+ pfcp_remote_ip := mp_pfcp_ip_remote,
+ pfcp_remote_port := PFCP_PORT,
+ role := UPF
+ };
+
+ vc_PFCP := PFCP_Emulation_CT.create(id) alive;
+ connect(self:PFCP, vc_PFCP:CLIENT);
+ connect(self:PFCP_PROC, vc_PFCP:CLIENT_PROC);
+ vc_PFCP.start(PFCP_Emulation.main(pfcp_cfg));
+}
+
function f_init_hnodeb(charstring id, integer hnb_idx, RuaOps rua_ops) runs on test_CT {
id := id & "-Iuh" & int2str(hnb_idx);
@@ -417,6 +447,9 @@ type function void_fn(charstring id, TestHdlrParams pars) runs on ConnHdlr;
function f_init_handler(TestHdlrParams pars, float t_guard := 20.0) runs on ConnHdlr {
/* make parameters available via component variable */
g_pars := pars;
+
+ f_init_pfcp(testcasename());
+
/* start guard timer and activate it as default */
g_Tguard.start(t_guard);
activate(as_Tguard_ConnHdlr());
@@ -643,7 +676,8 @@ t_pars(integer imsi_suffix, boolean ps_domain := false, integer hnb_idx := 0,
imsi := f_gen_imsi(imsi_suffix),
ps_domain := ps_domain,
hnb := omit, /* filled in later */
- separate_sccp_cr := separate_sccp_cr
+ separate_sccp_cr := separate_sccp_cr,
+ pfcp_local_addr := mp_pfcp_ip_local
}
/* Create an Iuh connection; send InitialUE; expect it to appear on new SCCP conenction */
@@ -1139,8 +1173,152 @@ testcase TC_ranap_ps_mo_disconnect() runs on test_CT {
vc_conn.done;
}
+type record FTeid {
+ HostName addr,
+ OCT4 teid
+}
+
+type record FTeids {
+ FTeid local,
+ FTeid remote
+}
+
+
+/* 'local' and 'remote' refer to the GTP information from the UPF's point of view:
+ * HNB UPF CN
+ * access.remote <---> access.local | core.local <---> core.remote
+ */
+type record GtpParameters {
+ FTeids core,
+ FTeids access
+}
+
+/* HNB UPF CN
+ * access.remote <---> access.local | core.local <---> core.remote
+ * 127.0.0.4 127.0.0.3 127.0.0.2 127.0.0.1
+ * 0x44004400 0x30303030 0x22002200 0x10101010
+ */
+template GtpParameters t_GtpParameters := {
+ core := {
+ local := {
+ addr := "127.0.0.2",
+ teid := '22002200'O
+ },
+ remote := {
+ addr := "127.0.0.1",
+ teid := '10101010'O
+ }
+ },
+ access := {
+ local := {
+ addr := "127.0.0.3",
+ teid := '30303030'O
+ },
+ remote := {
+ addr := "127.0.0.4",
+ teid := '44004400'O
+ }
+ }
+}
+
+friend function f_tc_ps_rab_assignment(charstring id, TestHdlrParams pars) runs on ConnHdlr {
+ var RANAP_PDU tx;
+ var RANAP_PDU rx;
+ timer T := 5.0;
+
+ f_init_handler(pars);
+
+ f_pfcp_register();
+
+ var PDU_PFCP m;
+ var Node_ID upf_node_id := valueof(ts_PFCP_Node_ID_fqdn("\07osmocom\03org"));
+
+ PFCP.receive(tr_PFCP_Assoc_Setup_Req()) -> value m;
+ PFCP.send(ts_PFCP_Assoc_Setup_Resp(m.sequence_number, upf_node_id,
+ ts_PFCP_Cause(REQUEST_ACCEPTED), 1234));
+ tx := f_build_initial_ue(g_pars);
+ f_iuh2iu_connect(tx);
+
+ var GtpParameters gtp_pars := valueof(t_GtpParameters);
+ var template RAB_SetupOrModifyList rab_sml;
+
+ /* Send RAB Assignment Request */
+ rab_sml := ts_RAB_SML_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.core.remote.addr), gtp_pars.core.remote.teid);
+ tx := valueof(ts_RANAP_RabAssReq(rab_sml));
+ BSSAP.send(tx);
+
+ /* Expect PFCP Session Establishment Request. */
+ PFCP.receive(tr_PFCP_Session_Est_Req()) -> value m;
+ var F_SEID hnbgw_f_seid := m.message_body.pfcp_session_establishment_request.CP_F_SEID;
+ var PFCP_Session_Establishment_Request serq := m.message_body.pfcp_session_establishment_request;
+
+ /* Acting as UPF, invent a new PFCP SEID to send to HNBGW. Respond to the Session Establishment.
+ * The PFCP response must have the same sequence_number as the request. */
+ var F_SEID up_f_seid := valueof(ts_PFCP_F_SEID_ipv4("127.0.0.1", '1111111111111111'O));
+ var template PDU_PFCP r := ts_PFCP_Session_Est_Resp(m.sequence_number, upf_node_id, hnbgw_f_seid.seid);
+ r.message_body.pfcp_session_establishment_response := {
+ offending_ie := omit,
+ UP_F_SEID := up_f_seid,
+ created_PDR_list := {
+ ts_PFCP_Created_PDR(pdr_id := serq.create_PDR_list[0].grouped_ie.pdr_id,
+ local_F_TEID := ts_PFCP_F_TEID_ipv4(gtp_pars.core.local.teid,
+ gtp_pars.core.local.addr)),
+ ts_PFCP_Created_PDR(pdr_id := serq.create_PDR_list[1].grouped_ie.pdr_id,
+ local_F_TEID := ts_PFCP_F_TEID_ipv4(gtp_pars.access.local.teid,
+ gtp_pars.access.local.addr))
+ },
+ load_control_information := omit,
+ overload_control_information := omit,
+ node_list := omit,
+ failed_rule_id := omit,
+ created_traffic_endpoint_list := omit
+ };
+ PFCP.send(r);
+
+ /* Expect on Iuh: RAB Assignment Request with IP/port from PFCP Session Est Resp */
+ rab_sml := ts_RAB_SML_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.access.local.addr),
+ gtp_pars.access.local.teid);
+ rx := valueof(ts_RANAP_RabAssReq(rab_sml));
+ RUA.receive(rx);
+
+ /* Send back RAB Assignment Response via Iuh */
+ var template RAB_SetupOrModifiedList rab_smdl;
+ rab_smdl := ts_RAB_SMdL_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.access.remote.addr),
+ gtp_pars.access.remote.teid);
+ tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
+ RUA.send(tx);
+ T.start;
+ PFCP.receive(tr_PFCP_Session_Mod_Req(up_f_seid.seid)) -> value m;
+ r := ts_PFCP_Session_Mod_Resp(m.sequence_number, hnbgw_f_seid.seid);
+ PFCP.send(r);
+
+ rab_smdl := ts_RAB_SMdL_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.core.local.addr), gtp_pars.core.local.teid);
+ BSSAP.receive(tr_RANAP_RabAssResp(rab_smdl));
+
+ f_sleep(2.0);
+ tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
+ f_iu2iuh(tx);
+
+ tx := valueof(ts_RANAP_IuReleaseComplete());
+ f_iuh2iu(tx);
+
+ PFCP.receive(tr_PFCP_Session_Del_Req(up_f_seid.seid)) -> value m;
+ PFCP.send(ts_PFCP_Session_Del_Resp(m.sequence_number, hnbgw_f_seid.seid));
+
+ f_sleep(2.0);
+}
+
+testcase TC_ps_rab_assignment() runs on test_CT {
+ var ConnHdlr vc_conn;
+ f_init();
+ f_start_hnbs();
+ f_sleep(1.0);
+
+ vc_conn := f_start_handler_with_pars(refers(f_tc_ps_rab_assignment), t_pars(7, ps_domain := true));
+ vc_conn.done;
+}
control {
execute(TC_hnb_register());
@@ -1156,6 +1334,7 @@ control {
execute(TC_rab_assign_mgcp_to());
execute(TC_ranap_cs_mo_disconnect());
execute(TC_ranap_ps_mo_disconnect());
+ execute(TC_ps_rab_assignment());
}
}
diff --git a/hnbgw/gen_links.sh b/hnbgw/gen_links.sh
index aabc8c0f..4be3b535 100755
--- a/hnbgw/gen_links.sh
+++ b/hnbgw/gen_links.sh
@@ -22,6 +22,7 @@ FILES="MobileL3_CC_Types.ttcn MobileL3_CommonIE_Types.ttcn MobileL3_GMM_SM_Types
gen_links $DIR $FILES
# Required by MGCP and IPA
+# Required by PFCP/UDP
DIR=$BASEDIR/titan.TestPorts.IPL4asp/src
FILES="IPL4asp_Functions.ttcn IPL4asp_PT.cc IPL4asp_PT.hh IPL4asp_PortType.ttcn IPL4asp_Types.ttcn IPL4asp_discovery.cc IPL4asp_protocol_L234.hh"
gen_links $DIR $FILES
@@ -76,6 +77,10 @@ DIR=$BASEDIR/titan.TestPorts.TELNETasp/src
FILES="TELNETasp_PT.cc TELNETasp_PT.hh TELNETasp_PortType.ttcn"
gen_links $DIR $FILES
+DIR=$BASEDIR/titan.ProtocolModules.PFCP_v15.1.0/src
+FILES="PFCP_Types.ttcn"
+gen_links $DIR $FILES
+
DIR=../library/hnbap
FILES="HNBAP_CommonDataTypes.asn HNBAP_Constants.asn HNBAP_Containers.asn HNBAP_IEs.asn HNBAP_PDU_Contents.asn HNBAP_PDU_Descriptions.asn "
FILES+="HNBAP_EncDec.cc HNBAP_Types.ttcn HNBAP_Templates.ttcn "
@@ -95,6 +100,7 @@ DIR=../library
FILES="Iuh_Types.ttcn Iuh_CodecPort.ttcn Iuh_CodecPort_CtrlFunctDef.cc Iuh_CodecPort_CtrlFunct.ttcn Iuh_Emulation.ttcn DNS_Helpers.ttcn "
FILES+="MGCP_Emulation.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_CodecPort_CtrlFunctDef.cc "
FILES+="RAN_Adapter.ttcnpp RAN_Emulation.ttcnpp BSSAP_CodecPort.ttcn SCCP_Templates.ttcn "
+FILES+="PFCP_CodecPort.ttcn PFCP_CodecPort_CtrlFunct.ttcn PFCP_CodecPort_CtrlFunctDef.cc PFCP_Emulation.ttcn PFCP_Templates.ttcn "
FILES+="Misc_Helpers.ttcn General_Types.ttcn Osmocom_Types.ttcn GSM_Types.ttcn Osmocom_VTY_Functions.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc IPA_Emulation.ttcnpp Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunct.ttcn RTP_CodecPort_CtrlFunctDef.cc RTP_Emulation.ttcn IuUP_Types.ttcn IuUP_EncDec.cc IuUP_Emulation.ttcn "
FILES+="StatsD_Types.ttcn StatsD_CodecPort.ttcn StatsD_CodecPort_CtrlFunct.ttcn StatsD_CodecPort_CtrlFunctdef.cc StatsD_Checker.ttcn "
diff --git a/hnbgw/osmo-hnbgw.cfg b/hnbgw/osmo-hnbgw.cfg
index f11f6136..e4dfed2a 100644
--- a/hnbgw/osmo-hnbgw.cfg
+++ b/hnbgw/osmo-hnbgw.cfg
@@ -33,3 +33,8 @@ hnbgw
remote-addr msc
iups
remote-addr sgsn
+ pfcp
+ remote-addr 127.0.0.1
+ local-addr 127.0.0.2
+ local-port 8805
+ timer pfcp x26 5
diff --git a/hnbgw/regen_makefile.sh b/hnbgw/regen_makefile.sh
index 47f7ee83..13db985b 100755
--- a/hnbgw/regen_makefile.sh
+++ b/hnbgw/regen_makefile.sh
@@ -27,6 +27,7 @@ FILES="
RANAP_EncDec.cc
MGCP_CodecPort_CtrlFunctDef.cc
UD_PT.cc
+ PFCP_CodecPort_CtrlFunctDef.cc
"
export CPPFLAGS_TTCN3="
diff --git a/library/ranap/RANAP_Templates.ttcn b/library/ranap/RANAP_Templates.ttcn
index 11947d9a..7fac3a48 100644
--- a/library/ranap/RANAP_Templates.ttcn
+++ b/library/ranap/RANAP_Templates.ttcn
@@ -1291,6 +1291,86 @@ template RAB_SetupOrModifyList tr_RAB_SML(template (present) RAB_ID rab_id,
}
} }
+template (value) TransportLayerInformation ts_TLI_ps(template (value) TransportLayerAddress tla,
+ template (value) GTP_TEI gtp_tei) := {
+ transportLayerAddress := tla,
+ iuTransportAssociation := {
+ gTP_TEI := gtp_tei
+ },
+ iE_Extensions := omit
+}
+template TransportLayerInformation tr_TLI_ps(template TransportLayerAddress tla,
+ template (value) GTP_TEI gtp_tei) := {
+ transportLayerAddress := tla,
+ iuTransportAssociation := {
+ gTP_TEI := gtp_tei
+ },
+ iE_Extensions := *
+}
+
+template (value) RAB_SetupOrModifyList ts_RAB_SML_ps(template (value) RAB_ID rab_id,
+ template (value) TransportLayerAddress tla,
+ template (value) GTP_TEI gtp_tei) := { {
+ {
+ id := id_RAB_SetupOrModifyItem,
+ firstCriticality := reject,
+ firstValue := {
+ rAB_SetupOrModifyItemFirst := {
+ rAB_ID := rab_id,
+ nAS_SynchronisationIndicator := omit,
+ rAB_Parameters := ts_RabParams,
+ userPlaneInformation := ts_UserPlaneInfo,
+ transportLayerInformation := ts_TLI_ps(tla, gtp_tei),
+ service_Handover := omit,
+ iE_Extensions := omit
+ }
+ },
+ secondCriticality := ignore,
+ secondValue := {
+ rAB_SetupOrModifyItemSecond := {
+ pDP_TypeInformation := omit,
+ dataVolumeReportingIndication := omit,
+ dl_GTP_PDU_SequenceNumber := omit,
+ ul_GTP_PDU_SequenceNumber := omit,
+ dl_N_PDU_SequenceNumber := omit,
+ ul_N_PDU_SequenceNumber := omit,
+ iE_Extensions := omit
+ }
+ }
+ }
+} }
+template RAB_SetupOrModifyList tr_RAB_SML_ps(template (present) RAB_ID rab_id,
+ template TransportLayerAddress tla,
+ template (value) GTP_TEI gtp_tei) := { {
+ {
+ id := id_RAB_SetupOrModifyItem,
+ firstCriticality := reject,
+ firstValue := {
+ rAB_SetupOrModifyItemFirst := {
+ rAB_ID := rab_id,
+ nAS_SynchronisationIndicator := *,
+ rAB_Parameters := ts_RabParams,
+ userPlaneInformation := ts_UserPlaneInfo,
+ transportLayerInformation := tr_TLI_ps(tla, gtp_tei),
+ service_Handover := *,
+ iE_Extensions := *
+ }
+ },
+ secondCriticality := ignore,
+ secondValue := {
+ rAB_SetupOrModifyItemSecond := {
+ pDP_TypeInformation := omit,
+ dataVolumeReportingIndication := omit,
+ dl_GTP_PDU_SequenceNumber := omit,
+ ul_GTP_PDU_SequenceNumber := omit,
+ dl_N_PDU_SequenceNumber := omit,
+ ul_N_PDU_SequenceNumber := omit,
+ iE_Extensions := omit
+ }
+ }
+ }
+} }
+
template (value) RAB_SetupOrModifiedList ts_RAB_SMdL(template (value) RAB_ID rab_id,
template (value) TransportLayerAddress tla,
template (value) BindingID binding_id) := { {
@@ -1311,6 +1391,26 @@ template (value) RAB_SetupOrModifiedList ts_RAB_SMdL(template (value) RAB_ID rab
}
} }
+template (value) RAB_SetupOrModifiedList ts_RAB_SMdL_ps(template (value) RAB_ID rab_id,
+ template (value) TransportLayerAddress tla,
+ template (value) GTP_TEI gtp_tei) := { {
+ {
+ id := id_RAB_SetupOrModifiedItem,
+ criticality := ignore,
+ value_ := {
+ rAB_SetupOrModifiedItem := {
+ rAB_ID := rab_id,
+ transportLayerAddress := tla,
+ iuTransportAssociation := {
+ gTP_TEI := gtp_tei
+ },
+ dl_dataVolumes := omit,
+ iE_Extensions := omit
+ }
+ }
+ }
+} }
+
template RAB_SetupOrModifiedList tr_RAB_SMdL(template (present) RAB_ID rab_id,
template TransportLayerAddress tla,
template BindingID binding_id) := { {