Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/7623

to look at the new patch set (#2).

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
---
M ggsn_tests/GGSN_Tests.default
M ggsn_tests/GGSN_Tests.ttcn
M ggsn_tests/gen_links.sh
M ggsn_tests/regen_makefile.sh
M library/GTP_Templates.ttcn
5 files changed, 115 insertions(+), 16 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks 
refs/changes/23/7623/2

diff --git a/ggsn_tests/GGSN_Tests.default b/ggsn_tests/GGSN_Tests.default
index 2d57f89..ff0cd97 100644
--- a/ggsn_tests/GGSN_Tests.default
+++ b/ggsn_tests/GGSN_Tests.default
@@ -1,6 +1,14 @@
 [LOGGING]
 
 [TESTPORT_PARAMETERS]
+*.GGSNVTY.CTRL_MODE := "client"
+*.GGSNVTY.CTRL_HOSTNAME := "127.0.0.1"
+*.GGSNVTY.CTRL_PORTNUM := "4260"
+*.GGSNVTY.CTRL_LOGIN_SKIPPED := "yes"
+*.GGSNVTY.CTRL_DETECT_SERVER_DISCONNECTED := "yes"
+*.GGSNVTY.CTRL_READMODE := "buffered"
+*.GGSNVTY.CTRL_CLIENT_CLEANUP_LINEFEED := "yes"
+*.GGSNVTY.PROMPT1 := "OsmoGGSN> "
 
 [MODULE_PARAMETERS]
 GGSN_Tests.m_bind_ip_gtpc := "127.0.42.1"
@@ -11,5 +19,6 @@
 GGSN_Tests.m_ggsn_ip4_dns2 := "8.8.8.8"
 GGSN_Tests.m_ggsn_ip6_dns1 := "2001:4860:4860::8888"
 GGSN_Tests.m_ggsn_ip6_dns2 := "2001:4860:4860::8844"
+Osmocom_VTY_Functions.mp_prompt_prefix := "OsmoGGSN";
 
 [EXECUTE]
diff --git a/ggsn_tests/GGSN_Tests.ttcn b/ggsn_tests/GGSN_Tests.ttcn
index 2b7de96..aac9f41 100644
--- a/ggsn_tests/GGSN_Tests.ttcn
+++ b/ggsn_tests/GGSN_Tests.ttcn
@@ -14,6 +14,8 @@
        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;
@@ -70,6 +72,42 @@
                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 {
@@ -94,6 +132,9 @@
                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 */
@@ -148,8 +189,12 @@
 
        /* 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 */
@@ -539,6 +584,10 @@
                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) {
@@ -571,6 +620,10 @@
                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) {
@@ -821,8 +874,8 @@
                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)));
@@ -834,6 +887,18 @@
                f_wait_icmp4_echo_request(ctxB);
 
                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 {
@@ -853,7 +918,8 @@
                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());
diff --git a/ggsn_tests/gen_links.sh b/ggsn_tests/gen_links.sh
index 6ef52e1..4e012ae 100755
--- a/ggsn_tests/gen_links.sh
+++ b/ggsn_tests/gen_links.sh
@@ -40,9 +40,14 @@
 FILES="GTPC_EncDec.cc  GTPC_Types.ttcn  GTPU_EncDec.cc  GTPU_Types.ttcn"
 gen_links $DIR $FILES
 
+DIR=$BASEDIR/titan.TestPorts.TELNETasp/src
+FILES="TELNETasp_PT.cc  TELNETasp_PT.hh  TELNETasp_PortType.ttcn"
+gen_links $DIR $FILES
+
 DIR=../library
 FILES="General_Types.ttcn GSM_Types.ttcn Osmocom_Types.ttcn 
Native_Functions.ttcn Native_FunctionDefs.cc IPCP_Types.ttcn "
 FILES+="GTP_CodecPort.ttcn GTP_CodecPort_CtrlFunct.ttcn 
GTP_CodecPort_CtrlFunctDef.cc GTP_Templates.ttcn "
+FILES+="Osmocom_VTY_Functions.ttcn "
 gen_links $DIR $FILES
 
 ignore_pp_results
diff --git a/ggsn_tests/regen_makefile.sh b/ggsn_tests/regen_makefile.sh
index 2fc74f7..6db1a3d 100755
--- a/ggsn_tests/regen_makefile.sh
+++ b/ggsn_tests/regen_makefile.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
 
