From c479e4fa3bdd2a31693b6a84bf72992d25d6f37f Mon Sep 17 00:00:00 2001 From: Stefan Sperling Date: Tue, 3 Apr 2018 19:34:16 +0200 Subject: test GGSN support for optional GTP-U sequence numbers Add VTY functionality to GGSN tests, and use the VTY to enable/disable GTP-U Tx sequence numbers in the running osmo-ggsn. The GTPU packet template now makes sequence numbers optional. A template created with its sequence number set to 'omit' will result in a packet without a sequence number, i.e. the 'sequence number present' bit in the packet header is cleared, and the sequence number field is omitted from the encoded GTPU T-PDU packet. Re-use the existing TC_pdp4_clients_interact() test for testing the behaviour of osmo-ggsn. This test is now run twice, once with and once without GTP-U Tx sequence numbers. Verify that packets relayed by osmo-ggsn match its "g-pdu tx-sequence-numbers" configuration setting. Change-Id: I1dc299407c61b1c865035add44067b8ab89001b3 Related: OS#2519 --- ggsn_tests/GGSN_Tests.ttcn | 76 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 5 deletions(-) (limited to 'ggsn_tests/GGSN_Tests.ttcn') diff --git a/ggsn_tests/GGSN_Tests.ttcn b/ggsn_tests/GGSN_Tests.ttcn index 14690628..ba8fae5d 100644 --- a/ggsn_tests/GGSN_Tests.ttcn +++ b/ggsn_tests/GGSN_Tests.ttcn @@ -14,6 +14,8 @@ module GGSN_Tests { import from ICMP_Types all; import from ICMPv6_Types all; import from Native_Functions all; + import from Osmocom_VTY_Functions all; + import from TELNETasp_PortType all; const integer GTP0_PORT := 3386; const integer GTP1C_PORT := 2123; @@ -89,6 +91,42 @@ module GGSN_Tests { var uint16_t g_c_seq_nr; /* next to-be-sent GTP-U sequence number */ var uint16_t g_d_seq_nr; + + port TELNETasp_PT GGSNVTY; + var boolean use_gptu_txseq := true; + } + + private function f_init_vty() runs on GT_CT { + map(self:GGSNVTY, system:GGSNVTY); + f_vty_set_prompts(GGSNVTY); + f_vty_transceive(GGSNVTY, "enable"); + } + + private function f_vty_set_gpdu_txseq(boolean enable) runs on GT_CT { + f_vty_enter_config(GGSNVTY); + f_vty_transceive(GGSNVTY, "ggsn ggsn0"); + f_vty_transceive(GGSNVTY, "apn internet"); + if (enable) { + f_vty_transceive(GGSNVTY, "g-pdu tx-sequence-numbers"); + } else { + f_vty_transceive(GGSNVTY, "no g-pdu tx-sequence-numbers"); + } + f_vty_transceive(GGSNVTY, "end"); + } + + private function f_verify_gtpu_txseq(in PDU_GTPU gtpu, in boolean expect_gptu_txseq) return boolean { + if (expect_gptu_txseq) { + if (gtpu.s_bit != '1'B) { + log("GTPU sequence number expected but not present") + return false; + } + } else { + if (gtpu.s_bit != '0'B) { + log("GTPU sequence number not expected but present") + return false; + } + } + return true; } function f_init() runs on GT_CT { @@ -113,6 +151,9 @@ module GGSN_Tests { g_restart_ctr := f_rnd_octstring(1); g_c_seq_nr := f_rnd_int(65535); g_d_seq_nr := f_rnd_int(65535); + + f_init_vty(); + f_vty_set_gpdu_txseq(use_gptu_txseq); } /* Altstep implementing responses to any incoming echo requests */ @@ -167,8 +208,12 @@ module GGSN_Tests { /* send GTP-U for a given context and increment sequence number */ function f_send_gtpu(inout PdpContext ctx, in octetstring data) runs on GT_CT { - GTPU.send(ts_GTP1U_GPDU(g_peer_u, g_d_seq_nr, ctx.teid_remote, data)); - g_d_seq_nr := g_d_seq_nr + 1; + if (use_gptu_txseq) { + GTPU.send(ts_GTP1U_GPDU(g_peer_u, g_d_seq_nr, ctx.teid_remote, data)); + g_d_seq_nr := g_d_seq_nr + 1; + } else { + GTPU.send(ts_GTP1U_GPDU(g_peer_u, omit, ctx.teid_remote, data)); + } } /* send a PDP context activation */ @@ -558,6 +603,10 @@ module GGSN_Tests { T_default.start; alt { [] GTPU.receive(tr_GTPU_GPDU(g_peer_u, ?)) -> value ud { + if (f_verify_gtpu_txseq(ud.gtpu, use_gptu_txseq) == false) { + setverdict(fail); + stop; + } var octetstring gpdu := ud.gtpu.gtpu_IEs.g_PDU_IEs.data; var IPv4_packet ip4 := f_IPv4_dec(gpdu); if (ip4.header.ver != 4) { @@ -590,6 +639,10 @@ module GGSN_Tests { T_default.start; alt { [] GTPU.receive(tr_GTPU_GPDU(g_peer_u, ?)) -> value ud { + if (f_verify_gtpu_txseq(ud.gtpu, use_gptu_txseq) == false) { + setverdict(fail); + stop; + } var octetstring gpdu := ud.gtpu.gtpu_IEs.g_PDU_IEs.data; var IPv6_packet ip6 := f_IPv6_dec(gpdu); if (ip6.header.ver != 6 or ip6.header.nexthead != 58) { @@ -840,8 +893,8 @@ module GGSN_Tests { f_pdp_ctx_del(ctx, '1'B); } - /* Validate if different clients (pdp ctx) can reach one another through GGSN. */ - testcase TC_pdp4_clients_interact() runs on GT_CT { + /* Helper function for tests below. */ + function f_pdp4_clients_interact() runs on GT_CT { f_init(); var PdpContext ctxA := valueof(t_DefinePDP(f_rnd_imsi('26242'H), '1234'O, c_ApnInternet, valueof(t_EuaIPv4Dyn))); var PdpContext ctxB := valueof(t_DefinePDP(f_rnd_imsi('26242'H), '1234'O, c_ApnInternet, valueof(t_EuaIPv4Dyn))); @@ -855,6 +908,18 @@ module GGSN_Tests { f_pdp_ctx_del(ctxA, '1'B); } + /* Validate if different clients (pdp ctx) can reach one another through GGSN. */ + testcase TC_pdp4_clients_interact_with_txseq() runs on GT_CT { + use_gptu_txseq := true; + f_pdp4_clients_interact(); + } + + /* Validate if different clients (pdp ctx) can reach one another through GGSN (without Tx sequence number). */ + testcase TC_pdp4_clients_interact_without_txseq() runs on GT_CT { + use_gptu_txseq := false; + f_pdp4_clients_interact(); + } + testcase TC_echo_req_resp() runs on GT_CT { f_init(); f_send_gtpc(ts_GTPC_PING(g_peer_c, g_c_seq_nr)); @@ -872,7 +937,8 @@ module GGSN_Tests { execute(TC_pdp4_act_deact_ipcp()); execute(TC_pdp4_act_deact_pcodns()); execute(TC_pdp4_act_deact_gtpu_access()); - execute(TC_pdp4_clients_interact()); + execute(TC_pdp4_clients_interact_with_txseq()); + execute(TC_pdp4_clients_interact_without_txseq()); execute(TC_pdp6_act_deact()); execute(TC_pdp6_act_deact_pcodns()); -- cgit v1.2.3