GTPv2_Emulation: improve accessibility of unit-data (TEID0)

When GTPv2 unit-data is passed around, there is always the problem that
it is routed to the MTC_CT (TEID0). The reason for this is that GTPv2_Emulation
cannot determine a specific receiver component because unit-data does
not contain any addressing fields that would identifiy a specific vc_conn.

In GTPv2_Emulation there is already a mechanism implemented that detects
responses by their sequence number. Untfortunately this does only work
when the vc_conn has send a unit-data message before so that the
sequence number of the response can be guessed.

In case the first messages comes from the IUT, there is no way to
determine the receiving vc_conn, so this message is then routed to the
MCT_CT (TEID0). This can be a problem for testcases that run from inside
a ConnHdlr componet.

The solution that is proposed in this patch uses a mechanism that allows
to create an expectation for a specific messageType. When the GTPv2_Emulation
sees a unit-data message with the expected messageType, it will forward
it to all ConnHdlr (vc_conn) components that have registered for this
messageType previously.

Related: OS#5760
Change-Id: I02bb74d7bd547347168b5c64ee6512c71e8fd960
This commit is contained in:
Philipp Maier 2023-09-01 17:10:24 +02:00
parent 26a09f39bd
commit ac791564f1
1 changed files with 49 additions and 1 deletions

View File

@ -69,7 +69,9 @@ type component GTPv2_Emulation_CT {
var TidTableRec TidTable[256];
var SeqTableRec SeqTable[256];
var ImsiTableRec ImsiTable[256];
var UdMsgTableRec UdMsgTable[256];
var PidTableRec PidTable[256];
var integer g_uecups_conn_id;
};
@ -91,6 +93,12 @@ type record ImsiTableRec {
GTP2_ConnHdlr vc_conn
};
/* Unit data message type <-> ConnHdlr mapping */
type record UdMsgTableRec {
OCT1 messageType,
GTP2_ConnHdlr vc_conn
};
/* pid <-> ConnHdlr mapping (for UECUPS process termination indication) */
type record PidTableRec {
/* process ID of the running process */
@ -202,6 +210,18 @@ private function f_imsi_tbl_add(hexstring imsi, GTP2_ConnHdlr vc_conn) runs on G
testcase.stop("No Space in IMSI Table for ", imsi);
}
private function f_udmsg_tbl_add(OCT1 messageType, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT {
var integer i;
for (i := 0; i < sizeof(UdMsgTable); i := i+1) {
if (not isbound(UdMsgTable[i].messageType)) {
UdMsgTable[i].messageType := messageType;
UdMsgTable[i].vc_conn := vc_conn;
return;
}
}
testcase.stop("No Space in UdMsg Table for messateType ", messageType);
}
private function f_pid_tbl_add(integer pid, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT {
var integer i;
for (i := 0; i < sizeof(PidTable); i := i+1) {
@ -419,11 +439,27 @@ var GTP2_ConnHdlr vc_conn;
}
}
private function SendToUdMsgTable(Gtp2cUnitdata g2c_ud) runs on GTPv2_Emulation_CT {
var GTP2_ConnHdlr vc_conn;
for (var integer i := 0; i < sizeof(UdMsgTable); i := i + 1) {
if (isbound(UdMsgTable[i].messageType)) {
if (UdMsgTable[i].messageType == g2c_ud.gtpc.messageType) {
vc_conn := UdMsgTable[i].vc_conn;
CLIENT.send(g2c_ud.gtpc) to vc_conn;
}
}
}
return;
}
function main(Gtp2EmulationCfg cfg) runs on GTPv2_Emulation_CT {
var Gtp2cUnitdata g2c_ud;
var PDU_GTPCv2 g2c;
var GTP2_ConnHdlr vc_conn;
var hexstring imsi;
var OCT1 messageType;
var OCT4 teid;
var PDU_UECUPS rx_uecups;
var UECUPS_CreateTun gtc;
@ -444,6 +480,7 @@ function main(Gtp2EmulationCfg cfg) runs on GTPv2_Emulation_CT {
vc_conn := f_comp_by_seq(g2c_ud.gtpc.sequenceNumber);
CLIENT.send(g2c_ud.gtpc) to vc_conn;
} else {
SendToUdMsgTable(g2c_ud);
TEID0.send(g2c_ud.gtpc);
}
} else if (ispresent(g2c_ud.gtpc.tEID) and g2c_ud.gtpc.tEID != int2oct(0, 4)) {
@ -499,6 +536,10 @@ function main(Gtp2EmulationCfg cfg) runs on GTPv2_Emulation_CT {
f_imsi_tbl_add(imsi, vc_conn);
CLIENT_PROC.reply(GTP2EM_register_imsi:{imsi}) to vc_conn;
}
[] CLIENT_PROC.getcall(GTP2EM_register_udmsg:{?}) -> param(messageType) sender vc_conn {
f_udmsg_tbl_add(messageType, vc_conn);
CLIENT_PROC.reply(GTP2EM_register_udmsg:{messageType}) to vc_conn;
}
[] CLIENT_PROC.getcall(GTP2EM_register_teid:{?}) -> param(teid) sender vc_conn {
f_tid_tbl_add(teid, vc_conn);
@ -539,6 +580,7 @@ type port GTP2EM_PT message {
} with { extension "internal" };
signature GTP2EM_register_imsi(hexstring imsi);
signature GTP2EM_register_udmsg(OCT1 messageType);
signature GTP2EM_register_teid(OCT4 teid);
signature GTP2EM_allocate_teid() return OCT4;
signature GTP2EM_create_tunnel(UECUPS_CreateTun gtc);
@ -546,7 +588,7 @@ signature GTP2EM_destroy_tunnel(UECUPS_DestroyTun gtd);
signature GTP2EM_start_program(UECUPS_StartProgram sprog) return UECUPS_StartProgramRes;
type port GTP2EM_PROC_PT procedure {
inout GTP2EM_register_imsi, GTP2EM_register_teid, GTP2EM_allocate_teid,
inout GTP2EM_register_imsi, GTP2EM_register_udmsg, GTP2EM_register_teid, GTP2EM_allocate_teid,
GTP2EM_create_tunnel, GTP2EM_destroy_tunnel, GTP2EM_start_program;
} with { extension "internal" };
@ -565,6 +607,12 @@ function f_gtp2_register_imsi(hexstring imsi) runs on GTP2_ConnHdlr {
}
}
function f_gtp2_register_udmsg(OCT1 messageType) runs on GTP2_ConnHdlr {
GTP2_PROC.call(GTP2EM_register_udmsg:{messageType}) {
[] GTP2_PROC.getreply(GTP2EM_register_udmsg:{messageType});
}
}
function f_gtp2_register_teid(OCT4 teid) runs on GTP2_ConnHdlr {
GTP2_PROC.call(GTP2EM_register_teid:{teid}) {
[] GTP2_PROC.getreply(GTP2EM_register_teid:{teid});