-FILES="*.ttcn IPL4asp_PT.cc  IPL4asp_discovery.cc  TCCConversion.cc  
TCCInterface.cc GTPC_EncDec.cc GTPU_EncDec.cc GTP_CodecPort_CtrlFunctDef.cc 
ICMPv6_EncDec.cc IP_EncDec.cc Native_FunctionDefs.cc UDP_EncDec.cc 
ICMP_EncDec.cc"
+FILES="*.ttcn IPL4asp_PT.cc  IPL4asp_discovery.cc  TCCConversion.cc  
TCCInterface.cc GTPC_EncDec.cc GTPU_EncDec.cc GTP_CodecPort_CtrlFunctDef.cc 
ICMPv6_EncDec.cc IP_EncDec.cc Native_FunctionDefs.cc UDP_EncDec.cc 
ICMP_EncDec.cc TELNETasp_PT.cc"
 
 ../regen-makefile.sh GGSN_Tests.ttcn $FILES
diff --git a/library/GTP_Templates.ttcn b/library/GTP_Templates.ttcn
index d8a43c2..44ec439 100644
--- a/library/GTP_Templates.ttcn
+++ b/library/GTP_Templates.ttcn
@@ -545,15 +545,39 @@
                gtpu_IEs := ies
        }
 
+       function f_GTPU_s_bit(template (omit) uint16_t seq) return BIT1 {
+               if (istemplatekind(seq, "omit")) {
+                       return '0'B;
+               }
+               return '1'B;
+       }
+
+       function f_GTPU_opt_part(template (omit) uint16_t seq) return template 
(omit) GTPU_Header_optional_part {
+               if (istemplatekind(seq, "omit")) {
+                       return omit;
+               }
+               var GTPU_Header_optional_part ret := {
+                       sequenceNumber := int2oct(valueof(seq), 2),
+                       npduNumber := '00'O,
+                       nextExtHeader := '00'O,
+                       gTPU_extensionHeader_List := omit
+               };
+               return ret;
+       }
+
        /* generalized GTP-U send template */
-       template PDU_GTPU ts_GTP1U_PDU(OCT1 msg_type, uint16_t seq, OCT4 teid, 
GTPU_IEs ies) := {
+       template PDU_GTPU ts_GTP1U_PDU(OCT1 msg_type, template (omit) uint16_t 
seq, OCT4 teid, GTPU_IEs ies) := {
                /* N-PDU Number flag (PN): the GTP-U header contains a 
meaningful N-PDU Number field if the PN
                 * flag is set to 1. */
                pn_bit := '0'B, /* we assume the encoder overwrites this if an 
optional part is given */
                /* If the Sequence Number flag (S) is set to '1' the sequence 
number field is present and
                 * meaningful otherwise it is set to '0'. For GTP-U messages 
Echo Request, Echo Response,
-                * Error Indication and Supported Extension Headers 
Notification, the S flag shall be set to '1'. */
-               s_bit := '1'B,  /* we assume the encoder overwrites this if an 
optional part is given */
+                * Error Indication and Supported Extension Headers 
Notification, the S flag shall be set to '1'.
+                *
+                * Note that the caller must ensure that these conditions hold.
+                * The caller can either pass a sequence number (we set s_bit 
to '1'B) when appropriate,
+                * or may omit the sequence number (we set s_bit to '0'B). */
+               s_bit := f_GTPU_s_bit(seq),
                /* Extension header presence */
                e_bit := '0'B,
                spare := '0'B,
@@ -564,12 +588,7 @@
                messageType := msg_type,
                lengthf := 0,   /* we assume encoder overwrites this */
                teid := teid,
-               opt_part :=  {
-                       sequenceNumber := int2oct(seq, 2),
-                       npduNumber := '00'O,
-                       nextExtHeader := '00'O,
-                       gTPU_extensionHeader_List := omit
-               },
+               opt_part := f_GTPU_opt_part(seq),
                gtpu_IEs := ies
        }
 
@@ -610,7 +629,7 @@
        }
 
        /* master template for sending a GTP-U user plane data */
-       template Gtp1uUnitdata ts_GTP1U_GPDU(GtpPeer peer, uint16_t seq, OCT4 
teid, octetstring data) := {
+       template Gtp1uUnitdata ts_GTP1U_GPDU(GtpPeer peer, template (omit) 
uint16_t seq, OCT4 teid, octetstring data) := {
                peer := peer,
                gtpu := ts_GTP1U_PDU('FF'O, seq, teid, { g_PDU_IEs := { data := 
data }})
        }

-- 
To view, visit https://gerrit.osmocom.org/7623
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I1dc299407c61b1c865035add44067b8ab89001b3
Gerrit-PatchSet: 2
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Owner: Stefan Sperling <ssperl...@sysmocom.de>
Gerrit-Reviewer: Harald Welte <lafo...@gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Pau Espin Pedrol <pes...@sysmocom.de>
Gerrit-Reviewer: Stefan Sperling <ssperl...@sysmocom.de>

Reply via email to