blob: 8672947f0139b0f2e9c46e7f560a01dbcd8b73f8 [file] [log] [blame]
Harald Welte379d45a2017-08-03 09:55:15 +02001module GGSN_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* GGSN test suite in TTCN-3
4 * (C) 2017-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Pau Espin Pedrold25095f2022-05-18 16:29:05 +020014 import from TCCEncoding_Functions all;
Harald Welte34b5a952019-05-27 11:54:11 +020015
Harald Welte94ade362017-08-04 00:36:55 +020016 import from General_Types all;
Harald Welte811651e2017-08-05 15:25:06 +020017 import from Osmocom_Types all;
Pau Espin Pedrolc04c69e2020-03-03 16:46:29 +010018 import from Misc_Helpers all;
Harald Welte94ade362017-08-04 00:36:55 +020019 import from IPL4asp_PortType all;
20 import from IPL4asp_Types all;
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +010021 import from GTPv1C_CodecPort all;
22 import from GTPv1U_CodecPort all;
23 import from GTPv1C_CodecPort_CtrlFunct all;
24 import from GTPv1U_CodecPort_CtrlFunct all;
Harald Welte94ade362017-08-04 00:36:55 +020025 import from GTPC_Types all;
26 import from GTPU_Types all;
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +010027 import from GTPv1C_Templates all;
28 import from GTPv1U_Templates all;
Harald Welte71a36022017-12-04 18:55:58 +010029 import from IPCP_Types all;
Harald Weltef8298542019-04-10 10:15:28 +020030 import from PAP_Types all;
Harald Welte231b9412017-08-09 17:16:31 +020031 import from IP_Types all;
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +010032 import from ICMP_Types all;
Harald Welte231b9412017-08-09 17:16:31 +020033 import from ICMPv6_Types all;
Pau Espin Pedrole16e9282024-03-01 14:45:22 +010034 import from ICMP_Templates all;
35 import from ICMPv6_Templates all;
Harald Welteddeecbb2017-08-18 22:53:30 +020036 import from Native_Functions all;
Stefan Sperlingc479e4f2018-04-03 19:34:16 +020037 import from Osmocom_VTY_Functions all;
38 import from TELNETasp_PortType all;
Harald Welte94ade362017-08-04 00:36:55 +020039
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +010040 import from DIAMETER_Types all;
41 import from DIAMETER_Templates all;
Pau Espin Pedrol867b1302024-01-24 16:14:28 +010042 import from DIAMETER_ts29_212_Templates all;
Pau Espin Pedrol117a94f2023-12-21 16:10:12 +010043 import from DIAMETER_ts29_272_Templates all;
Pau Espin Pedrol867b1302024-01-24 16:14:28 +010044 import from DIAMETER_ts32_299_Templates all;
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +010045 import from DIAMETER_Emulation all;
46
Harald Welte94ade362017-08-04 00:36:55 +020047 const integer GTP0_PORT := 3386;
48 const integer GTP1C_PORT := 2123;
49 const integer GTP1U_PORT := 2152;
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +010050 const integer PCRF_PORT := 3868;
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +010051 const integer OCS_PORT := 3869;
Harald Welteddeecbb2017-08-18 22:53:30 +020052
Pau Espin Pedrolc1b1ddf2022-01-19 18:10:30 +010053 type enumerated GGSN_Impl {
54 GGSN_IMPL_OSMOCOM,
55 GGSN_IMPL_OPEN5GS
56 };
57
Oliver Smithb8561082024-03-22 11:21:10 +010058 type enumerated GGSN_Conf {
59 GGSN_CONF_ALL,
60 GGSN_CONF_V4_ONLY,
61 GGSN_CONF_V6_ONLY,
62 GGSN_CONF_V4V6_ONLY
63 };
64
Harald Welteddeecbb2017-08-18 22:53:30 +020065 modulepar {
Stefan Sperlingcb782b92018-04-03 16:03:15 +020066 /* Default IP addresses. May be overridden by GGSN_Tests configuration files. */
67
68 /* The SGSN simulated by TTCN3 will bind to these addresses for GTP control and GTP user planes. */
Harald Welteddeecbb2017-08-18 22:53:30 +020069 charstring m_bind_ip_gtpc := "127.23.42.1";
70 charstring m_bind_ip_gtpu := "127.23.42.1";
71
Stefan Sperlingcb782b92018-04-03 16:03:15 +020072 /* Addresses the GGSN which is being tested is listening on for SGSN connections. */
Harald Welteddeecbb2017-08-18 22:53:30 +020073 charstring m_ggsn_ip_gtpc := "127.0.0.6";
74 charstring m_ggsn_ip_gtpu := "127.0.0.6";
Pau Espin Pedrolf69a4382018-01-29 13:09:00 +010075
Stefan Sperlingcb782b92018-04-03 16:03:15 +020076 /*
77 * Our tests expect to see these DNS servers in 'Create PDP context responses' sent by the GGSN.
78 * These addresses must therefore match 'ip[v6] dns' options configured in osmo-ggsn.conf.
79 *
80 * These addresses are not expected to serve actual DNS requests. However, tests may expect to be
81 * able to ping these addresses (currently, IPv4 addresses must respond with an ICMP 'echo reply',
82 * and IPv6 addresses may respond with either ICMPv6 'echo reply' or 'destination unreachable').
83 */
Pau Espin Pedrolf69a4382018-01-29 13:09:00 +010084 charstring m_ggsn_ip4_dns1 := "192.168.100.1"
85 charstring m_ggsn_ip4_dns2 := "8.8.8.8"
Pau Espin Pedrol363ba482018-01-29 18:42:00 +010086 charstring m_ggsn_ip6_dns1 := "2001:4860:4860::8888"
87 charstring m_ggsn_ip6_dns2 := "2001:4860:4860::8844"
Stefan Sperlingcb782b92018-04-03 16:03:15 +020088
89 /*
90 * Additional address ranges are defined in osmo-ggsn.conf from which addresses are assigned
91 * to MS "behind" the simulated SGSN. These addresses appear on tun devices used by osmo-ggsn.
92 * The tests expect to be able to send ping packets between any two simulated MS within the same
93 * address range. This requires IP forwarding to be enabled on the corresponding tun interfaces.
94 */
Pau Espin Pedrolbfad97f2022-11-04 12:03:17 +010095 integer mp_t3_response := 5; /* local T3-RESPONSE timeout, seconds */
96 integer mp_n3_requests := 3; /* local N3-REQUESTS counter */
Pau Espin Pedrolc1b1ddf2022-01-19 18:10:30 +010097
98 GGSN_Impl m_ggsn_impl := GGSN_IMPL_OSMOCOM;
Oliver Smithb8561082024-03-22 11:21:10 +010099 GGSN_Conf m_ggsn_conf := GGSN_CONF_ALL;
Harald Welteddeecbb2017-08-18 22:53:30 +0200100 }
Harald Welte94ade362017-08-04 00:36:55 +0200101
Harald Welte811651e2017-08-05 15:25:06 +0200102 type set PdpContext {
103 hexstring imsi,
104 octetstring msisdn optional,
105 octetstring apn,
Harald Welteed7a1772017-08-09 20:26:20 +0200106 ProtConfigOptions pco_req optional,
107 ProtConfigOptions pco_neg optional,
Harald Welte811651e2017-08-05 15:25:06 +0200108 EndUserAddress eua,
Harald Welte231b9412017-08-09 17:16:31 +0200109 OCT16 ip6_prefix optional,
Harald Welte811651e2017-08-05 15:25:06 +0200110 BIT4 nsapi,
111 /* TEI (Data) local side */
112 OCT4 teid,
113 /* TEI (Control) local side */
114 OCT4 teic,
115 /* TEI (Data) remote side */
116 OCT4 teid_remote,
117 /* TEI (Control) remote side */
Pau Espin Pedrol38aeffb2022-02-01 20:46:29 +0100118 OCT4 teic_remote,
Pau Espin Pedrolca587f12022-02-02 10:42:01 +0100119 OCT1 ratType optional,
Pau Espin Pedrol0e127872022-05-12 17:58:50 +0200120 UserLocationInformation uli optional,
Pau Espin Pedrol38968e92022-05-13 16:17:48 +0200121 OCT2 charging_char optional,
Pau Espin Pedrol535ca262022-05-16 14:07:17 +0200122 OCT8 imeisv optional,
123 MS_TimeZone ms_tz optional
Harald Welte811651e2017-08-05 15:25:06 +0200124 }
125
Harald Welte94ade362017-08-04 00:36:55 +0200126 type component GT_CT {
127 port GTPC_PT GTPC;
128 port GTPU_PT GTPU;
129
Harald Welte0be142b2017-08-13 13:28:10 +0200130 var boolean g_initialized := false;
131
Harald Welte94ade362017-08-04 00:36:55 +0200132 var OCT1 g_restart_ctr := '01'O;
133 /* FIXME: unify with g_bind_ip + parse from config file */
Harald Welteddeecbb2017-08-18 22:53:30 +0200134 var OCT4 g_sgsn_ip_c;
135 var OCT4 g_sgsn_ip_u;
Harald Welte94ade362017-08-04 00:36:55 +0200136 /* FIXME: parse remName from config file */
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +0100137 var Gtp1cPeer g_peer_c := { connId := 0, remName := m_ggsn_ip_gtpc, remPort := GTP1C_PORT };
138 var Gtp1uPeer g_peer_u := { connId := 0, remName := m_ggsn_ip_gtpu, remPort := GTP1U_PORT };
Harald Welte94ade362017-08-04 00:36:55 +0200139 timer T_default := 3.0;
Harald Welte5438b9d2017-08-13 13:27:48 +0200140
141 /* next to-be-sent GTP-C sequence number */
142 var uint16_t g_c_seq_nr;
143 /* next to-be-sent GTP-U sequence number */
144 var uint16_t g_d_seq_nr;
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200145
146 port TELNETasp_PT GGSNVTY;
Harald Welted2394e92018-04-26 10:21:49 +0200147 var boolean use_gtpu_txseq := false;
Pau Espin Pedrol05118022022-02-17 19:49:13 +0100148 var integer g_use_echo_intval := 0; /* 0 = disabled */
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100149
Pau Espin Pedrol733369a2022-05-20 18:39:55 +0200150 /* Emulated PCRF, used with m_ggsn_impl = GGSN_IMPL_OPEN5GS */
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200151 var DIAMETER_conn_parameters g_gx_pars;
Pau Espin Pedrol45d57022022-03-08 13:49:02 +0100152 var DIAMETER_Emulation_CT vc_Gx;
153 port DIAMETER_PT Gx_UNIT;
154 port DIAMETEREM_PROC_PT Gx_PROC;
Pau Espin Pedrol733369a2022-05-20 18:39:55 +0200155
156 /* Emulated OCS, used with m_ggsn_impl = GGSN_IMPL_OPEN5GS */
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200157 var DIAMETER_conn_parameters g_gy_pars;
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100158 var DIAMETER_Emulation_CT vc_Gy;
159 port DIAMETER_PT Gy_UNIT;
160 port DIAMETEREM_PROC_PT Gy_PROC;
161 var integer g_gy_validity_time := 0; /* In seconds. 0 => disabled, !0 => grant over CC-Time period */
Pau Espin Pedrol52562c92022-05-23 15:45:46 +0200162 var integer g_gy_volume_threshold := 0; /* In octets. 0 => disabled, !0 => request IUT to revalidate after N octets */
Pau Espin Pedrol8fa22842022-05-20 14:47:55 +0200163 var PDU_DIAMETER g_rx_gy; /* Store last received Gy message */
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200164 }
165
166 private function f_init_vty() runs on GT_CT {
167 map(self:GGSNVTY, system:GGSNVTY);
168 f_vty_set_prompts(GGSNVTY);
169 f_vty_transceive(GGSNVTY, "enable");
170 }
171
172 private function f_vty_set_gpdu_txseq(boolean enable) runs on GT_CT {
173 f_vty_enter_config(GGSNVTY);
174 f_vty_transceive(GGSNVTY, "ggsn ggsn0");
Pau Espin Pedrol205a3842018-07-06 13:24:14 +0200175
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200176 f_vty_transceive(GGSNVTY, "apn internet");
177 if (enable) {
178 f_vty_transceive(GGSNVTY, "g-pdu tx-sequence-numbers");
179 } else {
180 f_vty_transceive(GGSNVTY, "no g-pdu tx-sequence-numbers");
181 }
Pau Espin Pedrol205a3842018-07-06 13:24:14 +0200182 f_vty_transceive(GGSNVTY, "exit");
183
184 f_vty_transceive(GGSNVTY, "apn inet6");
185 if (enable) {
186 f_vty_transceive(GGSNVTY, "g-pdu tx-sequence-numbers");
187 } else {
188 f_vty_transceive(GGSNVTY, "no g-pdu tx-sequence-numbers");
189 }
190 f_vty_transceive(GGSNVTY, "exit");
191
192 f_vty_transceive(GGSNVTY, "apn inet46");
193 if (enable) {
194 f_vty_transceive(GGSNVTY, "g-pdu tx-sequence-numbers");
195 } else {
196 f_vty_transceive(GGSNVTY, "no g-pdu tx-sequence-numbers");
197 }
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200198 f_vty_transceive(GGSNVTY, "end");
199 }
200
201 private function f_verify_gtpu_txseq(in PDU_GTPU gtpu, in boolean expect_gptu_txseq) return boolean {
202 if (expect_gptu_txseq) {
203 if (gtpu.s_bit != '1'B) {
204 log("GTPU sequence number expected but not present")
205 return false;
206 }
207 } else {
208 if (gtpu.s_bit != '0'B) {
209 log("GTPU sequence number not expected but present")
210 return false;
211 }
212 }
213 return true;
Harald Welte94ade362017-08-04 00:36:55 +0200214 }
215
Pau Espin Pedrol05118022022-02-17 19:49:13 +0100216 private function f_vty_enable_echo_interval(integer intval_sec) runs on GT_CT {
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +0200217 f_vty_enter_config(GGSNVTY);
218 f_vty_transceive(GGSNVTY, "ggsn ggsn0");
Pau Espin Pedrol05118022022-02-17 19:49:13 +0100219 if (intval_sec > 0) {
220 f_vty_transceive(GGSNVTY, "echo-interval " & int2str(intval_sec));
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +0200221 } else {
222 f_vty_transceive(GGSNVTY, "no echo-interval");
223 }
224 f_vty_transceive(GGSNVTY, "end");
225 }
226
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100227 private function DiameterForwardUnitdataCallback(PDU_DIAMETER msg)
228 runs on DIAMETER_Emulation_CT return template PDU_DIAMETER {
229 DIAMETER_UNIT.send(msg);
230 return omit;
231 }
232
233 private function f_init_diameter(charstring id) runs on GT_CT {
234 var DIAMETEROps ops := {
235 create_cb := refers(DIAMETER_Emulation.ExpectedCreateCallback),
236 unitdata_cb := refers(DiameterForwardUnitdataCallback),
237 raw := true /* handler mode (single component for all IMSI)) */
238 };
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100239
240 /* Gx setup: */
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200241 g_gx_pars := {
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100242 remote_ip := m_ggsn_ip_gtpc,
243 remote_sctp_port := -1,
244 local_ip := m_bind_ip_gtpc,
245 local_sctp_port := PCRF_PORT,
Pau Espin Pedrol45d57022022-03-08 13:49:02 +0100246 origin_host := "pcrf.localdomain",
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100247 origin_realm := "localdomain",
Pau Espin Pedrol33b47492022-03-08 17:43:01 +0100248 auth_app_id := omit,
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100249 vendor_app_id := c_DIAMETER_3GPP_Gx_AID
250 };
Pau Espin Pedrol45d57022022-03-08 13:49:02 +0100251 vc_Gx := DIAMETER_Emulation_CT.create(id);
252 map(vc_Gx:DIAMETER, system:DIAMETER_CODEC_PT);
253 connect(vc_Gx:DIAMETER_UNIT, self:Gx_UNIT);
254 connect(vc_Gx:DIAMETER_PROC, self:Gx_PROC);
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200255 vc_Gx.start(DIAMETER_Emulation.main(ops, g_gx_pars, id));
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100256
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100257 /* Gy setup: */
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200258 g_gy_pars := {
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100259 remote_ip := m_ggsn_ip_gtpc,
260 remote_sctp_port := -1,
261 local_ip := m_bind_ip_gtpc,
262 local_sctp_port := OCS_PORT,
263 origin_host := "ocs.localdomain",
264 origin_realm := "localdomain",
265 auth_app_id := c_DIAMETER_CREDIT_CONTROL_AID,
266 vendor_app_id := omit
267 };
268 vc_Gy := DIAMETER_Emulation_CT.create(id);
269 map(vc_Gy:DIAMETER, system:DIAMETER_CODEC_PT);
270 connect(vc_Gy:DIAMETER_UNIT, self:Gy_UNIT);
271 connect(vc_Gy:DIAMETER_PROC, self:Gy_PROC);
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200272 vc_Gy.start(DIAMETER_Emulation.main(ops, g_gy_pars, id));
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100273
Pau Espin Pedrol45d57022022-03-08 13:49:02 +0100274 f_diameter_wait_capability(Gx_UNIT);
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100275 f_diameter_wait_capability(Gy_UNIT);
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100276 /* Give some time for our emulation to get out of SUSPECT list of SUT (3 watchdong ping-pongs):
277 * RFC6733 sec 5.1
278 * RFC3539 sec 3.4.1 [5]
279 * https://github.com/freeDiameter/freeDiameter/blob/master/libfdcore/p_psm.c#L49
280 */
281 f_sleep(1.0);
282 }
283
Harald Welte94ade362017-08-04 00:36:55 +0200284 function f_init() runs on GT_CT {
Harald Welte0be142b2017-08-13 13:28:10 +0200285 if (g_initialized == true) {
286 return;
287 }
288 g_initialized := true;
289
Harald Welteddeecbb2017-08-18 22:53:30 +0200290 g_sgsn_ip_c := f_inet_addr(m_bind_ip_gtpc);
291 g_sgsn_ip_u := f_inet_addr(m_bind_ip_gtpu);
292
Harald Welte94ade362017-08-04 00:36:55 +0200293 var Result res;
294 map(self:GTPC, system:GTPC);
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +0100295 res := GTPv1C_CodecPort_CtrlFunct.f_IPL4_listen(GTPC, m_bind_ip_gtpc, GTP1C_PORT, {udp:={}});
Harald Welte94ade362017-08-04 00:36:55 +0200296 log("GTP1C ConnectionID: ", res.connId);
Harald Welte811651e2017-08-05 15:25:06 +0200297 g_peer_c.connId := res.connId;
Harald Welte94ade362017-08-04 00:36:55 +0200298
299 map(self:GTPU, system:GTPU);
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +0100300 res := GTPv1U_CodecPort_CtrlFunct.f_GTPU_listen(GTPU, m_bind_ip_gtpu, GTP1U_PORT, {udp:={}});
Harald Welte811651e2017-08-05 15:25:06 +0200301 g_peer_u.connId:= res.connId;
Harald Welte5438b9d2017-08-13 13:27:48 +0200302
303 g_restart_ctr := f_rnd_octstring(1);
Harald Welte11dbc7b2017-08-13 18:57:56 +0200304 g_c_seq_nr := f_rnd_int(65535);
305 g_d_seq_nr := f_rnd_int(65535);
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200306
Pau Espin Pedrolc1b1ddf2022-01-19 18:10:30 +0100307 if (m_ggsn_impl == GGSN_IMPL_OSMOCOM) {
308 f_init_vty();
309 f_vty_set_gpdu_txseq(use_gtpu_txseq);
Pau Espin Pedrol05118022022-02-17 19:49:13 +0100310 f_vty_enable_echo_interval(g_use_echo_intval);
Oliver Smith95722c62023-10-20 13:59:10 +0200311 /* Emit a marker to appear in the SUT's own logging output */
312 f_logp(GGSNVTY, testcasename() & "() start");
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100313 } else if (m_ggsn_impl == GGSN_IMPL_OPEN5GS) {
314 f_init_diameter(testcasename());
Pau Espin Pedrolc1b1ddf2022-01-19 18:10:30 +0100315 }
Harald Welte94ade362017-08-04 00:36:55 +0200316 }
317
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +0100318 function f_shutdown_helper() runs on GT_CT {
Pau Espin Pedrolbfad97f2022-11-04 12:03:17 +0100319 /* Sleep (T3-RESPONSE * N3-REQUESTS) seconds.
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +0100320 * This ensures all retransmit queues are cleared before jumping
321 * into next tests, hence avoding situation where a test resuses
322 * a seqnum still in the GGSN's resp queue (dup req detector).
323 * See OS#5485 avout decreasing time. We could also add a new
324 * VTY command that calls gtp_clear_queues() */
Pau Espin Pedrolbfad97f2022-11-04 12:03:17 +0100325 f_sleep(int2float(mp_t3_response * mp_n3_requests));
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +0100326 setverdict(pass);
327 }
328
Harald Welte94ade362017-08-04 00:36:55 +0200329 /* Altstep implementing responses to any incoming echo requests */
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100330 private altstep pingpong() runs on GT_CT {
Harald Welte94ade362017-08-04 00:36:55 +0200331 var Gtp1cUnitdata ud;
Harald Welte3af89482017-08-04 16:20:23 +0200332 var Gtp1uUnitdata udu;
Pau Espin Pedrol05118022022-02-17 19:49:13 +0100333 [g_use_echo_intval > 0] GTPC.receive(tr_GTPC_PING(?)) -> value ud {
Harald Welte811651e2017-08-05 15:25:06 +0200334 var uint16_t seq := oct2int(ud.gtpc.opt_part.sequenceNumber);
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +0200335 GTPC.send(ts_GTPC_PONG(ud.peer, seq, g_restart_ctr));
Harald Welte94ade362017-08-04 00:36:55 +0200336 repeat;
337 };
Pau Espin Pedrol05118022022-02-17 19:49:13 +0100338 [g_use_echo_intval == 0] GTPC.receive(tr_GTPC_PING(?)) {
Pau Espin Pedrolc04c69e2020-03-03 16:46:29 +0100339 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
340 "GTP Echo Req rceived but not enabled in VTY");
Harald Welte3af89482017-08-04 16:20:23 +0200341 };
Pau Espin Pedrolc04c69e2020-03-03 16:46:29 +0100342 [] T_default.timeout {
343 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
Oliver Smithbbbe05d2024-02-28 11:14:32 +0100344 "pingpong T_default timeout");
Pau Espin Pedrolc04c69e2020-03-03 16:46:29 +0100345 };
Harald Welte94ade362017-08-04 00:36:55 +0200346 }
347
Harald Welte811651e2017-08-05 15:25:06 +0200348 /* 'internet' in DNS encoding */
Harald Welteed097432017-08-13 13:28:49 +0200349 const octetstring c_ApnInternet := '08696E7465726E6574'O;
350 const octetstring c_ApnInet6 := '05696E657436'O;
351 const octetstring c_ApnInet46 := '06696E65743436'O;
Harald Welte94ade362017-08-04 00:36:55 +0200352
Harald Welte811651e2017-08-05 15:25:06 +0200353 /* return random NSAPI */
354 function f_rnd_nsapi() return BIT4 {
355 return int2bit(f_rnd_int(16), 4);
356 }
357
358 /* return random TEI[DC] */
359 function f_rnd_tei() return OCT4 {
360 return int2oct(f_rnd_int(4294967296), 4);
361 }
362
Pau Espin Pedrol38968e92022-05-13 16:17:48 +0200363 /* return random IMEI(SV) */
364 function f_rnd_imeisv() return OCT8 {
365 return hex2oct(f_rnd_hexstring(16, 10));
366 }
367
Harald Welte811651e2017-08-05 15:25:06 +0200368 /* define an (internal) representation of a PDP context */
Pau Espin Pedrold25095f2022-05-18 16:29:05 +0200369 template PdpContext t_DefinePDP(hexstring imsi, charstring msisdn, octetstring apn,
Pau Espin Pedrol38aeffb2022-02-01 20:46:29 +0100370 EndUserAddress eua, OCT1 ratType := '02'O /* GERAN */) := {
Harald Welte811651e2017-08-05 15:25:06 +0200371 imsi := imsi,
Pau Espin Pedrold25095f2022-05-18 16:29:05 +0200372 msisdn := '11'O & f_enc_TBCD(msisdn), /* encoded as TS 29.060 7.7.33, TS 29.002 */
Harald Welte811651e2017-08-05 15:25:06 +0200373 nsapi := f_rnd_nsapi(),
374 apn := apn,
Harald Welteed7a1772017-08-09 20:26:20 +0200375 pco_req := omit,
Harald Welte811651e2017-08-05 15:25:06 +0200376 eua := eua,
377 teid := f_rnd_tei(),
Pau Espin Pedrol38aeffb2022-02-01 20:46:29 +0100378 teic := f_rnd_tei(),
Pau Espin Pedrolca587f12022-02-02 10:42:01 +0100379 ratType := ratType,
380 uli := {
381 type_gtpc := '98'O,
382 lengthf := 0 /* filled in by encoder */,
383 geographicLocationType := '00'O /* CGI */,
384 geographicLocation := {
385 geographicLocationCGI := ts_GeographicLocationCGI('262'H, '42F'H, '0001'O, '0002'O)
386 }
Pau Espin Pedrol0e127872022-05-12 17:58:50 +0200387 },
Pau Espin Pedrol38968e92022-05-13 16:17:48 +0200388 charging_char := '0000'O,
Pau Espin Pedrol535ca262022-05-16 14:07:17 +0200389 imeisv := f_rnd_imeisv(),
390 ms_tz := f_ts_MS_TimeZone('03'O, '01'B)
Harald Welte811651e2017-08-05 15:25:06 +0200391 }
392
393 /* send GTP-C for a given context and increment sequence number */
Harald Welte41575e92017-08-13 13:49:57 +0200394 function f_send_gtpc(in template Gtp1cUnitdata data) runs on GT_CT {
Harald Welte811651e2017-08-05 15:25:06 +0200395 GTPC.send(data);
Pau Espin Pedrol82a7f702022-05-19 17:41:29 +0200396 g_c_seq_nr := (g_c_seq_nr + 1) mod 65536;
Harald Welte811651e2017-08-05 15:25:06 +0200397 }
398
399 /* send GTP-U for a given context and increment sequence number */
Harald Welte231b9412017-08-09 17:16:31 +0200400 function f_send_gtpu(inout PdpContext ctx, in octetstring data) runs on GT_CT {
Harald Welte3e0b0392018-04-26 09:46:21 +0200401 if (use_gtpu_txseq) {
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200402 GTPU.send(ts_GTP1U_GPDU(g_peer_u, g_d_seq_nr, ctx.teid_remote, data));
Pau Espin Pedrol82a7f702022-05-19 17:41:29 +0200403 g_d_seq_nr := (g_d_seq_nr + 1) mod 65536;
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200404 } else {
405 GTPU.send(ts_GTP1U_GPDU(g_peer_u, omit, ctx.teid_remote, data));
406 }
Harald Welte811651e2017-08-05 15:25:06 +0200407 }
408
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +0100409 function f_handle_create_req(inout PdpContext ctx, in Gtp1cUnitdata ud, in template OCT1 exp_cause := '80'O) runs on GT_CT {
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +0200410 var CreatePDPContextResponse cpr := ud.gtpc.gtpc_pdu.createPDPContextResponse;
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +0100411
412 if (not match(cpr.cause.causevalue, exp_cause)) {
413 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
414 "CreatePDPContextResp: cause expectancies didn't match");
415 }
416
417 if (cpr.cause.causevalue == '80'O) { /* Accepted */
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +0200418 /* Check if EUA type corresponds to requested type */
419 if (match(ctx.eua, t_EuaIPv4(?)) and
420 not match(cpr.endUserAddress, tr_EuaIPv4(?))){
Pau Espin Pedrol8ad031a2022-02-16 17:33:43 +0100421 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
422 "EUAv4 expectancies didn't match");
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +0200423 }
424 if (match(ctx.eua, t_EuaIPv6(?)) and
425 not match(cpr.endUserAddress, tr_EuaIPv6(?))) {
Pau Espin Pedrol8ad031a2022-02-16 17:33:43 +0100426 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
427 "EUAv6 expectancies didn't match");
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +0200428 }
429 if (match(ctx.eua, t_EuaIPv4v6(?, ?)) and
430 not match(cpr.endUserAddress, tr_EuaIPv4v6(?, ?))) {
Pau Espin Pedrol8ad031a2022-02-16 17:33:43 +0100431 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
432 "EUAv4v6 expectancies didn't match");
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +0200433 }
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +0100434 } else if (cpr.cause.causevalue == '81'O) { /* Cause: New PDP type due to network preference */
435 /* ETSI TS 129 060 7.3.2 Create PDP Context Response. OS#5449 */
436 /* This should only happen if EUA requested type is v4v6: */
437 if (not ischosen(ctx.eua.endUserAddress.endUserAddressIPv4andIPv6)) {
438 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
439 "Cause not expected when requesting a non v4v6 EUA");
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +0200440 }
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +0100441 if (not match(cpr.endUserAddress, (tr_EuaIPv4(?), tr_EuaIPv6(?)))) {
442 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
443 "Cause not expected when requesting+receiving EUAv4v6");
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +0200444 }
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +0200445 } else {
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +0100446 if (ispresent(cpr.endUserAddress)) {
447 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
448 "EUA received on createPDPContextResponse cause=" & oct2str(cpr.cause.causevalue));
449 }
450 setverdict(pass);
451 return;
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +0200452 }
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +0100453
454 /* Check if PCO response corresponds to request */
455 if (ispresent(ctx.pco_req)) {
456 if (match(ctx.pco_req, ts_PCO_IPv4_DNS_CONT) and
457 not match(cpr.protConfigOptions, tr_PCO_IPv4_DNS_CONT_resp(?))) {
458 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
459 "IPv4 DNS Container requested, but missing");
460 }
461 if (match(ctx.pco_req, ts_PCO_IPv6_DNS) and
462 not match(cpr.protConfigOptions, tr_PCO_IPv6_DNS_resp(?))) {
463 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
464 "IPv6 DNS Container requested, but missing");
465 }
466 }
467 ctx.teid_remote := cpr.teidDataI.teidDataI;
468 ctx.teic_remote := cpr.teidControlPlane.teidControlPlane;
469 ctx.eua := cpr.endUserAddress;
470 ctx.pco_neg := cpr.protConfigOptions;
471 setverdict(pass);
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +0200472 }
473
Pau Espin Pedrolcd326c52022-02-14 18:57:43 +0100474 function f_handle_update_req(inout PdpContext ctx, in Gtp1cUnitdata ud, in OCT1 exp_cause := '80'O) runs on GT_CT {
475 var UpdatePDPContextResponseGGSN upr := ud.gtpc.gtpc_pdu.updatePDPContextResponse.updatePDPContextResponseGGSN;
476 if (exp_cause == '80'O and exp_cause == upr.cause.causevalue) {
477 ctx.teid_remote := upr.teidDataI.teidDataI;
478 ctx.teic_remote := upr.teidControlPlane.teidControlPlane;
479 if (ispresent(upr.protConfigOptions)) {
480 ctx.pco_neg := upr.protConfigOptions;
481 }
482 setverdict(pass);
483 } else if (exp_cause != '80'O and exp_cause == upr.cause.causevalue) {
484 setverdict(pass);
485 } else {
Pau Espin Pedrol8ad031a2022-02-16 17:33:43 +0100486 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
487 "UpdatePDPContextResp: cause expectancies didn't match");
Pau Espin Pedrolcd326c52022-02-14 18:57:43 +0100488 }
489 }
490
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100491 private altstep as_DIA_Gx_CCR(DCC_NONE_CC_Request_Type req_type) runs on GT_CT {
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100492 var PDU_DIAMETER rx_dia;
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100493 [] Gx_UNIT.receive(tr_DIA_Gx_CCR(req_type := req_type)) -> value rx_dia {
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100494 var template (omit) AVP avp;
495 var octetstring sess_id;
496 var AVP_Unsigned32 req_num;
497
498 avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_BASE_NONE_Session_Id);
499 sess_id := valueof(avp.avp_data.avp_BASE_NONE_Session_Id);
500
501 avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_DCC_NONE_CC_Request_Number);
502 req_num := valueof(avp.avp_data.avp_DCC_NONE_CC_Request_Number);
503
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100504 Gx_UNIT.send(ts_DIA_Gx_CCA(rx_dia.hop_by_hop_id, rx_dia.end_to_end_id, sess_id,
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100505 req_type, req_num));
506 }
Pau Espin Pedrol45d57022022-03-08 13:49:02 +0100507 [] Gx_UNIT.receive(PDU_DIAMETER:?) -> value rx_dia {
Pau Espin Pedrol8ad031a2022-02-16 17:33:43 +0100508 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
509 log2str("Received unexpected DIAMETER ", rx_dia));
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100510 }
511 }
512
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200513 private function f_tr_DIA_Gy_CCR(template (omit) PdpContext ctx, DCC_NONE_CC_Request_Type req_type)
514 runs on GT_CT return template (present) PDU_DIAMETER
515 {
516 var template (present) PDU_DIAMETER tpl;
517 var charstring smf_origin_host := "smf.localdomain";
518 var template (present) octetstring imsi := ?;
519 var template (present) octetstring msisdn := ?;
520 var template (present) octetstring imeisv := ?;
521 var template (present) octetstring rat_type := ?;
522 var template (present) OCT4 charging_char := ?;
523 var template (present) OCT1 nsapi := ?;
524 if (not istemplatekind(ctx, "omit")) {
525 var PdpContext ctx_val := valueof(ctx);
526 imsi := char2oct(f_dec_TBCD(imsi_hex2oct(ctx_val.imsi)));
527 msisdn := char2oct(f_dec_TBCD(substr(ctx_val.msisdn, 1, lengthof(ctx_val.msisdn) -1)));
528 imeisv := char2oct(f_dec_TBCD(ctx_val.imeisv));
529 rat_type := ctx_val.ratType;
530 charging_char := char2oct(oct2str(ctx_val.charging_char));
531 nsapi := char2oct(hex2str(bit2hex(ctx_val.nsapi)));
532 }
533 select (req_type) {
534 case (INITIAL_REQUEST) {
535 tpl := tr_DIAMETER(flags:='11000000'B, cmd_code:=Credit_Control,
536 avps := superset(
537 tr_AVP_SessionId,
538 tr_AVP_OriginHost(smf_origin_host),
539 tr_AVP_OriginRealm(g_gy_pars.origin_realm),
540 tr_AVP_DestinationRealm(g_gy_pars.origin_realm),
541 tr_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
542 tr_AVP_ServiceContextId,
543 tr_AVP_CcReqType(req_type),
544 tr_AVP_CcReqNum(?),
545 tr_AVP_EventTimestamp(?),
546 tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_IMSI), tr_AVP_SubcrIdData(imsi)}),
547 tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_E164), tr_AVP_SubcrIdData(msisdn)}),
548 tr_AVP_RequestedAction(DIRECT_DEBITING),
549 tr_AVP_3GPP_AoCRequestType,
550 tr_AVP_MultipleServicesIndicator,
551 tr_AVP_Multiple_Services_Credit_Control(content := superset(
552 tr_AVP_Requested_Service_Unit,
Pau Espin Pedrol97f95472024-03-25 12:17:43 +0100553 tr_AVP_PCC_3GPP_QoS_Information
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200554 )),
555 tr_AVP_3GPP_ServiceInformation(content := superset(
556 tr_AVP_3GPP_PSInformation(content := superset(
557 tr_AVP_3GPP_ChargingId,
558 tr_AVP_3GPP_PDPType((IPv4,IPv6,IPv4v6)),
559 tr_AVP_3GPP_PDPAddress(tr_AVP_Address((IP,IP6), ?)),
560 tr_AVP_3GPP_SGSNAddress(tr_AVP_Address(IP, f_inet_addr(m_bind_ip_gtpc))),
561 tr_AVP_3GPP_GGSNAddress(tr_AVP_Address(IP, f_inet_addr(m_ggsn_ip_gtpc))),
562 tr_AVP_3GPP_CalledStationId,
563 tr_AVP_3GPP_SelectionMode,
564 tr_AVP_3GPP_ChargingCharacteristics(charging_char),
565 tr_AVP_3GPP_SGSNMCCMNC,
566 tr_AVP_3GPP_NSAPI(nsapi),
567 tr_AVP_3GPP_MS_TimeZone,
568 tr_AVP_3GPP_ULI,
Pau Espin Pedrol97f95472024-03-25 12:17:43 +0100569 tr_AVP_GI_3GPP_RatType(rat_type),
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200570 tr_AVP_UserEquipmentInfo({
571 tr_AVP_UserEquipmentInfoType(IMEISV),
572 tr_AVP_UserEquipmentInfoValue(imeisv)
573 })
574 ))
575 ))
576 ));
577 }
578 case (UPDATE_REQUEST) {
579 tpl := tr_DIAMETER(flags:='11000000'B, cmd_code:=Credit_Control,
580 avps := superset(
581 tr_AVP_SessionId,
582 tr_AVP_OriginHost(smf_origin_host),
583 tr_AVP_OriginRealm(g_gy_pars.origin_realm),
584 tr_AVP_DestinationRealm(g_gy_pars.origin_realm),
585 tr_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
586 tr_AVP_ServiceContextId,
587 tr_AVP_CcReqType(req_type),
588 tr_AVP_CcReqNum(?),
589 tr_AVP_DestinationHost(?),
590 tr_AVP_EventTimestamp(?),
591 tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_IMSI), tr_AVP_SubcrIdData(imsi)}),
592 tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_E164), tr_AVP_SubcrIdData(msisdn)}),
593 tr_AVP_RequestedAction(DIRECT_DEBITING),
594 tr_AVP_3GPP_AoCRequestType,
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200595 tr_AVP_Multiple_Services_Credit_Control(content := superset(
596 tr_AVP_Requested_Service_Unit,
597 tr_AVP_Used_Service_Unit,
Pau Espin Pedrolcba0f6d2022-05-24 13:49:46 +0200598 /* tr_AVP_3GPP_Reporting_Reason, can be sometimes inside UsedServiceUnit */
Pau Espin Pedrol97f95472024-03-25 12:17:43 +0100599 tr_AVP_PCC_3GPP_QoS_Information
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200600 )),
601 tr_AVP_3GPP_ServiceInformation(content := superset(
602 tr_AVP_3GPP_PSInformation(content := superset(
603 tr_AVP_3GPP_ChargingId,
604 /* tr_AVP_3GPP_PDPType, Only in INIT */
605 tr_AVP_3GPP_PDPAddress(tr_AVP_Address((IP,IP6), ?)),
606 tr_AVP_3GPP_SGSNAddress(tr_AVP_Address(IP, f_inet_addr(m_bind_ip_gtpc))),
607 tr_AVP_3GPP_GGSNAddress(tr_AVP_Address(IP, f_inet_addr(m_ggsn_ip_gtpc))),
608 tr_AVP_3GPP_CalledStationId,
609 tr_AVP_3GPP_SelectionMode,
610 tr_AVP_3GPP_ChargingCharacteristics(charging_char),
611 tr_AVP_3GPP_SGSNMCCMNC,
612 tr_AVP_3GPP_NSAPI(nsapi),
613 tr_AVP_3GPP_MS_TimeZone,
614 tr_AVP_3GPP_ULI,
Pau Espin Pedrol97f95472024-03-25 12:17:43 +0100615 tr_AVP_GI_3GPP_RatType(rat_type),
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200616 tr_AVP_UserEquipmentInfo({
617 tr_AVP_UserEquipmentInfoType(IMEISV),
618 tr_AVP_UserEquipmentInfoValue(imeisv)
619 })
620 ))
621 ))
622 ));
623 }
624 case (TERMINATION_REQUEST) {
625 tpl := tr_DIAMETER(flags:='11000000'B, cmd_code:=Credit_Control,
626 avps := superset(
627 tr_AVP_SessionId,
628 tr_AVP_OriginHost(smf_origin_host),
629 tr_AVP_OriginRealm(g_gy_pars.origin_realm),
630 tr_AVP_DestinationRealm(g_gy_pars.origin_realm),
631 tr_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
632 tr_AVP_ServiceContextId,
633 tr_AVP_CcReqType(req_type),
634 tr_AVP_CcReqNum(?),
635 tr_AVP_DestinationHost(?),
636 tr_AVP_EventTimestamp(?),
637 tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_IMSI), tr_AVP_SubcrIdData(imsi)}),
638 tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_E164), tr_AVP_SubcrIdData(msisdn)}),
639 tr_AVP_TerminationCause(?),
640 tr_AVP_RequestedAction(DIRECT_DEBITING),
641 tr_AVP_3GPP_AoCRequestType,
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200642 tr_AVP_Multiple_Services_Credit_Control(content := superset(
643 /* tr_AVP_Requested_Service_Unit, Only in INIT and UPDATE */
644 tr_AVP_Used_Service_Unit,
Pau Espin Pedrolcba0f6d2022-05-24 13:49:46 +0200645 tr_AVP_3GPP_Reporting_Reason(FINAL),
Pau Espin Pedrol97f95472024-03-25 12:17:43 +0100646 tr_AVP_PCC_3GPP_QoS_Information
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200647 )),
648 tr_AVP_3GPP_ServiceInformation(content := superset(
649 tr_AVP_3GPP_PSInformation(content := superset(
650 tr_AVP_3GPP_ChargingId,
651 /* tr_AVP_3GPP_PDPType, Only in INIT */
652 tr_AVP_3GPP_PDPAddress(tr_AVP_Address((IP,IP6), ?)),
653 tr_AVP_3GPP_SGSNAddress(tr_AVP_Address(IP, f_inet_addr(m_bind_ip_gtpc))),
654 tr_AVP_3GPP_GGSNAddress(tr_AVP_Address(IP, f_inet_addr(m_ggsn_ip_gtpc))),
655 tr_AVP_3GPP_CalledStationId,
656 tr_AVP_3GPP_SelectionMode,
657 tr_AVP_3GPP_ChargingCharacteristics(charging_char),
658 tr_AVP_3GPP_SGSNMCCMNC,
659 tr_AVP_3GPP_NSAPI(nsapi),
660 tr_AVP_3GPP_MS_TimeZone,
661 tr_AVP_3GPP_ULI,
Pau Espin Pedrol97f95472024-03-25 12:17:43 +0100662 tr_AVP_GI_3GPP_RatType(rat_type),
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200663 tr_AVP_UserEquipmentInfo({
664 tr_AVP_UserEquipmentInfoType(IMEISV),
665 tr_AVP_UserEquipmentInfoValue(imeisv)
666 })
667 ))
668 ))
669 ));
670 }
671 }
672 return tpl;
673 }
674
675 private altstep as_DIA_Gy_CCR(template (omit) PdpContext ctx, DCC_NONE_CC_Request_Type req_type) runs on GT_CT {
Pau Espin Pedrol8fa22842022-05-20 14:47:55 +0200676 [] Gy_UNIT.receive(f_tr_DIA_Gy_CCR(ctx, req_type := req_type)) -> value g_rx_gy {
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100677 var template (value) PDU_DIAMETER tx_dia;
678 var template (omit) AVP avp;
679 var octetstring sess_id;
680 var AVP_Unsigned32 req_num;
681
Pau Espin Pedrol8fa22842022-05-20 14:47:55 +0200682 avp := f_DIAMETER_get_avp(g_rx_gy, c_AVP_Code_BASE_NONE_Session_Id);
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100683 sess_id := valueof(avp.avp_data.avp_BASE_NONE_Session_Id);
684
Pau Espin Pedrol8fa22842022-05-20 14:47:55 +0200685 avp := f_DIAMETER_get_avp(g_rx_gy, c_AVP_Code_DCC_NONE_CC_Request_Number);
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100686 req_num := valueof(avp.avp_data.avp_DCC_NONE_CC_Request_Number);
687 if (g_gy_validity_time > 0) {
Pau Espin Pedrol52562c92022-05-23 15:45:46 +0200688 if (g_gy_volume_threshold > 0) {
689 tx_dia := ts_DIA_Gy_CCA_ValidityTimeVolumeThreshold(g_rx_gy.hop_by_hop_id, g_rx_gy.end_to_end_id, sess_id,
690 req_type, req_num, g_gy_validity_time, g_gy_volume_threshold);
691 } else {
692 tx_dia := ts_DIA_Gy_CCA_ValidityTime(g_rx_gy.hop_by_hop_id, g_rx_gy.end_to_end_id, sess_id,
693 req_type, req_num, g_gy_validity_time);
694 }
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100695 } else {
Pau Espin Pedrol8fa22842022-05-20 14:47:55 +0200696 tx_dia := ts_DIA_Gy_CCA(g_rx_gy.hop_by_hop_id, g_rx_gy.end_to_end_id, sess_id,
Pau Espin Pedrol06fba9c2024-03-18 20:12:12 +0100697 DIAMETER_SUCCESS, req_type, req_num);
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100698 }
699 Gy_UNIT.send(tx_dia);
700 }
Pau Espin Pedrol8fa22842022-05-20 14:47:55 +0200701 [] Gy_UNIT.receive(PDU_DIAMETER:?) -> value g_rx_gy {
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100702 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
Pau Espin Pedrol8fa22842022-05-20 14:47:55 +0200703 log2str("Received unexpected DIAMETER Gy", g_rx_gy));
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100704 }
705 }
706
Harald Welte811651e2017-08-05 15:25:06 +0200707 /* send a PDP context activation */
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +0100708 function f_pdp_ctx_act(inout PdpContext ctx, template OCT1 exp_cause := '80'O) runs on GT_CT return CreatePDPContextResponse {
Harald Welte94ade362017-08-04 00:36:55 +0200709 var Gtp1cUnitdata ud;
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +0100710 var CreatePDPContextResponse cpr;
Harald Welte94ade362017-08-04 00:36:55 +0200711 var default d;
712
713 log("sending CreatePDP");
Harald Welte41575e92017-08-13 13:49:57 +0200714 f_send_gtpc(ts_GTPC_CreatePDP(g_peer_c, g_c_seq_nr, ctx.imsi, g_restart_ctr,
Harald Welte811651e2017-08-05 15:25:06 +0200715 ctx.teid, ctx.teic, ctx.nsapi, ctx.eua, ctx.apn,
Pau Espin Pedrol0e127872022-05-12 17:58:50 +0200716 g_sgsn_ip_c, g_sgsn_ip_u, ctx.msisdn, ctx.pco_req, ctx.ratType,
Pau Espin Pedrol535ca262022-05-16 14:07:17 +0200717 ctx.uli, ctx.charging_char, ctx.imeisv, ctx.ms_tz));
Harald Welte94ade362017-08-04 00:36:55 +0200718 T_default.start;
Harald Welte94ade362017-08-04 00:36:55 +0200719 d := activate(pingpong());
Pau Espin Pedrol45d57022022-03-08 13:49:02 +0100720 if (Gx_PROC.checkstate("Connected")) {
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100721 as_DIA_Gx_CCR(INITIAL_REQUEST);
722 }
723 if (Gy_PROC.checkstate("Connected")) {
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200724 as_DIA_Gy_CCR(ctx, INITIAL_REQUEST);
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100725 }
Harald Welte94ade362017-08-04 00:36:55 +0200726 alt {
Harald Welte811651e2017-08-05 15:25:06 +0200727 [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, createPDPContextResponse, ctx.teic)) -> value ud {
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +0200728 f_handle_create_req(ctx, ud, exp_cause);
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +0100729 cpr := ud.gtpc.gtpc_pdu.createPDPContextResponse;
Harald Welte94ade362017-08-04 00:36:55 +0200730 }
731 }
732 deactivate(d);
Harald Welte811651e2017-08-05 15:25:06 +0200733 T_default.stop;
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +0100734 return cpr;
Harald Welte94ade362017-08-04 00:36:55 +0200735 }
736
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +0200737 function f_pdp_ctx_exp_del_req(PdpContext ctx, template (omit) OCT1 expect_cause := omit, boolean expect_teardown := false) runs on GT_CT {
738 var Gtp1cUnitdata ud;
739 var default d;
740
741 T_default.start;
742 d := activate(pingpong());
743 alt {
744 [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, deletePDPContextRequest, ctx.teic)) -> value ud {
745 if (istemplatekind(expect_cause, "omit") and not ispresent(ud.gtpc.gtpc_pdu.deletePDPContextRequest.cause.causevalue)) {
746 setverdict(pass);
747 } else if (not istemplatekind(expect_cause, "omit") and
748 ispresent(ud.gtpc.gtpc_pdu.deletePDPContextRequest.cause.causevalue) and
749 ud.gtpc.gtpc_pdu.deletePDPContextRequest.cause.causevalue == valueof(expect_cause)) {
750 setverdict(pass);
751 } else {
Pau Espin Pedrol8ad031a2022-02-16 17:33:43 +0100752 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
753 "DeletePDPContextReq: cause expectancies didn't match");
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +0200754 }
755
756 if (expect_teardown == ispresent(ud.gtpc.gtpc_pdu.deletePDPContextRequest.tearDownIndicator)) {
757 setverdict(pass);
758 } else {
759 setverdict(fail);
Pau Espin Pedrol8ad031a2022-02-16 17:33:43 +0100760 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
761 "DeletePDPContextReq: tearDownIndicator expectancies didn't match");
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +0200762 }
763 }
764 }
765 deactivate(d);
766 T_default.stop;
767 }
768
Pau Espin Pedrol10ec96e2022-02-09 17:03:15 +0100769 function f_pdp_ctx_del(PdpContext ctx, template BIT1 teardown_ind, OCT1 expect_causevalue := '80'O, boolean expect_diameter := true) runs on GT_CT {
Harald Weltef1e0d5a2017-08-05 08:51:22 +0200770 var Gtp1cUnitdata ud;
771 var default d;
Pau Espin Pedrol9a5f42f2019-05-27 20:04:35 +0200772 var OCT4 expect_teid;
773
774 /* 3GPP TS 29.060 sec 7.3.6 specifies TEID used in response
775 message with cause value "Non existent" shall be zero. */
776 if (expect_causevalue == 'C0'O) {
777 expect_teid := '00000000'O;
778 } else {
779 expect_teid := ctx.teic;
780 }
Harald Weltef1e0d5a2017-08-05 08:51:22 +0200781
Harald Welte41575e92017-08-13 13:49:57 +0200782 f_send_gtpc(ts_GTPC_DeletePDP(g_peer_c, g_c_seq_nr, ctx.teic_remote, ctx.nsapi, teardown_ind));
Harald Weltef1e0d5a2017-08-05 08:51:22 +0200783 T_default.start;
Harald Weltef1e0d5a2017-08-05 08:51:22 +0200784 d := activate(pingpong());
Pau Espin Pedrol45d57022022-03-08 13:49:02 +0100785 if (Gx_PROC.checkstate("Connected") and expect_diameter) {
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +0100786 as_DIA_Gx_CCR(TERMINATION_REQUEST);
787 }
788 if (Gy_PROC.checkstate("Connected") and expect_diameter) {
Pau Espin Pedrola2af5782022-05-18 16:34:29 +0200789 as_DIA_Gy_CCR(ctx, TERMINATION_REQUEST);
Pau Espin Pedrol0bcfd9d2022-02-02 11:01:35 +0100790 }
Harald Weltef1e0d5a2017-08-05 08:51:22 +0200791 alt {
Pau Espin Pedrol9a5f42f2019-05-27 20:04:35 +0200792 [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, deletePDPContextResponse, expect_teid)) -> value ud {
793 if (ud.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue == expect_causevalue) {
Harald Weltef1e0d5a2017-08-05 08:51:22 +0200794 setverdict(pass);
795 } else {
Pau Espin Pedrol8ad031a2022-02-16 17:33:43 +0100796 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
797 "DeletePDPContextResp: cause expectancies didn't match");
Harald Weltef1e0d5a2017-08-05 08:51:22 +0200798 }
799 }
800 }
801 deactivate(d);
Harald Welte811651e2017-08-05 15:25:06 +0200802 T_default.stop;
Harald Weltef1e0d5a2017-08-05 08:51:22 +0200803 }
Pau Espin Pedrolcd326c52022-02-14 18:57:43 +0100804
805 /* send a Update PdP Context Request, expect Response */
806 function f_pdp_ctx_update(inout PdpContext ctx, OCT1 exp_cause := '80'O, template (omit) OCT4 new_teid := omit, template (omit) OCT4 new_teic := omit) runs on GT_CT {
807 var Gtp1cUnitdata ud;
808 var default d;
809
810 if (not istemplatekind(new_teid, "omit")) {
811 ctx.teid := valueof(new_teid);
812 }
813 if (not istemplatekind(new_teic, "omit")) {
814 ctx.teic := valueof(new_teic);
815 }
816
817 log("sending UpdatePDP");
818 f_send_gtpc(ts_GTPC_UpdatePDP(g_peer_c, ctx.teic_remote, g_c_seq_nr, ctx.imsi, g_restart_ctr,
819 ctx.teid, ctx.teic, ctx.nsapi, g_sgsn_ip_c, g_sgsn_ip_u,
820 ctx.pco_req, ctx.ratType, ctx.uli));
821 T_default.start;
822 d := activate(pingpong());
823 alt {
824 [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, updatePDPContextResponse, ctx.teic)) -> value ud {
825 f_handle_update_req(ctx, ud, exp_cause);
826 }
827 }
828 deactivate(d);
829 T_default.stop;
830 }
831
Pau Espin Pedrol57604212022-02-14 16:54:18 +0100832 /* Get link-id from PDP Context EUA */
833 function f_ctx_get_ipv6_interface_id(in PdpContext ctx) return OCT16 {
834 var OCT16 interface_id;
835 if (ischosen(ctx.eua.endUserAddress.endUserAddressIPv4andIPv6)) {
836 interface_id := ctx.eua.endUserAddress.endUserAddressIPv4andIPv6.ipv6_address;
837 } else if (ischosen(ctx.eua.endUserAddress.endUserAddressIPv6)) {
838 interface_id := ctx.eua.endUserAddress.endUserAddressIPv6.ipv6_address;
839 } else {
840 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected request to submit icmpv6 rs in IPv4 PDP context");
841 }
842 return interface_id;
843 }
844
Harald Welte231b9412017-08-09 17:16:31 +0200845 /* create ICMPv6 router solicitation deriving link-id from PDP Context EUA */
846 function f_icmpv6_rs_for_pdp(in PdpContext ctx) return octetstring {
Pau Espin Pedrol57604212022-02-14 16:54:18 +0100847 var OCT16 interface_id := f_ctx_get_ipv6_interface_id(ctx);
Harald Welte231b9412017-08-09 17:16:31 +0200848 return f_gen_icmpv6_router_solicitation(interface_id);
849 }
850
Harald Welte231b9412017-08-09 17:16:31 +0200851 /* generate and encode ICMPv6 neighbor solicitation for PDP Context */
852 function f_gen_icmpv6_neigh_solicit_for_pdp(in PdpContext ctx) return octetstring {
Pau Espin Pedrol57604212022-02-14 16:54:18 +0100853 var OCT16 interface_id := f_ctx_get_ipv6_interface_id(ctx);
Harald Welte231b9412017-08-09 17:16:31 +0200854 var OCT16 link_local := f_ipv6_link_local(interface_id);
855 var OCT16 daddr := f_ipv6_sol_node_mcast(link_local);
856
857 return f_gen_icmpv6_neigh_solicit(link_local, daddr, link_local);
858 }
859
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +0100860 /* Wait for ICMPv4 from GTP */
861 function f_wait_icmp4(PdpContext ctx, template PDU_ICMP expected) runs on GT_CT {
Harald Welte231b9412017-08-09 17:16:31 +0200862 var Gtp1uUnitdata ud;
863 T_default.start;
864 alt {
Pau Espin Pedrolcd326c52022-02-14 18:57:43 +0100865 [] GTPU.receive(tr_GTPU_GPDU(g_peer_u, ctx.teid)) -> value ud {
Harald Welte3e0b0392018-04-26 09:46:21 +0200866 if (f_verify_gtpu_txseq(ud.gtpu, use_gtpu_txseq) == false) {
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200867 setverdict(fail);
868 stop;
869 }
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +0100870 var octetstring gpdu := ud.gtpu.gtpu_IEs.g_PDU_IEs.data;
871 var IPv4_packet ip4 := f_IPv4_dec(gpdu);
872 if (ip4.header.ver != 4) {
873 repeat;
874 }
875 var PDU_ICMP icmp4 := f_dec_PDU_ICMP(ip4.payload);
876 if (not match(icmp4, expected)) {
877 repeat;
878 }
879 }
Pau Espin Pedrolcd326c52022-02-14 18:57:43 +0100880 [] GTPU.receive(tr_GTPU_GPDU(g_peer_u, ?)) -> value ud {
Oliver Smith9daae3e2024-02-28 11:54:22 +0100881 setverdict(fail, "Received wrong local TEID");
Pau Espin Pedrolcd326c52022-02-14 18:57:43 +0100882 }
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +0100883 [] GTPU.receive { setverdict(fail); }
884 [] T_default.timeout { setverdict(fail); }
885 }
886 T_default.stop;
887 }
888
Pau Espin Pedrol6c7285d2018-01-30 17:20:22 +0100889 /* Wait for ICMPv4 echo request from GTP */
890 function f_wait_icmp4_echo_request(PdpContext ctx) runs on GT_CT {
891 f_wait_icmp4(ctx, tr_ICMPv4_ERQ);
892 }
893
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +0100894 /* Wait for ICMPv4 echo reply (or unreachable) from GTP */
895 function f_wait_icmp4_echo_reply(PdpContext ctx) runs on GT_CT {
896 f_wait_icmp4(ctx, (tr_ICMPv4_ERP, tr_ICMPv4_DU));
897 }
898
899 /* Wait for ICMPv6 from GTP */
900 function f_wait_icmp6(PdpContext ctx, template PDU_ICMPv6 expected) runs on GT_CT {
901 var Gtp1uUnitdata ud;
902 T_default.start;
903 alt {
Harald Welte231b9412017-08-09 17:16:31 +0200904 [] GTPU.receive(tr_GTPU_GPDU(g_peer_u, ?)) -> value ud {
Harald Welte3e0b0392018-04-26 09:46:21 +0200905 if (f_verify_gtpu_txseq(ud.gtpu, use_gtpu_txseq) == false) {
Pau Espin Pedrol9c1c2ae2023-12-05 14:24:49 +0100906 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
907 log2str("Received GTPU with wrong txseq while waiting for ICMPv6: ", expected));
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200908 }
Harald Welte231b9412017-08-09 17:16:31 +0200909 var octetstring gpdu := ud.gtpu.gtpu_IEs.g_PDU_IEs.data;
910 var IPv6_packet ip6 := f_IPv6_dec(gpdu);
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +0100911 if (ip6.header.ver != 6 or ip6.header.nexthead != 58) {
Harald Welte231b9412017-08-09 17:16:31 +0200912 repeat;
913 }
914 var PDU_ICMPv6 icmp6 := f_dec_PDU_ICMPv6(ip6.payload);
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +0100915 if (not match(icmp6, expected)) {
Harald Welte231b9412017-08-09 17:16:31 +0200916 repeat;
917 }
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +0100918 /* We are waiting for RA, update ctx */
919 if (match(icmp6, tr_ICMPv6_RA(?, 64))) {
920 ctx.ip6_prefix := icmp6.routerAdvertisement.options[0].prefixInformation.prefix;
921 log("RA with /64 prefix ", ctx.ip6_prefix);
922 }
Harald Welte231b9412017-08-09 17:16:31 +0200923 }
924 [] GTPU.receive(tr_GTPU_GPDU(?, ?)) { repeat; }
Pau Espin Pedrol9c1c2ae2023-12-05 14:24:49 +0100925 [] GTPU.receive {
926 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
927 log2str("Received unexpected GTPU while waiting for ICMPv6: ", expected));
928 }
929 [] T_default.timeout {
930 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
931 log2str("Timeout waiting for ICMPv6: ", expected));
932 }
Harald Welte231b9412017-08-09 17:16:31 +0200933 }
934 T_default.stop;
935 }
936
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +0100937 /* wait for GGSN to send us an ICMPv6 router advertisement */
938 function f_wait_rtr_adv(PdpContext ctx) runs on GT_CT {
939 f_wait_icmp6(ctx, tr_ICMPv6_RA(?, 64));
940 }
941
Pau Espin Pedrol6c7285d2018-01-30 17:20:22 +0100942 /* Wait for ICMPv6 echo request from GTP */
943 function f_wait_icmp6_echo_request(PdpContext ctx) runs on GT_CT {
944 f_wait_icmp6(ctx, tr_ICMPv6_ERQ);
945 }
946
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +0100947 /* Wait for ICMPv6 echo reply (or unreachable) from GTP */
948 function f_wait_icmp6_echo_reply(PdpContext ctx) runs on GT_CT {
949 f_wait_icmp6(ctx, (tr_ICMPv6_ERP,tr_ICMPv6_DU));
950 }
951
Oliver Smithee6a0882019-03-08 11:05:46 +0100952 /* create ICMPv6 router solicitation deriving link-id from PDP Context EUA */
953 function f_icmpv6_rs_for_pdp46(in PdpContext ctx) return octetstring {
954 var OCT16 interface_id := ctx.eua.endUserAddress.endUserAddressIPv4andIPv6.ipv6_address;
955 return f_gen_icmpv6_router_solicitation(interface_id);
956 }
957
958 /* generate and encode ICMPv6 neighbor solicitation for PDP Context */
959 function f_gen_icmpv6_neigh_solicit_for_pdp46(in PdpContext ctx) return octetstring {
960 var OCT16 interface_id := ctx.eua.endUserAddress.endUserAddressIPv4andIPv6.ipv6_address;
961 var OCT16 link_local := f_ipv6_link_local(interface_id);
962 var OCT16 daddr := f_ipv6_sol_node_mcast(link_local);
963
964 return f_gen_icmpv6_neigh_solicit(link_local, daddr, link_local);
965 }
966
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +0100967 /* Assert we don't receive a ICMPv4/6 echo reply (or unreachable) from GTP */
968 function f_wait_gtpu_fail(PdpContext ctx) runs on GT_CT {
969 T_default.start;
970 alt {
971 [] GTPU.receive { setverdict(fail); }
972 [] T_default.timeout { }
973 }
974 T_default.stop;
975 }
976
Harald Welte79737b42019-04-10 10:39:30 +0200977 /* list of protocols where we don't accept duplicates */
978 const OCT2List protocol_ids_nodupes := { 'C021'O, 'C023'O, 'C223'O, '8021'O };
979 private function f_PCO_permits_duplicates(OCT2 id) return boolean {
980 var integer i;
981 for (i := 0; i < lengthof(protocol_ids_nodupes); i := i+1) {
982 if (id == protocol_ids_nodupes[i]) {
983 return false;
984 }
985 }
986 return true;
987 }
988
989 /* ensure that every given protocol Identifier exist only exactly once in the PCO */
990 function f_PCO_ensure_no_duplicates(ProtConfigOptions pco) {
991 var OCT2List protocol_ids := {};
992 var integer i, j;
993 for (i := 0; i < lengthof(pco.protocols); i := i+1) {
994 var OCT2 id := pco.protocols[i].protocolID;
995 for (j := 0; j < lengthof(protocol_ids); j := j+1) {
996 if (not f_PCO_permits_duplicates(id) and id == protocol_ids[j]) {
997 setverdict(fail, "Duplicate ProtocolID ", id, " already present in ", pco.protocols);
998 }
999 }
1000 protocol_ids := protocol_ids & { id };
1001 }
1002 }
1003
Harald Welte0ef285b2017-08-13 20:06:01 +02001004 /* Test IPv6 context activation for dynamic IPv6 EUA without request of IPv6 DNS */
Harald Welteed7a1772017-08-09 20:26:20 +02001005 testcase TC_pdp6_act_deact() runs on GT_CT {
Harald Welte94ade362017-08-04 00:36:55 +02001006 f_init();
Harald Welte231b9412017-08-09 17:16:31 +02001007
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001008 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet6, valueof(t_EuaIPv6Dyn)));
Harald Welte811651e2017-08-05 15:25:06 +02001009 f_pdp_ctx_act(ctx);
Harald Welteed7a1772017-08-09 20:26:20 +02001010 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001011 f_shutdown_helper();
Harald Welteed7a1772017-08-09 20:26:20 +02001012 }
1013
Harald Welte0ef285b2017-08-13 20:06:01 +02001014 /* Test IPv6 context activation for dynamic IPv6 EUA wirh request of IPv6 DNS in PCO */
Harald Welteed7a1772017-08-09 20:26:20 +02001015 testcase TC_pdp6_act_deact_pcodns() runs on GT_CT {
1016 f_init();
1017
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001018 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet6, valueof(t_EuaIPv6Dyn)));
Harald Welteed7a1772017-08-09 20:26:20 +02001019 ctx.pco_req := valueof(ts_PCO_IPv6_DNS);
1020 f_pdp_ctx_act(ctx);
Pau Espin Pedrol363ba482018-01-29 18:42:00 +01001021
Harald Welte79737b42019-04-10 10:39:30 +02001022 f_PCO_ensure_no_duplicates(ctx.pco_neg);
Pau Espin Pedrol363ba482018-01-29 18:42:00 +01001023 /* verify PCO contains both primary and secondary DNS */
1024 var OCT4 ggsn_ip6_dns1 := f_inet6_addr(m_ggsn_ip6_dns1);
1025 if (not match(f_PCO_extract_proto(ctx.pco_neg, '0003'O, 1), ggsn_ip6_dns1)) {
1026 setverdict(fail, "Primary DNS IPv6 PCO option not found");
1027 }
1028
1029 var OCT4 ggsn_ip6_dns2 := f_inet6_addr(m_ggsn_ip6_dns2);
1030 if (not match(f_PCO_extract_proto(ctx.pco_neg, '0003'O, 2), ggsn_ip6_dns2)) {
1031 setverdict(fail, "Secondary DNS IPv6 PCO option not found");
1032 }
1033
Harald Welteed7a1772017-08-09 20:26:20 +02001034 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001035 f_shutdown_helper();
Harald Welteed7a1772017-08-09 20:26:20 +02001036 }
1037
Harald Welte0ef285b2017-08-13 20:06:01 +02001038 /* Test PDP context activation for dynamic IPv6 EUA with IPv6 DNS in PCO and router solicitation/advertisement */
Harald Welteed7a1772017-08-09 20:26:20 +02001039 testcase TC_pdp6_act_deact_icmp6() runs on GT_CT {
1040 f_init();
1041
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001042 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet6, valueof(t_EuaIPv6Dyn)));
Harald Welteed7a1772017-08-09 20:26:20 +02001043 ctx.pco_req := valueof(ts_PCO_IPv6_DNS);
1044 f_pdp_ctx_act(ctx);
Harald Welte231b9412017-08-09 17:16:31 +02001045
Harald Welte79737b42019-04-10 10:39:30 +02001046 f_PCO_ensure_no_duplicates(ctx.pco_neg);
Harald Welte231b9412017-08-09 17:16:31 +02001047
1048 f_send_gtpu(ctx, f_icmpv6_rs_for_pdp(ctx));
1049 f_wait_rtr_adv(ctx);
1050 f_send_gtpu(ctx, f_gen_icmpv6_neigh_solicit_for_pdp(ctx));
1051
Harald Welte811651e2017-08-05 15:25:06 +02001052 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001053 f_shutdown_helper();
Harald Welte94ade362017-08-04 00:36:55 +02001054 }
1055
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001056 /* Test PDP context activation for dynamic IPv6 EUA with IPv6 DNS in PCO and router solicitation/advertisement.
1057 Test we can send ICMPv6 ping over GTPU to DNS server. */
1058 testcase TC_pdp6_act_deact_gtpu_access() runs on GT_CT {
1059 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001060 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet6, valueof(t_EuaIPv6Dyn)));
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001061 ctx.pco_req := valueof(ts_PCO_IPv6_DNS);
1062 f_pdp_ctx_act(ctx);
1063
1064 f_send_gtpu(ctx, f_icmpv6_rs_for_pdp(ctx));
1065 f_wait_rtr_adv(ctx);
1066 f_send_gtpu(ctx, f_gen_icmpv6_neigh_solicit_for_pdp(ctx));
1067
1068 var OCT16 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '0003'O);
1069
1070 /* Check if we can use valid link-local src addr. */
1071 var OCT16 saddr_ll := f_ipv6_link_local(ctx.eua.endUserAddress.endUserAddressIPv6.ipv6_address);
1072 f_send_gtpu(ctx, f_gen_icmpv6_echo(saddr_ll, dns1_addr));
Pau Espin Pedrolb63d85f2022-02-07 16:11:47 +01001073 if (m_ggsn_impl == GGSN_IMPL_OSMOCOM) {
1074 f_wait_icmp6_echo_reply(ctx);
1075 } else {
1076 f_wait_gtpu_fail(ctx);
1077 }
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001078
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001079 /* Check if we can use valid global src addr, should work */
1080 var OCT16 saddr_glob := f_ipv6_global(ctx.eua.endUserAddress.endUserAddressIPv6.ipv6_address);
1081 f_send_gtpu(ctx, f_gen_icmpv6_echo(saddr_glob, dns1_addr));
1082 f_wait_icmp6_echo_reply(ctx);
1083
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001084 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001085 f_shutdown_helper();
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001086 }
1087
1088 /* Check that attempting RA with another ll src addr won't work, packet dropped: */
1089 testcase TC_pdp6_act_deact_gtpu_access_wrong_ll_saddr() runs on GT_CT {
1090 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001091 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet6, valueof(t_EuaIPv6Dyn)));
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001092 ctx.pco_req := valueof(ts_PCO_IPv6_DNS);
1093 f_pdp_ctx_act(ctx);
1094
1095 f_send_gtpu(ctx, f_icmpv6_rs_for_pdp(ctx));
1096 f_wait_rtr_adv(ctx);
1097 f_send_gtpu(ctx, f_gen_icmpv6_neigh_solicit_for_pdp(ctx));
1098
1099 var OCT16 saddr_ll := f_ipv6_link_local(ctx.eua.endUserAddress.endUserAddressIPv6.ipv6_address);
1100 var OCT16 saddr_ll_wrong := f_ipv6_mangle(saddr_ll, 8);
1101 f_send_gtpu(ctx, f_gen_icmpv6_router_solicitation(saddr_ll_wrong));
1102 f_wait_gtpu_fail(ctx);
1103
1104 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001105 f_shutdown_helper();
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001106 }
1107
1108 /* Assert that packets with wrong global src addr are dropped by GGSN */
1109 testcase TC_pdp6_act_deact_gtpu_access_wrong_global_saddr() runs on GT_CT {
1110 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001111 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet6, valueof(t_EuaIPv6Dyn)));
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001112 ctx.pco_req := valueof(ts_PCO_IPv6_DNS);
1113 f_pdp_ctx_act(ctx);
1114
1115 f_send_gtpu(ctx, f_icmpv6_rs_for_pdp(ctx));
1116 f_wait_rtr_adv(ctx);
1117 f_send_gtpu(ctx, f_gen_icmpv6_neigh_solicit_for_pdp(ctx));
1118
1119 var OCT16 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '0003'O);
1120 var OCT16 saddr_glob := f_ipv6_global(ctx.eua.endUserAddress.endUserAddressIPv6.ipv6_address);
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001121 var OCT16 saddr_wrong := f_ipv6_mangle(saddr_glob);
1122 f_send_gtpu(ctx, f_gen_icmpv6_echo(saddr_wrong, dns1_addr));
1123 f_wait_gtpu_fail(ctx);
1124
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001125 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001126 f_shutdown_helper();
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001127 }
1128
1129 /* Send an IPv4 ICMP ECHO REQUEST to APN6, should fail (packet dropped */
1130 testcase TC_pdp6_act_deact_gtpu_access_ipv4_apn6() runs on GT_CT {
1131 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001132 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet6, valueof(t_EuaIPv6Dyn)));
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001133 ctx.pco_req := valueof(ts_PCO_IPv6_DNS);
1134 f_pdp_ctx_act(ctx);
1135
1136 f_send_gtpu(ctx, f_icmpv6_rs_for_pdp(ctx));
1137 f_wait_rtr_adv(ctx);
1138 f_send_gtpu(ctx, f_gen_icmpv6_neigh_solicit_for_pdp(ctx));
1139
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001140 var OCT4 saddr_v4 := f_inet_addr("192.168.10.2");
1141 var OCT4 daddr_v4 := f_inet_addr("8.8.8.8");
1142 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr_v4, daddr_v4));
1143 f_wait_gtpu_fail(ctx);
1144
1145 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001146 f_shutdown_helper();
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001147 }
1148
Pau Espin Pedrol6c7285d2018-01-30 17:20:22 +01001149 /* Validate if different clients (pdp ctx) can reach one another through GGSN. */
1150 testcase TC_pdp6_clients_interact() runs on GT_CT {
1151 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001152 var PdpContext ctxA := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet6, valueof(t_EuaIPv6Dyn)));
1153 var PdpContext ctxB := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet6, valueof(t_EuaIPv6Dyn)));
Pau Espin Pedrol6c7285d2018-01-30 17:20:22 +01001154 f_pdp_ctx_act(ctxA);
1155 f_send_gtpu(ctxA, f_icmpv6_rs_for_pdp(ctxA));
1156 f_wait_rtr_adv(ctxA);
1157 f_send_gtpu(ctxA, f_gen_icmpv6_neigh_solicit_for_pdp(ctxA));
1158
1159 f_pdp_ctx_act(ctxB);
1160 f_send_gtpu(ctxB, f_icmpv6_rs_for_pdp(ctxB));
1161 f_wait_rtr_adv(ctxB);
1162 f_send_gtpu(ctxB, f_gen_icmpv6_neigh_solicit_for_pdp(ctxB));
1163
1164 var OCT16 addrA_ll := f_ipv6_link_local(ctxA.eua.endUserAddress.endUserAddressIPv6.ipv6_address);
1165 var OCT16 addrB_ll := f_ipv6_link_local(ctxB.eua.endUserAddress.endUserAddressIPv6.ipv6_address);
1166 var OCT16 addrA_glob := f_ipv6_global(ctxA.eua.endUserAddress.endUserAddressIPv6.ipv6_address);
1167 var OCT16 addrB_glob := f_ipv6_global(ctxB.eua.endUserAddress.endUserAddressIPv6.ipv6_address);
1168
1169 /* Validate if clients can interact using ll addr. */
1170 f_send_gtpu(ctxA, f_gen_icmpv6_echo(addrA_ll, addrB_ll));
1171 f_wait_gtpu_fail(ctxB);
1172
1173 /* Validate if clients can interact using global addr. */
1174 f_send_gtpu(ctxA, f_gen_icmpv6_echo(addrA_glob, addrB_glob));
1175 f_wait_gtpu_fail(ctxB);
1176
1177 f_pdp_ctx_del(ctxA, '1'B);
Pau Espin Pedrolbb2bb062019-09-03 12:28:12 +02001178 f_pdp_ctx_del(ctxB, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001179 f_shutdown_helper();
Pau Espin Pedrol6c7285d2018-01-30 17:20:22 +01001180 }
1181
Harald Welte0ef285b2017-08-13 20:06:01 +02001182 /* Test PDP context activation for dynamic IPv4 EUA without DNS request */
Harald Welteed7a1772017-08-09 20:26:20 +02001183 testcase TC_pdp4_act_deact() runs on GT_CT {
1184 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001185 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Harald Welteed7a1772017-08-09 20:26:20 +02001186 f_pdp_ctx_act(ctx);
1187 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001188 f_shutdown_helper();
Harald Welteed7a1772017-08-09 20:26:20 +02001189 }
1190
Harald Welte0ef285b2017-08-13 20:06:01 +02001191 /* Test PDP context activation for dynamic IPv4 EUA with IPv4 DNS in IPCP */
Harald Welteed7a1772017-08-09 20:26:20 +02001192 testcase TC_pdp4_act_deact_ipcp() runs on GT_CT {
1193 f_init();
Pau Espin Pedrolf69a4382018-01-29 13:09:00 +01001194 var OCT4 ggsn_ip4_dns1 := f_inet_addr(m_ggsn_ip4_dns1);
1195 var OCT4 ggsn_ip4_dns2 := f_inet_addr(m_ggsn_ip4_dns2);
Pau Espin Pedrolcff72f82024-01-26 16:58:48 +01001196 var uint8_t ipcp_req_id := oct2int(f_rnd_octstring(1));
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001197 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrolcff72f82024-01-26 16:58:48 +01001198 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_IPCP(ipcp_req_id));
Harald Welteed7a1772017-08-09 20:26:20 +02001199 f_pdp_ctx_act(ctx);
Harald Welte79737b42019-04-10 10:39:30 +02001200 f_PCO_ensure_no_duplicates(ctx.pco_neg);
Harald Welte71a36022017-12-04 18:55:58 +01001201 /* verify IPCP is at all contained */
1202 if (not match(ctx.pco_neg, tr_PCO_Contains('8021'O))) {
1203 setverdict(fail, "IPCP not found in PCO");
1204 }
1205 /* verify IPCP contains both primary and secondary DNS */
1206 var IpcpPacket ipcp := dec_IpcpPacket(f_PCO_extract_proto(ctx.pco_neg, '8021'O));
Pau Espin Pedrolcff72f82024-01-26 16:58:48 +01001207 if (not match(ipcp, tr_IPCP_Ack_DNS(ipcp_req_id, ggsn_ip4_dns1, ggsn_ip4_dns2))) {
1208 if (not match(ipcp, tr_IPCP_Ack_DNS(ipcp_req_id))) {
1209 if (not match(ipcp, tr_IPCP_Ack_DNS(?))) {
1210 setverdict(fail, "Primary/Secondary DNS PCO IPCP option not found");
1211 } else {
1212 setverdict(fail, "Primary/Secondary DNS PCO IPCP option found but not matching expected identifier");
1213 }
Pau Espin Pedrolf69a4382018-01-29 13:09:00 +01001214 } else {
1215 setverdict(fail, "Primary/Secondary DNS PCO IPCP option found but not matching expected values");
1216 }
Harald Welte71a36022017-12-04 18:55:58 +01001217 }
Harald Welteed7a1772017-08-09 20:26:20 +02001218 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001219 f_shutdown_helper();
Harald Welteed7a1772017-08-09 20:26:20 +02001220 }
1221
Harald Weltef8298542019-04-10 10:15:28 +02001222 /* Test PDP context activation for dynamic IPv4 EUA with IPv4 DNS in IPCP + PAP authentication (broken) */
1223 testcase TC_pdp4_act_deact_ipcp_pap_broken() runs on GT_CT {
1224 f_init();
1225 var OCT4 ggsn_ip4_dns1 := f_inet_addr(m_ggsn_ip4_dns1);
1226 var OCT4 ggsn_ip4_dns2 := f_inet_addr(m_ggsn_ip4_dns2);
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001227 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Harald Weltef8298542019-04-10 10:15:28 +02001228 ctx.pco_req := valueof(ts_PCO_PAP_IPv4_DNS);
1229 f_pdp_ctx_act(ctx);
1230 f_PCO_ensure_no_duplicates(ctx.pco_neg);
1231 /* verify IPCP is at all contained */
1232 if (not match(ctx.pco_neg, tr_PCO_Contains('8021'O))) {
1233 setverdict(fail, "IPCP not found in PCO");
1234 }
1235 /* verify IPCP contains both primary and secondary DNS */
1236 var IpcpPacket ipcp := dec_IpcpPacket(f_PCO_extract_proto(ctx.pco_neg, '8021'O));
1237 if (not match(ipcp, tr_IPCP_Ack_DNS(0, ggsn_ip4_dns1, ggsn_ip4_dns2))) {
1238 if (not match(ipcp, tr_IPCP_Ack_DNS(0))) {
1239 setverdict(fail, "Primary/Secondary DNS PCO IPCP option not found");
1240 } else {
1241 setverdict(fail, "Primary/Secondary DNS PCO IPCP option found but not matching expected values");
1242 }
1243 }
1244 /* verify that PAP is contained */
1245 if (not match(ctx.pco_neg, tr_PCO_Contains('C023'O))) {
1246 setverdict(fail, "PAP not found in PCO");
1247 }
1248 var PapPacket pap := dec_PapPacket(f_PCO_extract_proto(ctx.pco_neg, 'C023'O));
1249 if (not match(pap, tr_PAP_AuthAck)) {
1250 setverdict(fail, "PAP isn't an AuthenticateAck: ", pap);
1251 }
1252 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001253 f_shutdown_helper();
Harald Weltef8298542019-04-10 10:15:28 +02001254 }
1255
Harald Welte0ef285b2017-08-13 20:06:01 +02001256 /* Test PDP context activation for dynamic IPv4 EUA with IPv4 DNS in PCO */
Harald Welteed7a1772017-08-09 20:26:20 +02001257 testcase TC_pdp4_act_deact_pcodns() runs on GT_CT {
1258 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001259 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Harald Weltedca80052017-08-13 20:01:38 +02001260 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
Harald Welteed7a1772017-08-09 20:26:20 +02001261 f_pdp_ctx_act(ctx);
Pau Espin Pedrol363ba482018-01-29 18:42:00 +01001262
Harald Welte79737b42019-04-10 10:39:30 +02001263 f_PCO_ensure_no_duplicates(ctx.pco_neg);
Pau Espin Pedrol363ba482018-01-29 18:42:00 +01001264 /* verify PCO contains both primary and secondary DNS */
1265 var OCT4 ggsn_ip4_dns1 := f_inet_addr(m_ggsn_ip4_dns1);
1266 if (not match(f_PCO_extract_proto(ctx.pco_neg, '000d'O, 1), ggsn_ip4_dns1)) {
1267 setverdict(fail, "Primary DNS IPv4 PCO option not found");
1268 }
1269
1270 var OCT4 ggsn_ip4_dns2 := f_inet_addr(m_ggsn_ip4_dns2);
1271 if (not match(f_PCO_extract_proto(ctx.pco_neg, '000d'O, 2), ggsn_ip4_dns2)) {
1272 setverdict(fail, "Secondary DNS IPv4 PCO option not found");
1273 }
1274
Harald Welteed7a1772017-08-09 20:26:20 +02001275 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001276 f_shutdown_helper();
Harald Welteed7a1772017-08-09 20:26:20 +02001277 }
1278
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001279 /* Test PDP context activation for dynamic IPv4 EUA.
1280 Test we can send ICMPv6 ping over GTPU to DNS server. */
1281 testcase TC_pdp4_act_deact_gtpu_access() runs on GT_CT {
1282 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001283 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001284 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
1285 f_pdp_ctx_act(ctx);
1286
Harald Welte79737b42019-04-10 10:39:30 +02001287 f_PCO_ensure_no_duplicates(ctx.pco_neg);
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001288 var OCT4 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '000d'O);
1289
1290 /* Check if we can use valid global src addr, should work */
1291 var OCT4 saddr := ctx.eua.endUserAddress.endUserAddressIPv4.ipv4_address;
1292 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
1293 f_wait_icmp4_echo_reply(ctx);
1294
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001295 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001296 f_shutdown_helper();
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001297 }
1298
1299 /* Assert that packets with wrong global src addr are dropped by GGSN */
1300 testcase TC_pdp4_act_deact_gtpu_access_wrong_saddr() runs on GT_CT {
1301 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001302 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001303 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
1304 f_pdp_ctx_act(ctx);
1305
1306 f_PCO_ensure_no_duplicates(ctx.pco_neg);
1307 var OCT4 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '000d'O);
1308 var OCT4 saddr := ctx.eua.endUserAddress.endUserAddressIPv4.ipv4_address;
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001309 var OCT4 saddr_wrong := substr(saddr, 0, 3) & (saddr[3] xor4b '11'O);
1310 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr_wrong, dns1_addr));
1311 f_wait_gtpu_fail(ctx);
1312
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001313 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001314 f_shutdown_helper();
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001315 }
1316
1317 /* Send an IPv6 RA to APN4, should fail (packet dropped) */
1318 testcase TC_pdp4_act_deact_gtpu_access_ipv6_apn4() runs on GT_CT {
1319 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001320 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001321 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
1322 f_pdp_ctx_act(ctx);
1323
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001324 /* Send an IPv6 RA to APN4, should fail (packet dropped) */
1325 var OCT16 saddr_v6 := f_inet6_addr("fde4:8dba:82e1:2000:1:2:3:4");
1326 f_send_gtpu(ctx, f_gen_icmpv6_router_solicitation(saddr_v6));
1327 f_wait_gtpu_fail(ctx);
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001328
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001329 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001330 f_shutdown_helper();
Pau Espin Pedrol3d9338f2018-01-29 20:42:54 +01001331 }
1332
Stefan Sperlingc479e4f2018-04-03 19:34:16 +02001333 /* Helper function for tests below. */
1334 function f_pdp4_clients_interact() runs on GT_CT {
Pau Espin Pedrol6c7285d2018-01-30 17:20:22 +01001335 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001336 var PdpContext ctxA := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
1337 var PdpContext ctxB := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrol6c7285d2018-01-30 17:20:22 +01001338 f_pdp_ctx_act(ctxA);
1339 f_pdp_ctx_act(ctxB);
1340 var OCT4 addrA := ctxA.eua.endUserAddress.endUserAddressIPv4.ipv4_address;
1341 var OCT4 addrB := ctxB.eua.endUserAddress.endUserAddressIPv4.ipv4_address;
1342 f_send_gtpu(ctxA, f_gen_icmpv4_echo(addrA, addrB));
1343 f_wait_icmp4_echo_request(ctxB);
1344
1345 f_pdp_ctx_del(ctxA, '1'B);
Pau Espin Pedrolbb2bb062019-09-03 12:28:12 +02001346 f_pdp_ctx_del(ctxB, '1'B);
Pau Espin Pedrol6c7285d2018-01-30 17:20:22 +01001347 }
1348
Stefan Sperlingc479e4f2018-04-03 19:34:16 +02001349 /* Validate if different clients (pdp ctx) can reach one another through GGSN. */
1350 testcase TC_pdp4_clients_interact_with_txseq() runs on GT_CT {
Harald Welte3e0b0392018-04-26 09:46:21 +02001351 use_gtpu_txseq := true;
Stefan Sperlingc479e4f2018-04-03 19:34:16 +02001352 f_pdp4_clients_interact();
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001353 f_shutdown_helper();
Stefan Sperlingc479e4f2018-04-03 19:34:16 +02001354 }
1355
1356 /* Validate if different clients (pdp ctx) can reach one another through GGSN (without Tx sequence number). */
1357 testcase TC_pdp4_clients_interact_without_txseq() runs on GT_CT {
Harald Welte3e0b0392018-04-26 09:46:21 +02001358 use_gtpu_txseq := false;
Stefan Sperlingc479e4f2018-04-03 19:34:16 +02001359 f_pdp4_clients_interact();
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001360 f_shutdown_helper();
Stefan Sperlingc479e4f2018-04-03 19:34:16 +02001361 }
1362
Harald Weltedca80052017-08-13 20:01:38 +02001363 testcase TC_echo_req_resp() runs on GT_CT {
1364 f_init();
1365 f_send_gtpc(ts_GTPC_PING(g_peer_c, g_c_seq_nr));
1366 T_default.start;
1367 alt {
1368 [] GTPC.receive(tr_GTPC_PONG(g_peer_c)) { setverdict(pass); };
1369 [] GTPC.receive { repeat; };
1370 [] T_default.timeout { setverdict(fail); }
1371 }
1372 T_default.stop;
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001373 f_shutdown_helper();
Harald Weltedca80052017-08-13 20:01:38 +02001374 }
1375
Pau Espin Pedrol480e67f2022-02-09 16:37:47 +01001376 testcase TC_echo_req_resp_gtpu() runs on GT_CT {
1377 f_init();
1378 GTPU.send(ts_GTPU_PING(g_peer_u, g_d_seq_nr));
1379 T_default.start;
1380 alt {
1381 [] GTPU.receive(tr_GTPU_PONG(g_peer_u)) { setverdict(pass); };
1382 [] GTPU.receive { repeat; };
1383 [] T_default.timeout { setverdict(fail); }
1384 }
1385 T_default.stop;
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001386 f_shutdown_helper();
Pau Espin Pedrol480e67f2022-02-09 16:37:47 +01001387 }
1388
Philipp Maier33e52612018-05-30 17:22:02 +02001389 /* Test if the parser can cope with PCO that only contain either a
1390 * single primary DNS or a secondary DNS. */
1391 testcase TC_pdp4_act_deact_with_single_dns() runs on GT_CT {
1392
1393 /* Note: an unpatched osmo-ggsn version will enter an endless-loop when
1394 * the test is executed.
1395 * see also: Change-Id Icffde89f9bc5d8fcadf6e2dd6c0b4de03440edd5 and OS#3288 */
1396
1397 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001398 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Philipp Maier33e52612018-05-30 17:22:02 +02001399 var OCT4 ggsn_ip4_dns1 := f_inet_addr(m_ggsn_ip4_dns1);
1400 var OCT4 ggsn_ip4_dns2 := f_inet_addr(m_ggsn_ip4_dns2);
1401 var octetstring pco_neg_dns;
1402 var octetstring pco_neg_dns_expected;
1403
1404 /* PCO with primary DNS only */
1405 ctx.pco_req := valueof(ts_PCO_IPv4_PRI_DNS_IPCP);
1406 f_pdp_ctx_act(ctx);
Harald Welte79737b42019-04-10 10:39:30 +02001407 f_PCO_ensure_no_duplicates(ctx.pco_neg);
Philipp Maier33e52612018-05-30 17:22:02 +02001408 pco_neg_dns := f_PCO_extract_proto(ctx.pco_neg, '8021'O, 1);
1409 pco_neg_dns_expected := '0200000A8106'O & ggsn_ip4_dns1
1410 /* Note: The prepended hex bytes encode the following information:
1411 * 0x02 = Configuration ACK
1412 * 0x00 = Identifier
1413 * 0x000a = Length
1414 * 0x81 = Type (Primary DNS Server Address)
1415 * 0x06 = Length
1416 * (4 byte IP-Address appended) */
1417 if (not match(pco_neg_dns, pco_neg_dns_expected)) {
1418 setverdict(fail, "Primary DNS IPv4 PCO option not found");
1419 }
1420 f_pdp_ctx_del(ctx, '1'B);
1421
1422 /* PCO with secondary DNS only */
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001423 ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Philipp Maier33e52612018-05-30 17:22:02 +02001424 ctx.pco_req := valueof(ts_PCO_IPv4_SEC_DNS_IPCP);
1425 f_pdp_ctx_act(ctx);
1426 pco_neg_dns := f_PCO_extract_proto(ctx.pco_neg, '8021'O, 1);
1427 pco_neg_dns_expected := '0200000A8306'O & ggsn_ip4_dns2
1428 if (not match(pco_neg_dns, pco_neg_dns_expected)) {
1429 setverdict(fail, "Secondary DNS IPv4 PCO option not found");
1430 }
1431 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001432 f_shutdown_helper();
Philipp Maier33e52612018-05-30 17:22:02 +02001433 }
1434
1435 /* Test if the parser can cope with PCO that contains primary and secondary DNS in a separate IPCP container.
1436 * Note: an unpatched osmo-ggsn version will enter an endless-loop when the test is run
1437 * see Change-Id Icffde89f9bc5d8fcadf6e2dd6c0b4de03440edd5 and OS#3288. */
1438 testcase TC_pdp4_act_deact_with_separate_dns() runs on GT_CT {
1439
1440 /* Note: an unpatched osmo-ggsn version will enter an endless-loop when
1441 * the test is executed.
1442 * see also: Change-Id Icffde89f9bc5d8fcadf6e2dd6c0b4de03440edd5 and OS#3288 */
1443
1444 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001445 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Philipp Maier33e52612018-05-30 17:22:02 +02001446 var OCT4 ggsn_ip4_dns1 := f_inet_addr(m_ggsn_ip4_dns1);
1447 var OCT4 ggsn_ip4_dns2 := f_inet_addr(m_ggsn_ip4_dns2);
1448 var octetstring pco_neg_dns;
1449 var octetstring pco_neg_dns_expected;
1450
1451 ctx.pco_req := valueof(ts_PCO_IPv4_SEPARATE_DNS_IPCP);
1452 f_pdp_ctx_act(ctx);
1453
1454 /* Check if primary DNS is contained */
1455 pco_neg_dns := f_PCO_extract_proto(ctx.pco_neg, '8021'O, 1);
1456 pco_neg_dns_expected := '0200000A8106'O & ggsn_ip4_dns1
1457 if (not match(pco_neg_dns, pco_neg_dns_expected)) {
1458 setverdict(fail, "Primary DNS IPv4 PCO option not found");
1459 }
Philipp Maier33e52612018-05-30 17:22:02 +02001460
1461 /* Check if secondary DNS is contained */
Stefan Sperling8e7a3962018-07-19 19:24:38 +02001462 /* This used to fail due to a bug in osmo-ggsn, see OS#3381 */
1463 pco_neg_dns := f_PCO_extract_proto(ctx.pco_neg, '8021'O, 2);
Philipp Maier33e52612018-05-30 17:22:02 +02001464 pco_neg_dns_expected := '0200000A8306'O & ggsn_ip4_dns2
1465 if (not match(pco_neg_dns, pco_neg_dns_expected)) {
1466 setverdict(fail, "Secondary DNS IPv4 PCO option not found");
1467 }
1468 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001469 f_shutdown_helper();
Philipp Maier33e52612018-05-30 17:22:02 +02001470 }
1471
Pau Espin Pedrolcd326c52022-02-14 18:57:43 +01001472 /* Validate that SUT updates remote TEIC when requested through UpdatePDPContextRequest */
1473 testcase TC_pdp4_act_update_teic() runs on GT_CT {
1474 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001475 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrolcd326c52022-02-14 18:57:43 +01001476 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
1477 f_pdp_ctx_act(ctx);
1478
1479 /* UpdatePDPContestRequest changing the local TEIC */
1480 var OCT4 new_teic := ctx.teic;
1481 new_teic[3] := new_teic[3] xor4b '11'O;
1482 f_pdp_ctx_update(ctx, new_teic := new_teic);
1483
1484 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001485 f_shutdown_helper();
Pau Espin Pedrolcd326c52022-02-14 18:57:43 +01001486 }
1487
1488 /* Validate that SUT updates remote TEID when requested through UpdatePDPContextRequest */
1489 testcase TC_pdp4_act_update_teid() runs on GT_CT {
1490 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001491 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrolcd326c52022-02-14 18:57:43 +01001492 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
1493 f_pdp_ctx_act(ctx);
1494
1495 f_PCO_ensure_no_duplicates(ctx.pco_neg);
1496 var OCT4 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '000d'O);
1497 var OCT4 saddr := ctx.eua.endUserAddress.endUserAddressIPv4.ipv4_address;
1498
1499 /* Data is sent (back) to the local TEID established during CreatePDPContext */
1500 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
1501 f_wait_icmp4_echo_reply(ctx);
1502
1503 /* UpdatePDPContestRequest changing the local TEID */
1504 var OCT4 new_teid := ctx.teid;
1505 new_teid[3] := new_teid[3] xor4b '11'O;
1506 f_pdp_ctx_update(ctx, new_teid := new_teid);
1507
1508 /* Check if we can send data after updating the PDP context. Answer should be sent to the new TEID */
1509 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
1510 f_wait_icmp4_echo_reply(ctx);
1511
1512 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001513 f_shutdown_helper();
Pau Espin Pedrolcd326c52022-02-14 18:57:43 +01001514 }
1515
Oliver Smithee6a0882019-03-08 11:05:46 +01001516 /* Test IPv4v6 context activation for dynamic IPv4v6 EUA without DNS request */
1517 testcase TC_pdp46_act_deact() runs on GT_CT {
1518 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001519 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet46, valueof(t_EuaIPv4Dynv6Dyn)));
Oliver Smithee6a0882019-03-08 11:05:46 +01001520 f_pdp_ctx_act(ctx);
1521 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001522 f_shutdown_helper();
Oliver Smithee6a0882019-03-08 11:05:46 +01001523 }
1524
1525 /* Test PDP context activation for dynamic IPv4v6 EUA with IPv4 DNS in IPCP */
1526 testcase TC_pdp46_act_deact_ipcp() runs on GT_CT {
1527 f_init();
1528 var OCT4 ggsn_ip4_dns1 := f_inet_addr(m_ggsn_ip4_dns1);
1529 var OCT4 ggsn_ip4_dns2 := f_inet_addr(m_ggsn_ip4_dns2);
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001530 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet46, valueof(t_EuaIPv4Dynv6Dyn)));
Oliver Smithee6a0882019-03-08 11:05:46 +01001531 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_IPCP);
1532 f_pdp_ctx_act(ctx);
Harald Welte79737b42019-04-10 10:39:30 +02001533 f_PCO_ensure_no_duplicates(ctx.pco_neg);
Oliver Smithee6a0882019-03-08 11:05:46 +01001534 /* verify IPCP is at all contained */
1535 if (not match(ctx.pco_neg, tr_PCO_Contains('8021'O))) {
1536 setverdict(fail, "IPCP not found in PCO");
1537 }
Harald Welte79737b42019-04-10 10:39:30 +02001538 f_PCO_ensure_no_duplicates(ctx.pco_neg);
Oliver Smithee6a0882019-03-08 11:05:46 +01001539 /* verify IPCP contains both primary and secondary IPv4 DNS */
1540 var IpcpPacket ipcp := dec_IpcpPacket(f_PCO_extract_proto(ctx.pco_neg, '8021'O));
1541 if (not match(ipcp, tr_IPCP_Ack_DNS(0, ggsn_ip4_dns1, ggsn_ip4_dns2))) {
1542 if (not match(ipcp, tr_IPCP_Ack_DNS(0))) {
1543 setverdict(fail, "Primary/Secondary DNS PCO IPCP option not found");
1544 } else {
1545 setverdict(fail, "Primary/Secondary DNS PCO IPCP option found but not matching expected values");
1546 }
1547 }
1548 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001549 f_shutdown_helper();
Oliver Smithee6a0882019-03-08 11:05:46 +01001550 }
1551
1552 /* Test PDP context activation for dynamic IPv4v6 EUA with IPv6 DNS in PCO and router solicitation/advertisement */
1553 testcase TC_pdp46_act_deact_icmp6() runs on GT_CT {
1554 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001555 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet46, valueof(t_EuaIPv4Dynv6Dyn)));
Oliver Smithee6a0882019-03-08 11:05:46 +01001556 ctx.pco_req := valueof(ts_PCO_IPv6_DNS);
1557 f_pdp_ctx_act(ctx);
1558
1559 f_send_gtpu(ctx, f_icmpv6_rs_for_pdp46(ctx));
1560 f_wait_rtr_adv(ctx);
1561 f_send_gtpu(ctx, f_gen_icmpv6_neigh_solicit_for_pdp46(ctx));
1562
1563 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001564 f_shutdown_helper();
Oliver Smithee6a0882019-03-08 11:05:46 +01001565 }
1566
1567 /* Test IPv4v6 context activation for dynamic IPv4v6 EUA with request of IPv4 DNS in PCO */
1568 testcase TC_pdp46_act_deact_pcodns4() runs on GT_CT {
1569 f_init();
1570
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001571 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet46, valueof(t_EuaIPv4Dynv6Dyn)));
Oliver Smithee6a0882019-03-08 11:05:46 +01001572 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
1573 f_pdp_ctx_act(ctx);
1574
Harald Welte79737b42019-04-10 10:39:30 +02001575 f_PCO_ensure_no_duplicates(ctx.pco_neg);
Oliver Smithee6a0882019-03-08 11:05:46 +01001576 /* verify PCO contains both primary and secondary IPv4 DNS */
1577 var OCT4 ggsn_ip4_dns1 := f_inet_addr(m_ggsn_ip4_dns1);
1578 if (not match(f_PCO_extract_proto(ctx.pco_neg, '000d'O, 1), ggsn_ip4_dns1)) {
1579 setverdict(fail, "Primary DNS IPv4 PCO option not found");
1580 }
1581
1582 var OCT4 ggsn_ip4_dns2 := f_inet_addr(m_ggsn_ip4_dns2);
1583 if (not match(f_PCO_extract_proto(ctx.pco_neg, '000d'O, 2), ggsn_ip4_dns2)) {
1584 setverdict(fail, "Secondary DNS IPv4 PCO option not found");
1585 }
1586
1587 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001588 f_shutdown_helper();
Oliver Smithee6a0882019-03-08 11:05:46 +01001589 }
1590
1591 /* Test IPv4v6 context activation for dynamic IPv4v6 EUA with request of IPv6 DNS in PCO */
1592 testcase TC_pdp46_act_deact_pcodns6() runs on GT_CT {
1593 f_init();
1594
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001595 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet46, valueof(t_EuaIPv4Dynv6Dyn)));
Oliver Smithee6a0882019-03-08 11:05:46 +01001596 ctx.pco_req := valueof(ts_PCO_IPv6_DNS);
1597 f_pdp_ctx_act(ctx);
1598
Harald Welte79737b42019-04-10 10:39:30 +02001599 f_PCO_ensure_no_duplicates(ctx.pco_neg);
Oliver Smithee6a0882019-03-08 11:05:46 +01001600 /* verify PCO contains both primary and secondary IPv6 DNS */
1601 var OCT4 ggsn_ip6_dns1 := f_inet6_addr(m_ggsn_ip6_dns1);
1602 if (not match(f_PCO_extract_proto(ctx.pco_neg, '0003'O, 1), ggsn_ip6_dns1)) {
1603 setverdict(fail, "Primary DNS IPv6 PCO option not found");
1604 }
1605
1606 var OCT4 ggsn_ip6_dns2 := f_inet6_addr(m_ggsn_ip6_dns2);
1607 if (not match(f_PCO_extract_proto(ctx.pco_neg, '0003'O, 2), ggsn_ip6_dns2)) {
1608 setverdict(fail, "Secondary DNS IPv6 PCO option not found");
1609 }
1610
1611 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001612 f_shutdown_helper();
Oliver Smithee6a0882019-03-08 11:05:46 +01001613 }
1614
1615 /* Test PDP context activation for dynamic IPv4v6 EUA.
1616 Test we can send ICMPv6 ping over GTPU to DNS server. */
1617 testcase TC_pdp46_act_deact_gtpu_access() runs on GT_CT {
1618 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001619 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet46, valueof(t_EuaIPv4Dynv6Dyn)));
Oliver Smithee6a0882019-03-08 11:05:46 +01001620 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
1621 f_pdp_ctx_act(ctx);
1622
1623 var OCT4 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '000d'O);
1624
1625 /* Check if we can use valid global src addr, should work */
1626 var OCT4 saddr := ctx.eua.endUserAddress.endUserAddressIPv4andIPv6.ipv4_address;
1627 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
1628 f_wait_icmp4_echo_reply(ctx);
1629
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001630 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001631 f_shutdown_helper();
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001632 }
1633
1634 /* Assert that packets with wrong ipv4 src addr are dropped by GGSN on APN IPv4v6 */
1635 testcase TC_pdp46_act_deact_gtpu_access_wrong_saddr_ipv4() runs on GT_CT {
1636 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001637 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet46, valueof(t_EuaIPv4Dynv6Dyn)));
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001638 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
1639 f_pdp_ctx_act(ctx);
1640
1641 var OCT4 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '000d'O);
1642 var OCT4 saddr := ctx.eua.endUserAddress.endUserAddressIPv4andIPv6.ipv4_address;
Oliver Smithee6a0882019-03-08 11:05:46 +01001643 var OCT4 saddr_wrong := substr(saddr, 0, 3) & (saddr[3] xor4b '11'O);
1644 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr_wrong, dns1_addr));
1645 f_wait_gtpu_fail(ctx);
1646
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001647 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001648 f_shutdown_helper();
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001649 }
1650
Pau Espin Pedrolc6ac6952022-02-14 11:19:23 +01001651 /* Check that attempting RA with another ll src addr won't work, packet dropped: */
1652 testcase TC_pdp46_act_deact_gtpu_access_wrong_ll_saddr_ipv6() runs on GT_CT {
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001653 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001654 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet46, valueof(t_EuaIPv4Dynv6Dyn)));
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001655 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
1656 f_pdp_ctx_act(ctx);
1657
Pau Espin Pedrolc6ac6952022-02-14 11:19:23 +01001658 var OCT16 saddr_ll := f_ipv6_link_local(ctx.eua.endUserAddress.endUserAddressIPv4andIPv6.ipv6_address);
1659 var OCT16 saddr_ll_wrong := f_ipv6_mangle(saddr_ll, 8);
1660 f_send_gtpu(ctx, f_gen_icmpv6_router_solicitation(saddr_ll_wrong));
1661 f_wait_gtpu_fail(ctx);
1662
1663 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001664 f_shutdown_helper();
Pau Espin Pedrolc6ac6952022-02-14 11:19:23 +01001665 }
1666
1667 /* Assert that packets with wrong ipv6 global src addr are dropped by GGSN on APN IPv4v6 */
1668 testcase TC_pdp46_act_deact_gtpu_access_wrong_global_saddr_ipv6() runs on GT_CT {
1669 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001670 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet46, valueof(t_EuaIPv4Dynv6Dyn)));
Pau Espin Pedrolc6ac6952022-02-14 11:19:23 +01001671 ctx.pco_req := valueof(ts_PCO_IPv6_DNS);
1672 f_pdp_ctx_act(ctx);
1673
1674 f_send_gtpu(ctx, f_icmpv6_rs_for_pdp(ctx));
1675 f_wait_rtr_adv(ctx);
1676 f_send_gtpu(ctx, f_gen_icmpv6_neigh_solicit_for_pdp(ctx));
1677
1678 var OCT16 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '0003'O);
1679 var OCT16 saddr_glob := f_ipv6_global(ctx.eua.endUserAddress.endUserAddressIPv4andIPv6.ipv6_address);
1680 var OCT16 saddr_wrong := f_ipv6_mangle(saddr_glob);
1681 f_send_gtpu(ctx, f_gen_icmpv6_echo(saddr_wrong, dns1_addr));
Oliver Smithee6a0882019-03-08 11:05:46 +01001682 f_wait_gtpu_fail(ctx);
Pau Espin Pedrolc8c03412022-02-11 13:39:26 +01001683
Oliver Smithee6a0882019-03-08 11:05:46 +01001684 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001685 f_shutdown_helper();
Oliver Smithee6a0882019-03-08 11:05:46 +01001686 }
1687
1688 /* Validate if different clients (pdp ctx) can reach one another through GGSN. */
1689 testcase TC_pdp46_clients_interact() runs on GT_CT {
1690 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001691 var PdpContext ctxA := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet46, valueof(t_EuaIPv4Dynv6Dyn)));
1692 var PdpContext ctxB := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInet46, valueof(t_EuaIPv4Dynv6Dyn)));
Oliver Smithee6a0882019-03-08 11:05:46 +01001693 f_pdp_ctx_act(ctxA);
1694 f_send_gtpu(ctxA, f_icmpv6_rs_for_pdp46(ctxA));
1695 f_wait_rtr_adv(ctxA);
1696 f_send_gtpu(ctxA, f_gen_icmpv6_neigh_solicit_for_pdp46(ctxA));
1697
1698 f_pdp_ctx_act(ctxB);
1699 f_send_gtpu(ctxB, f_icmpv6_rs_for_pdp46(ctxB));
1700 f_wait_rtr_adv(ctxB);
1701 f_send_gtpu(ctxB, f_gen_icmpv6_neigh_solicit_for_pdp46(ctxB));
1702
1703 var OCT16 addrA_ll := f_ipv6_link_local(ctxA.eua.endUserAddress.endUserAddressIPv4andIPv6.ipv6_address);
1704 var OCT16 addrB_ll := f_ipv6_link_local(ctxB.eua.endUserAddress.endUserAddressIPv4andIPv6.ipv6_address);
1705 var OCT16 addrA_glob := f_ipv6_global(ctxA.eua.endUserAddress.endUserAddressIPv4andIPv6.ipv6_address);
1706 var OCT16 addrB_glob := f_ipv6_global(ctxB.eua.endUserAddress.endUserAddressIPv4andIPv6.ipv6_address);
1707
1708 /* Validate if clients can interact using ll addr. */
1709 f_send_gtpu(ctxA, f_gen_icmpv6_echo(addrA_ll, addrB_ll));
1710 f_wait_gtpu_fail(ctxB);
1711
1712 /* Validate if clients can interact using global addr. */
1713 f_send_gtpu(ctxA, f_gen_icmpv6_echo(addrA_glob, addrB_glob));
1714 f_wait_gtpu_fail(ctxB);
1715
1716 f_pdp_ctx_del(ctxA, '1'B);
Pau Espin Pedrolbb2bb062019-09-03 12:28:12 +02001717 f_pdp_ctx_del(ctxB, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001718 f_shutdown_helper();
Oliver Smithee6a0882019-03-08 11:05:46 +01001719 }
1720
Pau Espin Pedrol22d597f2019-08-21 16:16:58 +02001721 /* Test IPv4v6 context activation for dynamic IPv4v6 EUA on a v4-only APN */
1722 testcase TC_pdp46_act_deact_apn4() runs on GT_CT {
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +01001723 const OCT1 cause_accept := '80'O; /* Normal accept cause */
1724 const OCT1 cause_new_pdp_type := '81'O; /* Cause: New PDP type due to network preference */
1725 const OCT1 cause_unknown_pdp := 'DC'O; /* Cause: Unknown PDP address or PDP type */
1726 var CreatePDPContextResponse cpr;
1727
Pau Espin Pedrol22d597f2019-08-21 16:16:58 +02001728 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001729 var PdpContext ctx46 := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dynv6Dyn)));
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +01001730 cpr := f_pdp_ctx_act(ctx46, (cause_unknown_pdp, cause_new_pdp_type));
Pau Espin Pedrol22d597f2019-08-21 16:16:58 +02001731
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +01001732 if (cpr.cause.causevalue == cause_new_pdp_type) {
1733 /* 3GPP TS 23.060 sec 9.2.1: "If the MS requests PDP type IPv4v6,
1734 * but the operator preferences dictate the use of a single IP
1735 * version only, the PDP type shall be changed to a single address
1736 * PDP type (IPv4 or IPv6) and a reason cause shall be returned to
1737 * the MS indicating that only the assigned PDP type is allowed. In
1738 * this case, the MS shall not request another PDP context for the
1739 * other PDP type during the existence of the PDP context." */
1740 f_pdp_ctx_del(ctx46, '1'B);
1741 } else {
1742 /* 3GPP TS 23.060 sec 9.2.1 NOTE 5: If the MS requests PDP type
1743 * IPv4v6, and the PDP context is rejected due to "unknown PDP
1744 * type", the MS can attempt to establish dual-stack connectivity
1745 * by performing two PDP context request procedures to activate an
1746 * IPv4 PDP context and an IPv6 PDP context, both to the same APN. A
1747 * typical MS first attempts v4v6, and if rejected, then tries v4
1748 * and v6 separetly */
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001749 var PdpContext ctx4 := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +01001750 f_pdp_ctx_act(ctx4, cause_accept); /* Normal accept cause */
Pau Espin Pedrol22d597f2019-08-21 16:16:58 +02001751
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001752 var PdpContext ctx6 := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv6Dyn)));
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +01001753 f_pdp_ctx_act(ctx6, cause_unknown_pdp); /* Cause: Unknown PDP address or PDP type */
Pau Espin Pedrol22d597f2019-08-21 16:16:58 +02001754
Pau Espin Pedrol0f464d62022-02-23 14:04:29 +01001755 f_pdp_ctx_del(ctx4, '1'B);
1756 }
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001757 f_shutdown_helper();
Pau Espin Pedrol22d597f2019-08-21 16:16:58 +02001758 }
1759
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +02001760 /* Validate if 2nd CtxCreateReq with increased Recovery IE causes ggsn to drop 1st one (while keeping 2nd one). */
1761 testcase TC_pdp_act2_recovery() runs on GT_CT {
1762 var Gtp1cUnitdata ud;
1763 var default d;
1764 var boolean ctxA_deleted := false;
1765 var boolean ctxB_created := false;
1766
1767 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001768 var PdpContext ctxA := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
1769 var PdpContext ctxB := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +02001770 f_pdp_ctx_act(ctxA);
1771
Vadim Yanitskiyd344b4a2022-02-09 18:28:18 +06001772 g_restart_ctr := int2oct((oct2int(g_restart_ctr) + 1) mod 256, 1);
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +02001773
1774 log("sending 2nd CreatePDP (recovery increased)");
1775 f_send_gtpc(ts_GTPC_CreatePDP(g_peer_c, g_c_seq_nr, ctxB.imsi, g_restart_ctr,
1776 ctxB.teid, ctxB.teic, ctxB.nsapi, ctxB.eua, ctxB.apn,
1777 g_sgsn_ip_c, g_sgsn_ip_u, ctxB.msisdn, ctxB.pco_req));
1778 T_default.start;
1779 d := activate(pingpong());
1780 alt {
1781 [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, createPDPContextResponse, ctxB.teic)) -> value ud {
1782 f_handle_create_req(ctxB, ud);
1783 if (not ctxB_created) {
1784 ctxB_created := true;
1785 setverdict(pass);
1786 } else {
1787 setverdict(fail, "Repeated createPDPContextResponse(ctxB)");
1788 }
1789
1790 if (not ctxA_deleted) {
1791 repeat;
1792 }
1793 }
1794 [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, deletePDPContextRequest, ctxA.teic)) -> value ud {
1795 if (ispresent(ud.gtpc.gtpc_pdu.deletePDPContextRequest.tearDownIndicator)) {
1796 setverdict(pass);
1797 } else {
1798 setverdict(fail);
1799 }
1800
1801 if (not ctxA_deleted) {
1802 ctxA_deleted := true;
1803 setverdict(pass);
1804 } else {
1805 setverdict(fail, "Repeated deletePDPContextRequest(ctxA)");
1806 }
1807
1808 if (not ctxB_created) {
1809 repeat;
1810 }
1811 }
1812 [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, deletePDPContextRequest, ctxB.teic)) -> value ud {
1813 setverdict(fail, "GGSN dropping still valid pdp ctx");
1814 }
1815 }
1816 deactivate(d);
1817 T_default.stop;
1818
1819 f_pdp_ctx_del(ctxB, '1'B);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001820 f_shutdown_helper();
Pau Espin Pedrolfa1ca022019-08-23 18:58:53 +02001821 }
1822
1823
Pau Espin Pedrolbfad97f2022-11-04 12:03:17 +01001824 /* Send a duplicate echo req. osmo-ggsn maintains a queue for sent responses (T3-RESPONSE * N3-REQUESTS):
1825 * If same delete req is sent and duplicate is detected, saved duplicate response should be sent back. */
Pau Espin Pedrol9a5f42f2019-05-27 20:04:35 +02001826 testcase TC_act_deact_retrans_duplicate() runs on GT_CT {
1827 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001828 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrol9a5f42f2019-05-27 20:04:35 +02001829 f_pdp_ctx_act(ctx);
1830 f_pdp_ctx_del(ctx, '1'B);
1831 /* leave some time in between to make sure retransmit response queue keeps packets for a while */
Pau Espin Pedrolbfad97f2022-11-04 12:03:17 +01001832 f_sleep(int2float(mp_t3_response));
Pau Espin Pedrol9a5f42f2019-05-27 20:04:35 +02001833 /* g_c_seq_nr was increased during f_pdp_ctx_del(), we want a
1834 duplicate. If it was not a duplicate, osmo-ggsn would answer
1835 with a failure since that PDP ctx was already deleted. */
Pau Espin Pedrold6b51332022-05-19 17:47:11 +02001836 if (g_c_seq_nr == 0) {
1837 g_c_seq_nr := 65535;
1838 } else {
1839 g_c_seq_nr := g_c_seq_nr - 1;
1840 }
Pau Espin Pedrol10ec96e2022-02-09 17:03:15 +01001841 f_pdp_ctx_del(ctx, '1'B, expect_diameter := false);
Pau Espin Pedrol9a5f42f2019-05-27 20:04:35 +02001842
1843 /* Now send a new pdp ctx del (increased seqnum). It should fail with cause "non-existent": */
1844 var OCT1 cause_nonexistent := 'C0'O;
Pau Espin Pedrol10ec96e2022-02-09 17:03:15 +01001845 f_pdp_ctx_del(ctx, '1'B, cause_nonexistent, expect_diameter := false);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001846 f_shutdown_helper();
Pau Espin Pedrol9a5f42f2019-05-27 20:04:35 +02001847 }
1848
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +02001849 /* Activate PDP context + trigger Recovery procedure through EchoResp */
1850 testcase TC_pdp_act_restart_ctr_echo() runs on GT_CT {
1851 var Gtp1cUnitdata ud;
Pau Espin Pedrol05118022022-02-17 19:49:13 +01001852 g_use_echo_intval := 5;
1853 timer T_echo;
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +02001854 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02001855 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +02001856 f_pdp_ctx_act(ctx);
1857
1858 /* Wait to receive echo request and send initial Restart counter */
Pau Espin Pedrol05118022022-02-17 19:49:13 +01001859 T_echo.start(int2float(g_use_echo_intval) + 1.0);
1860 alt {
1861 [] GTPC.receive(tr_GTPC_PING(?)) -> value ud {
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +02001862 var uint16_t seq := oct2int(ud.gtpc.opt_part.sequenceNumber);
1863 GTPC.send(ts_GTPC_PONG(ud.peer, seq, g_restart_ctr));
Pau Espin Pedrol05118022022-02-17 19:49:13 +01001864 }
1865 [] T_echo.timeout {
1866 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1867 "Timeout waiting for ping");
1868 }
1869 }
1870 T_echo.stop;
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +02001871
1872 /* Wait to receive second echo request and send incremented Restart
1873 counter. This will fake a restarted SGSN, and pdp ctx allocated
1874 should be released by GGSN */
Vadim Yanitskiyd344b4a2022-02-09 18:28:18 +06001875 g_restart_ctr := int2oct((oct2int(g_restart_ctr) + 1) mod 256, 1);
Pau Espin Pedrol05118022022-02-17 19:49:13 +01001876 T_echo.start(int2float(g_use_echo_intval) + 1.0);
1877 alt {
1878 [] GTPC.receive(tr_GTPC_PING(?)) -> value ud {
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +02001879 var uint16_t seq := oct2int(ud.gtpc.opt_part.sequenceNumber);
1880 GTPC.send(ts_GTPC_PONG(ud.peer, seq, g_restart_ctr));
Pau Espin Pedrol05118022022-02-17 19:49:13 +01001881 }
1882 [] T_echo.timeout {
1883 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1884 "Timeout waiting for ping");
1885 }
1886 }
1887 T_echo.stop;
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +02001888 f_pdp_ctx_exp_del_req(ctx, omit, true);
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01001889 f_shutdown_helper();
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +02001890 }
1891
Pau Espin Pedrol68c2af52022-02-25 11:56:17 +01001892 /* Test creation, user plane and deletion of big amount (1000) of concurrent PDP context */
1893 testcase TC_lots_of_concurrent_pdp_ctx() runs on GT_CT {
1894 var Gtp1cUnitdata udc;
1895 var Gtp1uUnitdata udu;
1896 const integer num_ctx := 1000;
1897 var PdpContext ctx[num_ctx];
1898 timer T_next := 0.01;
1899 var integer next_req_ctx := 0;
1900 var integer rx_resp_ctx := 0;
1901 var integer rx_pong := 0;
1902 var OCT4 dns1_addr;
1903 var OCT4 saddr;
1904 var integer teic;
1905 var integer idx;
1906
1907 f_init();
1908
1909 for (var integer i := 0; i < num_ctx; i := i + 1) {
Pau Espin Pedrola2af5782022-05-18 16:34:29 +02001910 ctx[i] := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234" & int2str(f_rnd_int(4294967296)), c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrol68c2af52022-02-25 11:56:17 +01001911 ctx[i].teic := int2oct(i+1, 4); /* +1: skip TEIC=0 */
1912 ctx[i].teid := int2oct(i+1, 4); /* +1: skip TEID=0 */
1913 ctx[i].pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
1914 }
1915
1916 T_default.start(60.0);
1917
1918 T_next.start;
1919 alt {
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01001920 [Gx_PROC.checkstate("Connected")] as_DIA_Gx_CCR(INITIAL_REQUEST) { repeat; }
Pau Espin Pedrola2af5782022-05-18 16:34:29 +02001921 [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, INITIAL_REQUEST) { repeat; }
Pau Espin Pedrol68c2af52022-02-25 11:56:17 +01001922 [] pingpong();
1923 [] T_next.timeout {
1924 f_send_gtpc(ts_GTPC_CreatePDP(g_peer_c, g_c_seq_nr, ctx[next_req_ctx].imsi, g_restart_ctr,
1925 ctx[next_req_ctx].teid, ctx[next_req_ctx].teic, ctx[next_req_ctx].nsapi,
1926 ctx[next_req_ctx].eua, ctx[next_req_ctx].apn, g_sgsn_ip_c, g_sgsn_ip_u,
1927 ctx[next_req_ctx].msisdn, ctx[next_req_ctx].pco_req, ctx[next_req_ctx].ratType,
Pau Espin Pedrol535ca262022-05-16 14:07:17 +02001928 ctx[next_req_ctx].uli, ctx[next_req_ctx].charging_char, ctx[next_req_ctx].imeisv,
1929 ctx[next_req_ctx].ms_tz));
Pau Espin Pedrol68c2af52022-02-25 11:56:17 +01001930 next_req_ctx := next_req_ctx + 1;
1931 if (next_req_ctx < num_ctx) {
1932 T_next.start;
1933 }
1934 repeat;
1935 }
1936 [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, createPDPContextResponse, ?)) -> value udc {
1937 teic := oct2int(udc.gtpc.teid);
1938 if (not match(teic, (1 .. num_ctx))) {
1939 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1940 "Rx Unexpected TEIC");
1941 }
1942 idx := teic - 1;
1943 f_handle_create_req(ctx[idx], udc);
1944 rx_resp_ctx := rx_resp_ctx + 1;
1945
1946 dns1_addr := f_PCO_extract_proto(ctx[idx].pco_neg, '000d'O);
1947 saddr := ctx[idx].eua.endUserAddress.endUserAddressIPv4.ipv4_address;
1948 f_send_gtpu(ctx[idx], f_gen_icmpv4_echo(saddr, dns1_addr));
1949 repeat;
1950 }
1951 [] GTPU.receive(tr_GTPU_GPDU(g_peer_u, ?)) -> value udu {
1952 var octetstring gpdu := udu.gtpu.gtpu_IEs.g_PDU_IEs.data;
1953 var IPv4_packet ip4 := f_IPv4_dec(gpdu);
1954 if (ip4.header.ver != 4) {
1955 repeat;
1956 }
1957 var PDU_ICMP icmp4 := f_dec_PDU_ICMP(ip4.payload);
1958 if (not match(icmp4, (tr_ICMPv4_ERP, tr_ICMPv4_DU))) {
1959 repeat;
1960 }
1961 rx_pong := rx_pong + 1;
1962 if (rx_pong < num_ctx) {
1963 repeat;
1964 }
1965 setverdict(pass);
1966 }
1967 [] GTPC.receive { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx Unexpected GTPC"); }
1968 [] GTPU.receive { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx Unexpected GTPU"); }
1969 }
1970
1971 /* Let's close them now: */
1972 next_req_ctx := 0;
1973 rx_resp_ctx := 0;
1974 T_next.start;
1975 alt {
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01001976 [Gx_PROC.checkstate("Connected")] as_DIA_Gx_CCR(TERMINATION_REQUEST) { repeat; }
Pau Espin Pedrola2af5782022-05-18 16:34:29 +02001977 [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, TERMINATION_REQUEST) { repeat; }
Pau Espin Pedrol68c2af52022-02-25 11:56:17 +01001978 [] pingpong();
1979 [] T_next.timeout {
1980 f_send_gtpc(ts_GTPC_DeletePDP(g_peer_c, g_c_seq_nr, ctx[next_req_ctx].teic_remote, ctx[next_req_ctx].nsapi, '1'B));
1981 next_req_ctx := next_req_ctx + 1;
1982 if (next_req_ctx < num_ctx) {
1983 T_next.start;
1984 }
1985 repeat;
1986 }
1987 [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, deletePDPContextResponse, ?)) -> value udc {
1988 teic := oct2int(udc.gtpc.teid);
1989 if (not match(teic, (1 .. num_ctx))) {
1990 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1991 "Rx Unexpected TEIC");
1992 }
1993 rx_resp_ctx := rx_resp_ctx + 1;
1994 if (rx_resp_ctx < num_ctx) {
1995 repeat;
1996 }
1997 setverdict(pass);
1998 }
1999 [] GTPC.receive { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx Unexpected GTPC"); }
2000 [] GTPU.receive { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx Unexpected GTPU"); }
2001 }
2002 T_next.stop;
2003
2004 T_default.stop;
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01002005 f_shutdown_helper();
Pau Espin Pedrol68c2af52022-02-25 11:56:17 +01002006 }
2007
Pau Espin Pedrolbfea8352022-02-28 12:11:26 +01002008 /* Test callocation of PDP contexts until reaching addr pool exhaustion */
2009 type record of OCT4 TEIClist;
2010 testcase TC_addr_pool_exhaustion() runs on GT_CT {
2011 var Gtp1cUnitdata udc;
2012 var Gtp1uUnitdata udu;
2013 var PdpContext ctx;
2014 timer T_next := 0.005;
2015 var integer next_req_ctx := 0;
2016 var integer rx_resp_ctx := 0;
2017 var integer num_ctx;
2018 var boolean cont_req := true;
2019 var CreatePDPContextResponse cpr;
2020 var TEIClist teic_list := {};
2021 var integer teic;
2022
2023 f_init();
2024
2025 T_default.start(120.0);
2026
2027 T_next.start;
2028 alt {
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01002029 [Gx_PROC.checkstate("Connected")] as_DIA_Gx_CCR(INITIAL_REQUEST) { repeat; }
Pau Espin Pedrola2af5782022-05-18 16:34:29 +02002030 [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, INITIAL_REQUEST) { repeat; }
Pau Espin Pedrolbfea8352022-02-28 12:11:26 +01002031 [] pingpong();
2032 [] T_next.timeout {
2033 if (cont_req) {
2034 if (next_req_ctx - rx_resp_ctx < 100) { /* if we have too many in progress, wait a bit to continue */
Pau Espin Pedrola2af5782022-05-18 16:34:29 +02002035 ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234" & int2str(f_rnd_int(4294967296)), c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrolbfea8352022-02-28 12:11:26 +01002036 ctx.nsapi := '0001'B;
2037 ctx.teic := int2oct(next_req_ctx+1, 4); /* +1: skip TEIC=0 */
2038 ctx.teid := int2oct(next_req_ctx+1, 4); /* +1: skip TEID=0 */
2039 f_send_gtpc(ts_GTPC_CreatePDP(g_peer_c, g_c_seq_nr, ctx.imsi, g_restart_ctr,
2040 ctx.teid, ctx.teic, ctx.nsapi,
2041 ctx.eua, ctx.apn, g_sgsn_ip_c, g_sgsn_ip_u,
2042 ctx.msisdn, ctx.pco_req, ctx.ratType,
Pau Espin Pedrol535ca262022-05-16 14:07:17 +02002043 ctx.uli, ctx.charging_char, ctx.imeisv,
2044 ctx.ms_tz));
Pau Espin Pedrolbfea8352022-02-28 12:11:26 +01002045 next_req_ctx := next_req_ctx + 1;
2046 }
2047 T_next.start;
2048 }
2049 repeat;
2050 }
2051 [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, createPDPContextResponse, ?)) -> value udc {
2052 cpr := udc.gtpc.gtpc_pdu.createPDPContextResponse;
2053
2054 if (cpr.cause.causevalue == '80'O) {
2055 teic_list := teic_list & {cpr.teidControlPlane.teidControlPlane};
2056 } else {
2057 if (cont_req == true) {
2058 num_ctx := rx_resp_ctx;
2059 log("Successfully created ", num_ctx, " PDP contexts before exhausting the pool");
2060 setverdict(pass);
2061 }
2062 cont_req := false;
2063 }
2064 rx_resp_ctx := rx_resp_ctx + 1;
2065 if (not cont_req and next_req_ctx == rx_resp_ctx) {
2066 break;
2067 } else {
2068 repeat;
2069 }
2070 }
2071 [] GTPC.receive { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx Unexpected GTPC"); }
2072 [] GTPU.receive { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx Unexpected GTPU"); }
2073 }
2074
2075 /* Let's close them now: */
2076 next_req_ctx := 0;
2077 rx_resp_ctx := 0;
2078 T_next.start;
2079 alt {
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01002080 [Gx_PROC.checkstate("Connected")] as_DIA_Gx_CCR(TERMINATION_REQUEST) { repeat; }
Pau Espin Pedrola2af5782022-05-18 16:34:29 +02002081 [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, TERMINATION_REQUEST) { repeat; }
Pau Espin Pedrolbfea8352022-02-28 12:11:26 +01002082 [] pingpong();
Harald Welte5dc20d72024-03-26 14:33:33 +01002083 [lengthof(teic_list) > 0] T_next.timeout {
Pau Espin Pedrolbfea8352022-02-28 12:11:26 +01002084 f_send_gtpc(ts_GTPC_DeletePDP(g_peer_c, g_c_seq_nr, teic_list[next_req_ctx], '0001'B, '1'B));
2085 next_req_ctx := next_req_ctx + 1;
2086 if (next_req_ctx < num_ctx) {
2087 T_next.start;
2088 }
2089 repeat;
2090 }
2091 [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, deletePDPContextResponse, ?)) -> value udc {
2092 teic := oct2int(udc.gtpc.teid);
2093 if (not match(teic, (1 .. num_ctx))) {
2094 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
2095 "Rx Unexpected TEIC");
2096 }
2097 rx_resp_ctx := rx_resp_ctx + 1;
2098 if (rx_resp_ctx < num_ctx) {
2099 repeat;
2100 }
2101 setverdict(pass);
2102 }
2103 [] GTPC.receive { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx Unexpected GTPC"); }
2104 [] GTPU.receive { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx Unexpected GTPU"); }
2105 }
2106 T_next.stop;
2107
2108 T_default.stop;
Pau Espin Pedrolc441ce02022-03-07 14:35:45 +01002109 f_shutdown_helper();
Pau Espin Pedrolbfea8352022-02-28 12:11:26 +01002110 }
2111
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01002112 /* Test charging over Gy interface. */
2113 testcase TC_gy_charging_cc_time() runs on GT_CT {
2114 var default d;
2115
2116 g_gy_validity_time := 3; /* Grant access for 3 seconds, needs to be re-validated afterwards */
2117 f_init();
Pau Espin Pedrold25095f2022-05-18 16:29:05 +02002118 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01002119 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
2120 f_pdp_ctx_act(ctx);
2121
2122 var OCT4 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '000d'O);
2123
2124 /* Send some UL traffic: */
2125 var OCT4 saddr := ctx.eua.endUserAddress.endUserAddressIPv4.ipv4_address;
2126 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
2127 f_wait_icmp4_echo_reply(ctx);
2128
2129 T_default.start(10.0);
2130 d := activate(pingpong());
2131
2132 g_gy_validity_time := 2;
2133 /* First update reports octests/pkt on both UL/DL (see icmp ping-pong above) */
Pau Espin Pedrola2af5782022-05-18 16:34:29 +02002134 as_DIA_Gy_CCR(ctx, UPDATE_REQUEST);
Pau Espin Pedrol8fa22842022-05-20 14:47:55 +02002135 f_validate_gy_cc_report(g_rx_gy, VALIDITY_TIME, (3..4), 28, 28);
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01002136
2137 /* Second update: 0 ul/dl pkt/octet should be reported, since nothing was sent */
Pau Espin Pedrola2af5782022-05-18 16:34:29 +02002138 as_DIA_Gy_CCR(ctx, UPDATE_REQUEST);
Pau Espin Pedrol8fa22842022-05-20 14:47:55 +02002139 f_validate_gy_cc_report(g_rx_gy, VALIDITY_TIME, (2..3), 0, 0);
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01002140
2141 /* Third update: make sure report contains again octets/pkts for both UL/DL: */
2142 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
2143 f_wait_icmp4_echo_reply(ctx);
2144 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
2145 f_wait_icmp4_echo_reply(ctx);
Pau Espin Pedrola2af5782022-05-18 16:34:29 +02002146 as_DIA_Gy_CCR(ctx, UPDATE_REQUEST);
Pau Espin Pedrol8fa22842022-05-20 14:47:55 +02002147 f_validate_gy_cc_report(g_rx_gy, VALIDITY_TIME, (2..3), 56, 56);
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01002148
2149 /* Let the CCA reach the GGSN */
2150 f_sleep(0.5);
2151 deactivate(d);
2152 T_default.stop;
2153
2154 /* Send some data and validate it is reported in the TERMINATION_REQUEST
2155 * (triggered by PFCP Session Deletion Response): */
2156 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
2157 f_wait_icmp4_echo_reply(ctx);
2158
2159 f_pdp_ctx_del(ctx, '1'B);
Pau Espin Pedrol8fa22842022-05-20 14:47:55 +02002160 f_validate_gy_cc_report(g_rx_gy, FINAL, (0..2), 28, 28);
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01002161
2162
2163 f_shutdown_helper();
2164 }
2165
Pau Espin Pedrol52562c92022-05-23 15:45:46 +02002166 /* Test Volume-Quota-Thresold AVP triggers request before Validity-Time */
2167 testcase TC_gy_charging_volume_quota_threshold() runs on GT_CT {
2168 var default d;
2169 timer Tout;
2170 g_gy_volume_threshold := 1000; /* Will make a trigger when we send bigger payload below */
2171 g_gy_validity_time := 8; /* Grant access for 8 seconds, needs to be re-validated afterwards */
2172 f_init();
2173 var float tout_sec := int2float(g_gy_validity_time) / 2.0;
2174 var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), "1234", c_ApnInternet, valueof(t_EuaIPv4Dyn)));
2175 ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
2176 f_pdp_ctx_act(ctx);
2177
2178 var OCT4 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '000d'O);
2179
2180 T_default.start(40.0);
2181 d := activate(pingpong());
2182
2183 /* Send some UL traffic: */
2184 var octetstring payload := f_rnd_octstring(1200);
2185 var OCT4 saddr := ctx.eua.endUserAddress.endUserAddressIPv4.ipv4_address;
2186 f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr, payload));
2187 f_wait_icmp4_echo_reply(ctx);
2188
2189 /* ICMP Req generates one report: */
2190 Tout.start(tout_sec);
2191 alt {
2192 [] as_DIA_Gy_CCR(ctx, UPDATE_REQUEST);
2193 [] Tout.timeout {
2194 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
2195 "TImeout waiting for Gy UPDATE triggered by Volume-Quota-Threshold");
2196 }
2197 }
Pau Espin Pedrol5fa8f782022-10-03 13:57:54 +02002198 f_validate_gy_cc_report(g_rx_gy, THRESHOLD, (0..6), (1200..1400), 0);
Pau Espin Pedrol52562c92022-05-23 15:45:46 +02002199
2200 /* ICMP Resp (echo back) generates one report: */
2201 as_DIA_Gy_CCR(ctx, UPDATE_REQUEST);
Pau Espin Pedrol5fa8f782022-10-03 13:57:54 +02002202 f_validate_gy_cc_report(g_rx_gy, THRESHOLD, (0..1), 0, (1200..1400));
Pau Espin Pedrol52562c92022-05-23 15:45:46 +02002203
2204 /* Second update: 0 ul/dl pkt/octet should be reported, since nothing was sent */
2205 as_DIA_Gy_CCR(ctx, UPDATE_REQUEST);
2206 f_validate_gy_cc_report(g_rx_gy, VALIDITY_TIME, (8..9), 0, 0);
2207
2208 /* Let the CCA reach the GGSN */
2209 f_sleep(0.5);
2210 deactivate(d);
2211 T_default.stop;
2212
2213 f_pdp_ctx_del(ctx, '1'B);
2214 f_validate_gy_cc_report(g_rx_gy, FINAL, (0..2), 0, 0);
2215
2216
2217 f_shutdown_helper();
2218 }
2219
Harald Welte94ade362017-08-04 00:36:55 +02002220 control {
Oliver Smithb8561082024-03-22 11:21:10 +01002221 if (m_ggsn_conf != GGSN_CONF_V6_ONLY) {
2222 execute(TC_pdp4_act_deact());
2223 execute(TC_pdp4_act_deact_ipcp());
2224 execute(TC_pdp4_act_deact_ipcp_pap_broken());
2225 execute(TC_pdp4_act_deact_pcodns());
2226 execute(TC_pdp4_act_deact_gtpu_access());
2227 execute(TC_pdp4_act_deact_gtpu_access_wrong_saddr());
2228 execute(TC_pdp4_act_deact_gtpu_access_ipv6_apn4());
2229 execute(TC_pdp4_clients_interact_with_txseq());
2230 execute(TC_pdp4_clients_interact_without_txseq());
2231 execute(TC_pdp4_act_deact_with_single_dns());
2232 execute(TC_pdp4_act_deact_with_separate_dns());
2233 execute(TC_pdp4_act_update_teic());
2234 execute(TC_pdp4_act_update_teid());
2235 }
Harald Welteed7a1772017-08-09 20:26:20 +02002236
Oliver Smithb8561082024-03-22 11:21:10 +01002237 if (m_ggsn_conf != GGSN_CONF_V4_ONLY) {
2238 execute(TC_pdp6_act_deact());
2239 execute(TC_pdp6_act_deact_pcodns());
2240 execute(TC_pdp6_act_deact_icmp6());
2241 execute(TC_pdp6_act_deact_gtpu_access());
2242 execute(TC_pdp6_act_deact_gtpu_access_wrong_ll_saddr());
2243 execute(TC_pdp6_act_deact_gtpu_access_wrong_global_saddr());
2244 execute(TC_pdp6_act_deact_gtpu_access_ipv4_apn6());
2245 execute(TC_pdp6_clients_interact());
2246 }
Harald Weltedca80052017-08-13 20:01:38 +02002247
Oliver Smithb8561082024-03-22 11:21:10 +01002248 if (m_ggsn_conf != GGSN_CONF_V4_ONLY and m_ggsn_conf != GGSN_CONF_V6_ONLY) {
2249 execute(TC_pdp46_act_deact());
2250 execute(TC_pdp46_act_deact_ipcp());
2251 execute(TC_pdp46_act_deact_icmp6());
2252 execute(TC_pdp46_act_deact_pcodns4());
2253 execute(TC_pdp46_act_deact_pcodns6());
2254 execute(TC_pdp46_act_deact_gtpu_access());
2255 execute(TC_pdp46_act_deact_gtpu_access_wrong_saddr_ipv4());
2256 execute(TC_pdp46_act_deact_gtpu_access_wrong_ll_saddr_ipv6());
2257 execute(TC_pdp46_act_deact_gtpu_access_wrong_global_saddr_ipv6());
2258 execute(TC_pdp46_clients_interact());
2259 }
2260
2261 if (m_ggsn_conf == GGSN_CONF_ALL) {
2262 execute(TC_pdp46_act_deact_apn4());
2263 }
Oliver Smithee6a0882019-03-08 11:05:46 +01002264
Harald Weltedca80052017-08-13 20:01:38 +02002265 execute(TC_echo_req_resp());
Pau Espin Pedrol480e67f2022-02-09 16:37:47 +01002266 execute(TC_echo_req_resp_gtpu());
Pau Espin Pedrol6916ec42019-08-23 16:15:07 +02002267
Oliver Smithb8561082024-03-22 11:21:10 +01002268 if (m_ggsn_conf == GGSN_CONF_V4_ONLY or m_ggsn_conf == GGSN_CONF_ALL) {
2269 execute(TC_pdp_act2_recovery());
2270 execute(TC_act_deact_retrans_duplicate());
2271 }
Pau Espin Pedrol68c2af52022-02-25 11:56:17 +01002272
Oliver Smithb8561082024-03-22 11:21:10 +01002273 if (m_ggsn_conf != GGSN_CONF_V6_ONLY) {
2274 execute(TC_pdp_act_restart_ctr_echo());
2275
2276 execute(TC_lots_of_concurrent_pdp_ctx());
2277 /* Keep at the end, crashes older osmo-ggsn versions (OS#5469): */
2278 execute(TC_addr_pool_exhaustion());
2279 }
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01002280
2281 /* open5gs specific tests: */
2282 if (m_ggsn_impl == GGSN_IMPL_OPEN5GS) {
2283 execute(TC_gy_charging_cc_time());
Pau Espin Pedrol52562c92022-05-23 15:45:46 +02002284 execute(TC_gy_charging_volume_quota_threshold());
Pau Espin Pedrol77fdd0b2022-03-08 14:03:33 +01002285 }
Harald Welte94ade362017-08-04 00:36:55 +02002286 }
Harald Welte379d45a2017-08-03 09:55:15 +02002287}