[PATCH] osmo-ttcn3-hacks[master]: ggsn_tests: Add test case to validate packets forwarded vs d...

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Pau Espin Pedrol gerrit-no-reply at lists.osmocom.org
Tue Jan 30 16:21:45 UTC 2018


Hello Jenkins Builder,

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

    https://gerrit.osmocom.org/6158

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

ggsn_tests: Add test case to validate packets forwarded vs dropped

New dependency is required: titan.ProtocolModules.ICMP
It tests that ICMP echo packets can be sent successfully (reply is
received or otherwise dest unreachable if routing is not set up
correctly during the test). It also tests some cases in which osmo-ggsn
is required to drop the packets (eg. unknown src ip unrelated to pdp
ctx). It also checks that IPv6 packets are dropped in IPv4 pdp ctx and
viceversa It also checks that IPv6 packets are dropped in IPv4 pdp ctx
and vice versa.

Change-Id: Ib9c6043a6cd3b6622782ec7e7fcd2815101755ba
---
M ggsn_tests/GGSN_Tests.cfg
M ggsn_tests/GGSN_Tests.ttcn
M ggsn_tests/gen_links.sh
M ggsn_tests/regen_makefile.sh
4 files changed, 262 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/58/6158/4

diff --git a/ggsn_tests/GGSN_Tests.cfg b/ggsn_tests/GGSN_Tests.cfg
index d8994df..bf82057 100644
--- a/ggsn_tests/GGSN_Tests.cfg
+++ b/ggsn_tests/GGSN_Tests.cfg
@@ -26,9 +26,11 @@
 GGSN_Tests.TC_pdp4_act_deact
 GGSN_Tests.TC_pdp4_act_deact_ipcp
 GGSN_Tests.TC_pdp4_act_deact_pcodns
+GGSN_Tests.TC_pdp4_act_deact_gtpu_access
 
 GGSN_Tests.TC_pdp6_act_deact
 GGSN_Tests.TC_pdp6_act_deact_pcodns
 GGSN_Tests.TC_pdp6_act_deact_icmp6
+GGSN_Tests.TC_pdp6_act_deact_gtpu_access
 
 GGSN_Tests.TC_echo_req_resp
diff --git a/ggsn_tests/GGSN_Tests.ttcn b/ggsn_tests/GGSN_Tests.ttcn
index f7814db..aa20f25 100644
--- a/ggsn_tests/GGSN_Tests.ttcn
+++ b/ggsn_tests/GGSN_Tests.ttcn
@@ -10,6 +10,7 @@
 	import from GTPU_Types all;
 	import from IPCP_Types all;
 	import from IP_Types all;
+	import from ICMP_Types all;
 	import from ICMPv6_Types all;
 	import from Native_Functions all;
 
@@ -734,6 +735,63 @@
 	/* IPv6 neighbor solicitation fe80::2 -> ff02::1:ff00:2 from 02:88:b5:1f:25:59 */
 	const octetstring c_neigh_solicit:= '6000000000203afffe800000000000000000000000000002ff0200000000000000000001ff00000287009f9600000000fe80000000000000000000000000000201010288b51f2559'O;
 
