pespin has submitted this change. (
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/37920?usp=email )
Change subject: s1gw: Add initial PFCP support emulating UPF
......................................................................
s1gw: Add initial PFCP support emulating UPF
Change-Id: If2b135e113d2568092e90ac9b6c5f651ab30f5d0
---
M library/PFCP_Emulation.ttcn
M s1gw/ConnHdlr.ttcn
M s1gw/S1GW_Tests.ttcn
M s1gw/gen_links.sh
M s1gw/osmo-s1gw.config
M s1gw/regen_makefile.sh
6 files changed, 144 insertions(+), 32 deletions(-)
Approvals:
laforge: Looks good to me, but someone else must approve
pespin: Looks good to me, approved
Jenkins Builder: Verified
diff --git a/library/PFCP_Emulation.ttcn b/library/PFCP_Emulation.ttcn
index d5a15a2..d872367 100644
--- a/library/PFCP_Emulation.ttcn
+++ b/library/PFCP_Emulation.ttcn
@@ -199,4 +199,12 @@
}
}
+altstep as_pfcp_ignore(PFCPEM_PT pt, template PDU_PFCP pfcp_expect := ?)
+{
+ [] pt.receive(pfcp_expect) {
+ log("Ignoring ", pfcp_expect);
+ repeat;
+ }
+}
+
}
diff --git a/s1gw/ConnHdlr.ttcn b/s1gw/ConnHdlr.ttcn
index e4cff0c..12c7414 100644
--- a/s1gw/ConnHdlr.ttcn
+++ b/s1gw/ConnHdlr.ttcn
@@ -19,6 +19,11 @@
import from IPL4asp_Types all;
import from Misc_Helpers all;
+import from PFCP_Types all;
+import from PFCP_Emulation all;
+import from PFCP_Templates all;
+import from PFCP_CodecPort all;
+
import from S1AP_CodecPort all;
import from S1AP_CodecPort_CtrlFunct all;
import from S1AP_Types all;
@@ -31,13 +36,15 @@
import from SCTP_Templates all;
import from S1AP_Server all;
-type component ConnHdlr extends S1APSRV_ConnHdlr {
+type component ConnHdlr extends S1APSRV_ConnHdlr, PFCP_ConnHdlr {
+ var ConnHdlrPars g_pars;
port S1AP_CODEC_PT S1AP_ENB;
var ConnectionId g_s1ap_conn_id := -1;
};
type record of ConnHdlr ConnHdlrList;
type record ConnHdlrPars {
+ integer idx,
Global_ENB_ID genb_id
};
@@ -52,11 +59,19 @@
}
template (value) ConnHdlrPars
-t_ConnHdlrPars(integer enb_id := 0) := {
- genb_id := ts_Global_ENB_ID(enb_id)
+t_ConnHdlrPars(integer idx := 0) := {
+ idx := idx,
+ genb_id := ts_Global_ENB_ID(idx)
}
-type function void_fn(ConnHdlrPars pars) runs on ConnHdlr;
+type function void_fn(charstring id) runs on ConnHdlr;
+
+function f_ConnHdlr_init(void_fn fn, charstring id, ConnHdlrPars pars)
+runs on ConnHdlr {
+ g_pars := pars;
+ fn.apply(id);
+}
+
function f_ConnHdlr_connect(charstring local_addr, charstring remote_addr) runs on
ConnHdlr {
var Result res;
@@ -209,4 +224,50 @@
}
}
+altstep as_pfcp_handle_assoc_setup_req(template (present) PDU_PFCP exp_rx :=
tr_PFCP_Assoc_Setup_Req(), boolean do_repeat := false)
+runs on ConnHdlr
+{
+ var PDU_PFCP rx;
+
+ [] PFCP.receive(exp_rx) -> value rx {
+ var Node_ID upf_node_id :=
valueof(ts_PFCP_Node_ID_fqdn("\07osmocom\03org"));
+ PFCP.send(ts_PFCP_Assoc_Setup_Resp(rx.sequence_number, upf_node_id,
+ ts_PFCP_Cause(REQUEST_ACCEPTED),
+ 1234));
+ if (do_repeat) {
+ repeat;
+ }
+ }
+}
+
+private function f_pfcp_wait_assoc_setup(template (present) PDU_PFCP exp_rx :=
tr_PFCP_Assoc_Setup_Req(),
+ float wait_time := 10.0)
+runs on ConnHdlr
+{
+ timer T := wait_time;
+ T.start;
+ alt {
+ [] as_pfcp_handle_assoc_setup_req(exp_rx);
+ [] PFCP.receive(PDU_PFCP:?) {
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+ log2str("Got an unexpected PFCP message, was waiting for ", exp_rx));
+ }
+ [] T.timeout {
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+ log2str("Timeout waiting for PFCP ", exp_rx));
+ }
+ }
+ T.stop;
+}
+
+function f_ConnHdlr_register_pfcp() runs on ConnHdlr
+{
+ f_pfcp_register();
+ if (g_pars.idx == 0) {
+ /* First ConnHdlr answers the AssocSetup: */
+ activate(as_pfcp_handle_assoc_setup_req(do_repeat := true));
+ } else {
+ activate(as_pfcp_ignore(PFCP, tr_PFCP_Assoc_Setup_Req()));
+ }
+}
}
diff --git a/s1gw/S1GW_Tests.ttcn b/s1gw/S1GW_Tests.ttcn
index 1f4bb71..9448ed5 100644
--- a/s1gw/S1GW_Tests.ttcn
+++ b/s1gw/S1GW_Tests.ttcn
@@ -28,20 +28,28 @@
import from S1AP_PDU_Contents all;
import from S1AP_Constants all;
+import from PFCP_Types all;
+import from PFCP_Emulation all;
+import from PFCP_Templates all;
+import from PFCP_CodecPort all;
+
import from SCTP_Templates all;
import from S1AP_Server all;
import from ConnHdlr all;
modulepar {
- charstring mp_s1gw_enb_ip; /* eNB facing address of the S1GW */
- charstring mp_s1gw_mme_ip; /* MME facing address of the S1GW */
- charstring mp_enb_bind_ip; /* eNB address to use locally when connecting to S1GW */
- charstring mp_mme_bind_ip; /* MME address on which we get connections from S1GW */
+ charstring mp_s1gw_enb_ip := "127.0.1.1"; /* eNB facing address of the S1GW
*/
+ charstring mp_s1gw_mme_ip := "127.0.2.1"; /* MME facing address of the S1GW
*/
+ charstring mp_s1gw_upf_ip := "127.0.3.1"; /* UPF facing address of the S1GW
*/
+ charstring mp_enb_bind_ip := "127.0.1.10"; /* eNB address to use locally when
connecting to S1GW */
+ charstring mp_mme_bind_ip := "127.0.2.10"; /* MME address on which we get
connections from S1GW */
+ charstring mp_upf_bind_ip := "127.0.3.10"; /* UPF address on which we get
connections from S1GW */
}
type component test_CT {
timer g_Tguard;
var S1AP_Server_CT vc_S1APSRV;
+ var PFCP_Emulation_CT vc_PFCP;
};
private altstep as_Tguard() runs on test_CT {
@@ -50,9 +58,18 @@
}
}
-function f_init(float Tval := 20.0) runs on test_CT {
+function f_init(boolean s1apsrv_start := true,
+ boolean upf_start := true,
+ float Tval := 20.0) runs on test_CT {
g_Tguard.start(Tval);
activate(as_Tguard());
+
+ if (s1apsrv_start) {
+ f_init_s1ap_srv();
+ }
+ if (upf_start) {
+ f_init_pfcp();
+ }
}
function f_init_s1ap_srv() runs on test_CT {
@@ -65,36 +82,54 @@
vc_S1APSRV.start(S1AP_Server.main(cpars));
}
+function f_init_pfcp() runs on test_CT {
+ var PFCP_Emulation_Cfg pfcp_cfg := {
+ pfcp_bind_ip := mp_upf_bind_ip,
+ pfcp_bind_port := PFCP_PORT,
+ pfcp_remote_ip := mp_s1gw_upf_ip,
+ pfcp_remote_port := PFCP_PORT,
+ role := UPF
+ };
+
+ vc_PFCP := PFCP_Emulation_CT.create("PFCP-" & testcasename()) alive;
+ vc_PFCP.start(PFCP_Emulation.main(pfcp_cfg));
+}
+
function f_ConnHdlr_spawn(void_fn fn, ConnHdlrPars pars)
runs on test_CT return ConnHdlr {
var ConnHdlr vc_conn;
+ var charstring id := "ConnHdlr-" & testcasename() & "-"
& int2str(pars.idx);
- vc_conn := ConnHdlr.create("ConnHdlr-" & testcasename()) alive;
- if (vc_S1APSRV.running) {
+ vc_conn := ConnHdlr.create(id) alive;
+ if (isbound(vc_S1APSRV) and vc_S1APSRV.running) {
connect(vc_conn:S1AP_CONN, vc_S1APSRV:S1AP_CLIENT);
connect(vc_conn:S1AP_PROC, vc_S1APSRV:S1AP_PROC);
}
- vc_conn.start(derefers(fn)(pars));
+ if (isbound(vc_PFCP) and vc_PFCP.running) {
+ connect(vc_conn:PFCP, vc_PFCP:CLIENT);
+ connect(vc_conn:PFCP_PROC, vc_PFCP:CLIENT_PROC);
+ }
+ vc_conn.start(f_ConnHdlr_init(fn, id, pars));
return vc_conn;
}
-function f_TC_setup(ConnHdlrPars pars) runs on ConnHdlr {
- f_ConnHdlr_register(pars.genb_id);
+function f_TC_setup(charstring id) runs on ConnHdlr {
+ f_ConnHdlr_register_pfcp();
+ f_ConnHdlr_register(g_pars.genb_id);
f_ConnHdlr_connect(mp_enb_bind_ip, mp_s1gw_enb_ip);
- f_ConnHdlr_setup(pars.genb_id);
+ f_ConnHdlr_setup(g_pars.genb_id);
f_sleep(0.5); /* keep the connection idle for some time */
f_ConnHdlr_disconnect();
- f_ConnHdlr_unregister(pars.genb_id);
+ f_ConnHdlr_unregister(g_pars.genb_id);
}
testcase TC_setup() runs on test_CT {
var ConnHdlrPars pars := valueof(t_ConnHdlrPars);
var ConnHdlr vc_conn;
f_init();
- f_init_s1ap_srv();
vc_conn := f_ConnHdlr_spawn(refers(f_TC_setup), pars);
vc_conn.done;
@@ -103,7 +138,6 @@
var ConnHdlrList vc_conns := { };
f_init();
- f_init_s1ap_srv();
for (var integer i := 0; i < 42; i := i + 1) {
var ConnHdlrPars pars := valueof(t_ConnHdlrPars(i));
@@ -118,26 +152,26 @@
/* MME terminates connection, expect S1GW to terminate the eNB connection */
-function f_TC_conn_term_by_mme(ConnHdlrPars pars) runs on ConnHdlr {
- f_ConnHdlr_register(pars.genb_id);
+function f_TC_conn_term_by_mme(charstring id) runs on ConnHdlr {
+ f_ConnHdlr_register_pfcp();
+ f_ConnHdlr_register(g_pars.genb_id);
f_ConnHdlr_connect(mp_enb_bind_ip, mp_s1gw_enb_ip);
- f_ConnHdlr_setup(pars.genb_id);
+ f_ConnHdlr_setup(g_pars.genb_id);
f_sleep(0.5); /* keep the connection idle for some time */
/* MME (S1AP_Server_CT) terminates connection */
- f_ConnHdlr_close_conn(pars.genb_id);
+ f_ConnHdlr_close_conn(g_pars.genb_id);
/* expect our eNB connection to be released gracefully */
f_ConnHdlr_expect_shutdown();
- f_ConnHdlr_unregister(pars.genb_id);
+ f_ConnHdlr_unregister(g_pars.genb_id);
}
testcase TC_conn_term_by_mme() runs on test_CT {
var ConnHdlrPars pars := valueof(t_ConnHdlrPars);
var ConnHdlr vc_conn;
f_init();
- f_init_s1ap_srv();
vc_conn := f_ConnHdlr_spawn(refers(f_TC_conn_term_by_mme), pars);
vc_conn.done;
@@ -145,7 +179,8 @@
/* MME is not available, expect S1GW to terminate the eNB connection */
-function f_TC_conn_term_mme_unavail(ConnHdlrPars pars) runs on ConnHdlr {
+function f_TC_conn_term_mme_unavail(charstring id) runs on ConnHdlr {
+ f_ConnHdlr_register_pfcp();
/* establish an eNB connection to the S1GW */
f_ConnHdlr_connect(mp_enb_bind_ip, mp_s1gw_enb_ip);
/* expect our eNB connection to be released gracefully */
@@ -156,21 +191,22 @@
var ConnHdlrPars pars := valueof(t_ConnHdlrPars);
var ConnHdlr vc_conn;
- f_init();
+ f_init(s1apsrv_start := false);
vc_conn := f_ConnHdlr_spawn(refers(f_TC_conn_term_mme_unavail), pars);
vc_conn.done;
}
-function f_TC_e_rab_setup(ConnHdlrPars pars) runs on ConnHdlr {
+function f_TC_e_rab_setup(charstring id) runs on ConnHdlr {
const integer mme_id := 7;
const integer enb_id := 9;
const integer erab_id := 6;
var S1AP_PDU pdu;
- f_ConnHdlr_register(pars.genb_id);
+ f_ConnHdlr_register_pfcp();
+ f_ConnHdlr_register(g_pars.genb_id);
f_ConnHdlr_connect(mp_enb_bind_ip, mp_s1gw_enb_ip);
- f_ConnHdlr_setup(pars.genb_id);
+ f_ConnHdlr_setup(g_pars.genb_id);
log("eNB <- [S1GW] <- MME: E-RAB SETUP REQUEST");
var template (value) E_RABToBeSetupListBearerSUReq items_req;
@@ -224,14 +260,13 @@
f_ConnHdlr_rx_s1ap_from_enb(pdu, tr_S1AP_RABSetupRsp(mme_id, enb_id, items_res));
f_ConnHdlr_disconnect();
- f_ConnHdlr_unregister(pars.genb_id);
+ f_ConnHdlr_unregister(g_pars.genb_id);
}
testcase TC_e_rab_setup() runs on test_CT {
var ConnHdlrPars pars := valueof(t_ConnHdlrPars);
var ConnHdlr vc_conn;
f_init();
- f_init_s1ap_srv();
vc_conn := f_ConnHdlr_spawn(refers(f_TC_e_rab_setup), pars);
vc_conn.done;
diff --git a/s1gw/gen_links.sh b/s1gw/gen_links.sh
index fd54815..ef8bdde 100755
--- a/s1gw/gen_links.sh
+++ b/s1gw/gen_links.sh
@@ -17,6 +17,10 @@
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
+DIR=$BASEDIR/titan.ProtocolModules.PFCP_v15.1.0/src
+FILES="PFCP_Types.ttcn"
+gen_links $DIR $FILES
+
DIR=../library/s1ap
FILES="S1AP_CommonDataTypes.asn S1AP_Constants.asn S1AP_Containers.asn S1AP_IEs.asn
"
FILES+="S1AP_PDU_Contents.asn S1AP_PDU_Descriptions.asn "
@@ -25,6 +29,7 @@
DIR=../library
FILES="Misc_Helpers.ttcn General_Types.ttcn Osmocom_Types.ttcn Native_Functions.ttcn
Native_FunctionDefs.cc IPCP_Types.ttcn "
+FILES+="PFCP_CodecPort.ttcn PFCP_CodecPort_CtrlFunct.ttcn
PFCP_CodecPort_CtrlFunctDef.cc PFCP_Emulation.ttcn PFCP_Templates.ttcn "
FILES+="S1AP_CodecPort.ttcn S1AP_CodecPort_CtrlFunctDef.cc
S1AP_CodecPort_CtrlFunct.ttcn "
FILES+="SCTP_Templates.ttcn "
gen_links $DIR $FILES
diff --git a/s1gw/osmo-s1gw.config b/s1gw/osmo-s1gw.config
index f4a4a73..a04d1cf 100644
--- a/s1gw/osmo-s1gw.config
+++ b/s1gw/osmo-s1gw.config
@@ -13,7 +13,9 @@
{osmo_s1gw,
[{s1gw_bind_addr, "127.0.1.1"}, %% S1GW bind address for incoming eNB
connections
{mme_loc_addr, "127.0.2.1"}, %% local address for outgoing connections to
the MME
- {mme_rem_addr, "127.0.2.10"} %% remote address for outgoing connections to
the MME
+ {mme_rem_addr, "127.0.2.10"}, %% remote address for outgoing connections to
the MME
+ {pfcp_loc_addr, "127.0.3.1"}, %% local address for outgoing connections to
the UPF
+ {pfcp_rem_addr, "127.0.3.10"} %% local address for outgoing connections to
the UPF
]},
%% ================================================================================
%% kernel config
diff --git a/s1gw/regen_makefile.sh b/s1gw/regen_makefile.sh
index 7eef51b..8c32b3d 100755
--- a/s1gw/regen_makefile.sh
+++ b/s1gw/regen_makefile.sh
@@ -8,6 +8,7 @@
IPL4asp_PT.cc
IPL4asp_discovery.cc
Native_FunctionDefs.cc
+ PFCP_CodecPort_CtrlFunctDef.cc
S1AP_CodecPort_CtrlFunctDef.cc
S1AP_EncDec.cc
TCCConversion.cc
--
To view, visit
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/37920?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: If2b135e113d2568092e90ac9b6c5f651ab30f5d0
Gerrit-Change-Number: 37920
Gerrit-PatchSet: 5
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>