+	/* template for an ICMPv6 echo request */
+	template PDU_ICMP ts_ICMPv4_ERQ := {
+		echo := {
+			type_field := 8,
+			code := 0,
+			checksum := '0000'O,
+			identifier := '0345'O,
+			sequence_number := '0001'O,
+			data := ''O
+		}
+	}
+
+	/* template for an ICMPv4 echo reply */
+	template PDU_ICMP tr_ICMPv4_ERP(octetstring data := ''O) := {
+		echo_reply := {
+			type_field := 0,
+			code := 0,
+			checksum := ?,
+			identifier := ?,
+			sequence_number := ?,
+			data := data
+		}
+	}
+
+	/* template for receiving/matching an ICMPv6 Destination Unreachable  */
+	template PDU_ICMP tr_ICMPv4_DU := {
+		destination_unreachable := {
+			type_field := 1,
+			code := ?,
+			checksum := ?,
+			unused := ?,
+			original_ip_msg  := ?
+		}
+	}
+
+	/* template to construct IPv4_packet from input arguments, ready for use in f_IPv4_enc() */
+	template IPv4_packet ts_IP4(OCT4 srcaddr, OCT4 dstaddr, LIN1 proto, LIN2_BO_LAST tlen, octetstring payload) := {
+		header := {
+			ver := 4,
+			hlen := 5,
+			tos := 0,
+			tlen := tlen,
+			id := 35902,
+			res := '0'B,
+			dfrag := '1'B,
+			mfrag := '0'B,
+			foffset := 0,
+			ttl := 64,
+			proto := proto,
+			cksum := 0,
+			srcaddr := srcaddr,
+			dstaddr := dstaddr
+		},
+		ext_headers := omit,
+		payload := payload
+	}
+
 	/* template to generate a 'Prefix Information' ICMPv6 option */
 	template OptionField ts_ICMP6_OptPrefix(OCT16 prefix, INT1 prefix_len) := {
 		prefixInformation := {
@@ -747,6 +805,18 @@
 			preferredLifetime := oct2int('FFFFFFFF'O),
 			reserved2 := '00000000'O,
 			prefix := prefix
+		}
+	}
+
+	/* template for an ICMPv6 echo request */
+	template PDU_ICMPv6 ts_ICMPv6_ERQ := {
+		echoRequest := {
+			typeField := 128,
+			code := 0,
+			checksum := '0000'O,
+			identifier := 0,
+			sequenceNr := 0,
+			data := ''O
 		}
 	}
 
@@ -829,6 +899,29 @@
 		}
 	}
 
+	/* template for receiving/matching an ICMPv6 Destination Unreachable  */
+	template PDU_ICMPv6 tr_ICMPv6_DU := {
+		destinationUnreachable := {
+			typeField := 1,
+			code := ?,
+			checksum := ?,
+			unused := ?,
+			originalIpMsg  := ?
+		}
+	}
+
+	/* template for receiving/matching an ICMPv6 echo reply */
+	template PDU_ICMPv6 tr_ICMPv6_ERP(octetstring data := ''O) := {
+		echoReply := {
+			typeField := 129,
+			code := 0,
+			checksum := ?,
+			identifier := ?,
+			sequenceNr := ?,
+			data := data
+		}
+	}
+
 	/* template to construct IPv6_packet from input arguments, ready for use in f_IPv6_enc() */
 	template IPv6_packet ts_IP6(OCT16 srcaddr, OCT16 dstaddr, LIN1 nexthead, octetstring payload, LIN1 hlim := 255) := {
 		header := {
@@ -847,6 +940,21 @@
 
 	function f_ipv6_link_local(in OCT16 link_id) return OCT16 {
 		 return 'FE80000000000000'O & substr(link_id, 8, 8);
+	}
+
+	function f_ipv6_global(in OCT16 link_id) return OCT16 {
+		 return substr(link_id, 0, 8) & '1234123412341234'O;
+	}
+
+	/* Create a new different IPv6 addr from input. Starts mangling at byte prefix. */
+	function f_ipv6_mangle(in OCT16 addr, in integer prefix := 0) return OCT16 {
+		var integer i;
+		var octetstring res := substr(addr, 0, prefix);
+		for (i := prefix; i < lengthof(addr); i := i + 1) {
+			var octetstring a := addr[i] xor4b '11'O;
+			res := res & a;
+		}
+		return res;
 	}
 
 	/* Compute solicited-node multicast address as per RFC4291 2.7.1 */
@@ -889,6 +997,25 @@
 		return f_gen_icmpv6_neigh_solicit(link_local, daddr, link_local);
 	}
 
+	/* Send an ICMPv4 echo msg through GTP given pdp ctx, and ip src and dst addr */
+	function f_gen_icmpv4_echo(OCT4 saddr, OCT4 daddr) return octetstring {
+		var octetstring tmp := f_enc_PDU_ICMP(valueof(ts_ICMPv4_ERQ));
+		var IPv4_packet ip4 := valueof(ts_IP4(saddr, daddr, 1, 50, tmp));
+		var octetstring data := f_IPv4_enc(ip4);
+		var OCT2 cksum := f_IPv4_checksum(data);
+		data[10] := cksum[0];
+		data[11] := cksum[1];
+		return data;
+	}
+
+	/* Send an ICMPv6 echo msg through GTP given pdp ctx, and ip src and dst addr */
+	function f_gen_icmpv6_echo(OCT16 saddr, OCT16 daddr) return octetstring {
+		var octetstring tmp := f_enc_PDU_ICMPv6(valueof(ts_ICMPv6_ERQ), saddr, daddr);
+		var IPv6_packet ip6 := valueof(ts_IP6(saddr, daddr, 58, tmp));
+		var octetstring data := f_IPv6_enc(ip6);
+		return data;
+	}
+
 	/* wait for GGSN to send us an ICMPv6 router advertisement */
 	function f_wait_rtr_adv(PdpContext ctx) runs on GT_CT {
 		var Gtp1uUnitdata ud;
@@ -911,6 +1038,62 @@
 			[] GTPU.receive(tr_GTPU_GPDU(?, ?)) { repeat; }
 			[] GTPU.receive { setverdict(fail); }
 			[] T_default.timeout { setverdict(fail); }
+		}
+		T_default.stop;
+	}
+
+	/* Wait to ICMPv4 echo reply (or unreachable) from GTP */
+	function f_wait_icmp4_echo_reply(PdpContext ctx) runs on GT_CT {
+		var Gtp1uUnitdata ud;
+		T_default.start;
+		alt {
+			[] GTPU.receive(tr_GTPU_GPDU(g_peer_u, ?)) -> value ud {
+				var octetstring gpdu := ud.gtpu.gtpu_IEs.g_PDU_IEs.data;
+				var IPv4_packet ip4 := f_IPv4_dec(gpdu);
+				if (ip4.header.ver != 4) {
+					repeat;
+				}
+				var PDU_ICMP icmp4 := f_dec_PDU_ICMP(ip4.payload);
+				if (not match(icmp4, tr_ICMPv4_ERP()) and not match(icmp4, tr_ICMPv4_DU)) {
+					repeat;
+				}
+				log("Received echo response");
+			}
+			[] GTPU.receive { setverdict(fail); }
+			[] T_default.timeout { setverdict(fail); }
+		}
+		T_default.stop;
+	}
+
+	/* Wait to ICMPv6 echo reply (or unreachable) from GTP */
+	function f_wait_icmp6_echo_reply(PdpContext ctx) runs on GT_CT {
+		var Gtp1uUnitdata ud;
+		T_default.start;
+		alt {
+			[] GTPU.receive(tr_GTPU_GPDU(g_peer_u, ?)) -> value ud {
+				var octetstring gpdu := ud.gtpu.gtpu_IEs.g_PDU_IEs.data;
+				var IPv6_packet ip6 := f_IPv6_dec(gpdu);
+				if (ip6.header.ver != 6 or ip6.header.nexthead != 58) {
+					repeat;
+				}
+				var PDU_ICMPv6 icmp6 := f_dec_PDU_ICMPv6(ip6.payload);
+				if (not match(icmp6, tr_ICMPv6_ERP()) and not match(icmp6, tr_ICMPv6_DU)) {
+					repeat;
+				}
+				log("Received echo response");
+			}
+			[] GTPU.receive { setverdict(fail); }
+			[] T_default.timeout { setverdict(fail); }
+		}
+		T_default.stop;
+	}
+
+	/* Assert we don't receive a ICMPv4/6 echo reply (or unreachable) from GTP */
+	function f_wait_gtpu_fail(PdpContext ctx) runs on GT_CT {
+		T_default.start;
+		alt {
+			[] GTPU.receive { setverdict(fail); }
+			[] T_default.timeout { }
 		}
 		T_default.stop;
 	}
@@ -960,6 +1143,49 @@
 		f_send_gtpu(ctx, f_icmpv6_rs_for_pdp(ctx));
 		f_wait_rtr_adv(ctx);
 		f_send_gtpu(ctx, f_gen_icmpv6_neigh_solicit_for_pdp(ctx));
+
+		f_pdp_ctx_del(ctx, '1'B);
+	}
+
+	/* Test PDP context activation for dynamic IPv6 EUA with IPv6 DNS in PCO and router solicitation/advertisement.
+	   Test we can send ICMPv6 ping over GTPU to DNS server. */
+	testcase TC_pdp6_act_deact_gtpu_access() runs on GT_CT {
+		f_init();
+		var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), '1234'O, c_ApnInet6, valueof(t_EuaIPv6Dyn)));
+		ctx.pco_req := valueof(ts_PCO_IPv6_DNS);
+		f_pdp_ctx_act(ctx);
+
+		f_send_gtpu(ctx, f_icmpv6_rs_for_pdp(ctx));
+		f_wait_rtr_adv(ctx);
+		f_send_gtpu(ctx, f_gen_icmpv6_neigh_solicit_for_pdp(ctx));
+
+		var OCT16 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '0003'O);
+
+		/* Check if we can use valid link-local src addr.  */
+		var OCT16 saddr_ll := f_ipv6_link_local(ctx.eua.endUserAddress.endUserAddressIPv6.ipv6_address);
+		f_send_gtpu(ctx, f_gen_icmpv6_echo(saddr_ll, dns1_addr));
+		f_wait_icmp6_echo_reply(ctx);
+
+		/* Check that attempting RA with another ll src addr won't work, packet dropped: */
+		var OCT16 saddr_ll_wrong := f_ipv6_mangle(saddr_ll, 8);
+		f_send_gtpu(ctx, f_gen_icmpv6_router_solicitation(saddr_ll_wrong));
+		f_wait_gtpu_fail(ctx);
+
+		/* Check if we can use valid global src addr, should work */
+		var OCT16 saddr_glob := f_ipv6_global(ctx.eua.endUserAddress.endUserAddressIPv6.ipv6_address);
+		f_send_gtpu(ctx, f_gen_icmpv6_echo(saddr_glob, dns1_addr));
+		f_wait_icmp6_echo_reply(ctx);
+
+		/* Assert that packets with wrong global src addr are dropped by GGSN */
+		var OCT16 saddr_wrong := f_ipv6_mangle(saddr_glob);
+		f_send_gtpu(ctx, f_gen_icmpv6_echo(saddr_wrong, dns1_addr));
+		f_wait_gtpu_fail(ctx);
+
+		/* Send an IPv4 ICMP ECHO REQUEST to APN6, should fail (packet dropped) */
+		var OCT4 saddr_v4 := f_inet_addr("192.168.10.2");
+		var OCT4 daddr_v4 := f_inet_addr("8.8.8.8");
+		f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr_v4, daddr_v4));
+		f_wait_gtpu_fail(ctx);
 
 		f_pdp_ctx_del(ctx, '1'B);
 	}
@@ -1017,6 +1243,33 @@
 		f_pdp_ctx_del(ctx, '1'B);
 	}
 
+	/* Test PDP context activation for dynamic IPv4 EUA.
+	   Test we can send ICMPv6 ping over GTPU to DNS server. */
+	testcase TC_pdp4_act_deact_gtpu_access() runs on GT_CT {
+		f_init();
+		var PdpContext ctx := valueof(t_DefinePDP(f_rnd_imsi('26242'H), '1234'O, c_ApnInternet, valueof(t_EuaIPv4Dyn)));
+		ctx.pco_req := valueof(ts_PCO_IPv4_DNS_CONT);
+		f_pdp_ctx_act(ctx);
+
+		var OCT4 dns1_addr := f_PCO_extract_proto(ctx.pco_neg, '000d'O);
+
+		/* Check if we can use valid global src addr, should work */
+		var OCT4 saddr := ctx.eua.endUserAddress.endUserAddressIPv4.ipv4_address;
+		f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
+		f_wait_icmp4_echo_reply(ctx);
+
+		/* Assert that packets with wrong global src addr are dropped by GGSN */
+		var OCT4 saddr_wrong := substr(saddr, 0, 3) & (saddr[3] xor4b '11'O);
+		f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr_wrong, dns1_addr));
+		f_wait_gtpu_fail(ctx);
+
+		/* Send an IPv6 RA to APN4, should fail (packet dropped) */
+		var OCT16 saddr_v6 := f_inet6_addr("fde4:8dba:82e1:2000:1:2:3:4");
+		f_send_gtpu(ctx, f_gen_icmpv6_router_solicitation(saddr_v6));
+		f_wait_gtpu_fail(ctx);
+		f_pdp_ctx_del(ctx, '1'B);
+	}
+
 	testcase TC_echo_req_resp() runs on GT_CT {
 		f_init();
 		f_send_gtpc(ts_GTPC_PING(g_peer_c, g_c_seq_nr));
@@ -1033,10 +1286,12 @@
 		execute(TC_pdp4_act_deact());
 		execute(TC_pdp4_act_deact_ipcp());
 		execute(TC_pdp4_act_deact_pcodns());
+		execute(TC_pdp4_act_deact_gtpu_access());
 
 		execute(TC_pdp6_act_deact());
 		execute(TC_pdp6_act_deact_pcodns());
 		execute(TC_pdp6_act_deact_icmp6());
+		execute(TC_pdp6_act_deact_gtpu_access());
 
 		execute(TC_echo_req_resp());
 	}
diff --git a/ggsn_tests/gen_links.sh b/ggsn_tests/gen_links.sh
index 8098f9b..58c681f 100755
--- a/ggsn_tests/gen_links.sh
+++ b/ggsn_tests/gen_links.sh
@@ -27,6 +27,10 @@
 FILES="IPL4asp_Functions.ttcn  IPL4asp_PT.cc  IPL4asp_PT.hh IPL4asp_PortType.ttcn  IPL4asp_Types.ttcn  IPL4asp_discovery.cc IPL4asp_protocol_L234.hh"
 gen_links $DIR $FILES
 
+DIR=$BASEDIR/titan.ProtocolModules.ICMP/src
+FILES="ICMP_EncDec.cc  ICMP_Types.ttcn"
+gen_links $DIR $FILES
+
 DIR=$BASEDIR/titan.ProtocolModules.ICMPv6/src
 FILES="ICMPv6_EncDec.cc  ICMPv6_Types.ttcn"
 gen_links $DIR $FILES
diff --git a/ggsn_tests/regen_makefile.sh b/ggsn_tests/regen_makefile.sh
index 3970187..2fc74f7 100755
--- a/ggsn_tests/regen_makefile.sh
+++ b/ggsn_tests/regen_makefile.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
 
-FILES="*.ttcn IPL4asp_PT.cc  IPL4asp_discovery.cc  TCCConversion.cc  TCCInterface.cc GTPC_EncDec.cc GTPU_EncDec.cc GTP_CodecPort_CtrlFunctDef.cc ICMPv6_EncDec.cc IP_EncDec.cc Native_FunctionDefs.cc UDP_EncDec.cc"
+FILES="*.ttcn IPL4asp_PT.cc  IPL4asp_discovery.cc  TCCConversion.cc  TCCInterface.cc GTPC_EncDec.cc GTPU_EncDec.cc GTP_CodecPort_CtrlFunctDef.cc ICMPv6_EncDec.cc IP_EncDec.cc Native_FunctionDefs.cc UDP_EncDec.cc ICMP_EncDec.cc"
 
 ../regen-makefile.sh GGSN_Tests.ttcn $FILES

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

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: Ib9c6043a6cd3b6622782ec7e7fcd2815101755ba
Gerrit-PatchSet: 4
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Owner: Pau Espin Pedrol <pespin at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Pau Espin Pedrol <pespin at sysmocom.de>



More information about the gerrit-log mailing list