module UPF_Tests {

/* Integration Tests for OsmoUPF
 * (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * This test suite acts as a PFCP Control Plane Function to test OsmoUPF.
 */

import from Misc_Helpers all;
import from General_Types all;
import from Osmocom_Types all;
import from IPL4asp_Types all;
import from Native_Functions all;
import from TCCConversion_Functions all;

import from Osmocom_CTRL_Functions all;
import from Osmocom_CTRL_Types all;
import from Osmocom_CTRL_Adapter all;

import from StatsD_Types all;
import from StatsD_CodecPort all;
import from StatsD_CodecPort_CtrlFunct all;
import from StatsD_Checker all;

import from Osmocom_VTY_Functions all;
import from TELNETasp_PortType all;

import from CPF_ConnectionHandler all;

import from PFCP_Types all;
import from PFCP_Emulation all;
import from PFCP_Templates all;

modulepar {
	/* IP address at which the UPF can be reached */
	charstring mp_pfcp_ip_upf := "127.0.0.1";
	charstring mp_pfcp_ip_local := "127.0.0.2";

	charstring mp_netinst_access_ip_1 := "127.0.1.1";
	charstring mp_netinst_access_ip_2 := "127.0.1.2";
	charstring mp_netinst_core_ip_1 := "127.0.2.1";
	charstring mp_netinst_core_ip_2 := "127.0.2.2";

	/* When testing with gtp mockup, actions will not show. */
	boolean mp_verify_gtp_actions := false;
}

type component test_CT extends CTRL_Adapter_CT {
	port PFCPEM_PT PFCP;

	port TELNETasp_PT UPFVTY;

	/* global test case guard timer (actual timeout value is set in f_init()) */
	timer T_guard := 15.0;
}

/* global altstep for global guard timer; */
altstep as_Tguard() runs on test_CT {
	[] T_guard.timeout {
			setverdict(fail, "Timeout of T_guard");
			mtc.stop;
		}
}

friend function f_logp(TELNETasp_PT pt, charstring log_msg)
{
	// log on TTCN3 log output
	log(log_msg);
	// log in stderr log
	f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
}

private function f_get_name_val(out charstring val, charstring str, charstring name, charstring sep := ":", charstring delim := " ") return boolean {
	var charstring labl := name & sep;
	var integer namepos := f_strstr(str, labl);
	if (namepos < 0) {
		return false;
	}
	var integer valpos := namepos + lengthof(labl);
	var integer valend := f_strstr(str, delim, valpos);
	if (valend < 0) {
		valend := lengthof(str);
	}
	val := substr(str, valpos, valend - valpos);
	return true;
}

private function f_get_name_val_oct8(out OCT8 val, charstring str, charstring name) return boolean {
	var charstring token;
	if (not f_get_name_val(token, str, name, ":0x")) {
		return false;
	}
	if (lengthof(token) > 16) {
		log("token too long: ", name, " in ", str);
		return false;
	}
	var charstring padded := substr("0000000000000000", 0, 16 - lengthof(token)) & token;
	val := str2oct(padded);
	return true;
}

private function f_get_name_val_oct4(out OCT4 val, charstring str, charstring name) return boolean {
	var charstring token;
	if (not f_get_name_val(token, str, name, ":0x")) {
		return false;
	}
	if (lengthof(token) > 8) {
		log("token too long: ", name, " in ", str);
		return false;
	}
	var charstring padded := substr("00000000", 0, 8 - lengthof(token)) & token;
	val := str2oct(padded);
	return true;
}

private function f_get_name_val_int(out integer val, charstring str, charstring name) return boolean {
	var charstring token;
	if (not f_get_name_val(token, str, name)) {
		return false;
	}
	val := str2int(token);
	return true;
}

private function f_get_name_val_2int(out integer val1, out integer val2, charstring str, charstring name, charstring delim := ",") return boolean {
	var charstring token;
	if (not f_get_name_val(token, str, name)) {
		return false;
	}
	var ro_charstring nrl := f_str_split(token, delim);
	if (lengthof(nrl) != 2) {
		return false;
	}
	val1 := str2int(nrl[0]);
	val2 := str2int(nrl[1]);
	return true;
}

/* A PFCP session as seen by the system under test, osmo-upf. up_seid is what osmo-upf sees as its local SEID
 * ("SEID-l"). cp_seid is this tester's side's SEID, which osmo-upf sees as the remote SEID. */
type record PFCP_session {
	OCT8 up_seid,
	OCT8 cp_seid,
	GTP_Action gtp
}

/* _r and _l means 'remote' and 'local', from the perspective of the osmo-upf process. */
type record GTP_Action_tunend {
	/* the PDR Id detecting packets from this side */
	integer pdr_id,
	/* IP packets arriving from this side are arriving on ip_l */
	charstring ip_l,

	/* the FAR Id forwarding packets to this side */
	integer far_id
}

/* _r and _l means 'remote' and 'local', from the perspective of the osmo-upf process. */
type record GTP_Action_tun {
	/* the PDR Id detecting packets from this side */
	integer pdr_id,
	/* GTP arriving from this side is arriving on gtp_ip_l with teid_l */
	charstring gtp_ip_l,
	OCT4 teid_l,

	/* the FAR Id forwarding packets to this side */
	integer far_id,
	/* GTP going out to this side should be sent to gtp_ip_r with teid_r */
	charstring gtp_ip_r,
	OCT4 teid_r
}

type union GTP_Action_core {
	/* For kind = "tunend", the local IP that the UE has on 'the internet' */
	GTP_Action_tunend tunend,
	/* For kind = "tunmap", the second GTP tunnel */
	GTP_Action_tun tunmap
}

/* State of what GTP functionality osmo-upf should put in place, after a PFCP request was ACKed by it.
 * _r and _l means 'remote' and 'local', from the perspective of the osmo-upf process.
 *
 * tunend:
 *  Access                                            UPF                      Core
 *  GTP-r:127.0.0.2,0x1  <-FAR-1--                     | 192.168.0.1 <-PDR-1--
 *                       --PDR-2-> GTP-l:127.0.0.1,0x2 |             --FAR-2-> (IP destination is in each GTP payload)
 *
 * tunmap:
 *  Access                                            UPF                        Core
 *  GTP-r:127.0.0.2,0x1  <-FAR-1--                     | 127.0.0.1,0x1 <-PDR-1--
 *                       --PDR-2-> GTP-l:127.0.0.1,0x2 |               --FAR-2-> GTP-r:127.0.0.3,0x2
 */
type record GTP_Action {
	/* kind = ("tunend"|"tunmap") */
	charstring kind,
	/* The access side GTP tunnel. (The 'Access' side is always GTP.) */
	GTP_Action_tun access,
	/* The core side GTP tunnel (tunmap) or local IP (tunend) */
	GTP_Action_core core,
	/* Reference to the PFCP Session that created this GTP action: PFCP session's F-SEID as seen from osmo-upf */
	charstring pfcp_peer,
	OCT8 seid_l
};

type record of GTP_Action GTP_Action_List;

private function f_parse_gtp_action(out GTP_Action ret, charstring str) return boolean {
	/* Parse a string like
	 * "GTP:tunend GTP-access-r:127.0.0.2 TEID-access-r:0x94f0001 TEID-access-l:0x1 IP-core-l:192.168.44.241 PFCP-peer:127.0.0.2 SEID-l:0x1 PDR:1,2"
	 */
	var GTP_Action a;
	if (not f_get_name_val(a.kind, str, "GTP")) {
		return false;
	}
	if (not f_get_name_val(a.access.gtp_ip_r, str, "GTP-access-r")) {
		return false;
	}
	if (not f_get_name_val_oct4(a.access.teid_r, str, "TEID-access-r")) {
		return false;
	}
	if (not f_get_name_val(a.access.gtp_ip_l, str, "GTP-access-l")) {
		return false;
	}
	if (not f_get_name_val_oct4(a.access.teid_l, str, "TEID-access-l")) {
		return false;
	}
	if (not f_get_name_val_int(a.access.pdr_id, str, "PDR-access")) {
		return false;
	}
	if (not f_get_name_val(a.pfcp_peer, str, "PFCP-peer")) {
		return false;
	}
	if (not f_get_name_val_oct8(a.seid_l, str, "SEID-l")) {
		return false;
	}
	if (a.kind == "tunend") {
		if (not f_get_name_val_int(a.core.tunend.pdr_id, str, "PDR-core")) {
			return false;
		}
		if (not f_get_name_val(a.core.tunend.ip_l, str, "IP-core-l")) {
			return false;
		}
		/* in these tests, the PDR Id and its FAR Id are always the same: PDR for incoming on Access matches its
		 * FAR that forwards to Core. */
		a.core.tunend.far_id := a.access.pdr_id;
		a.access.far_id := a.core.tunend.pdr_id;
	} else if (a.kind == "tunmap") {
		if (not f_get_name_val(a.core.tunmap.gtp_ip_r, str, "GTP-core-r")) {
			return false;
		}
		if (not f_get_name_val_oct4(a.core.tunmap.teid_r, str, "TEID-core-r")) {
			return false;
		}
		if (not f_get_name_val(a.core.tunmap.gtp_ip_l, str, "GTP-core-l")) {
			return false;
		}
		if (not f_get_name_val_oct4(a.core.tunmap.teid_l, str, "TEID-core-l")) {
			return false;
		}
		if (not f_get_name_val_int(a.core.tunmap.pdr_id, str, "PDR-core")) {
			return false;
		}
		/* in these tests, the PDR Id and its FAR Id are always the same: PDR for incoming on Access matches its
		 * FAR that forwards to Core. */
		a.core.tunmap.far_id := a.access.pdr_id;
		a.access.far_id := a.core.tunmap.pdr_id;
	}

	ret := a;
	return true;
}

private function f_vty_get_gtp_actions(TELNETasp_PT vty_pt) return GTP_Action_List {
	var charstring gtp_str := f_vty_transceive_ret(vty_pt, "show gtp");
	var ro_charstring lines := f_str_split(gtp_str, "\n");
	var GTP_Action_List gtps := {};
	for (var integer i := 0; i < lengthof(lines); i := i + 1) {
		var charstring line := lines[i];
		var GTP_Action a;
		if (not f_parse_gtp_action(a, line)) {
			continue;
		}
		gtps := gtps & { a };
	}
	log("GTP-actions: ", gtps);
	return gtps;
}

private function f_find_gtp_action(GTP_Action_List actions, template GTP_Action find) return boolean {
	for (var integer i := 0; i < lengthof(actions); i := i + 1) {
		if (match(actions[i], find)) {
			return true;
		}
	}
	return false;
}

private function f_expect_gtp_action(GTP_Action_List actions, template GTP_Action expect) {
	if (f_find_gtp_action(actions, expect)) {
		log("VTY confirms: GTP action active: ", expect);
		setverdict(pass);
		return;
	}
	log("Expected to find ", expect, " in ", actions);
	setverdict(fail, "on VTY, a GTP action failed to show as active");
	mtc.stop;
}

private function f_expect_no_gtp_action(GTP_Action_List actions, template GTP_Action expect) {
	if (f_find_gtp_action(actions, expect)) {
		log("Expected to *not* find ", expect, " in ", actions);
		setverdict(fail, "a GTP action failed to show as inactive");
		mtc.stop;
	}
	log("VTY confirms: GTP action inactive: ", expect);
	setverdict(pass);
	return;
}

private function f_vty_expect_gtp_action(TELNETasp_PT vty_pt, template GTP_Action expect) {
	if (not mp_verify_gtp_actions) {
		/* In GTP mockup mode, GTP actions don't show on VTY. Cannot verify. */
		setverdict(pass);
		return;
	}
	var GTP_Action_List actions := f_vty_get_gtp_actions(vty_pt);
	f_expect_gtp_action(actions, expect);
}

private function f_vty_expect_no_gtp_actions(TELNETasp_PT vty_pt) {
	var GTP_Action_List actions := f_vty_get_gtp_actions(vty_pt);
	if (lengthof(actions) > 0) {
		setverdict(fail, "VTY says that there are still active GTP actions");
		mtc.stop;
	}
	setverdict(pass);
}

type record PFCP_Session_Status {
	charstring peer,
	OCT8 seid_r,
	OCT8 seid_l,
	charstring state,
	integer pdr_active_count,
	integer pdr_count,
	integer far_active_count,
	integer far_count,
	integer gtp_active_count
};

template PFCP_Session_Status PFCP_session_active := {
	peer := ?,
	seid_r := ?,
	seid_l := ?,
	state := "ESTABLISHED",
	pdr_active_count := (1..99999),
	pdr_count := (1..99999),
	far_active_count := (1..99999),
	far_count := (1..99999),
	gtp_active_count := (1..99999)
};

template PFCP_Session_Status PFCP_session_inactive := {
	peer := ?,
	seid_r := ?,
	seid_l := ?,
	state := "ESTABLISHED",
	pdr_active_count := 0,
	pdr_count := (1..99999),
	far_active_count := 0,
	far_count := (1..99999),
	gtp_active_count := 0
};

type record of PFCP_Session_Status PFCP_Session_Status_List;

private function f_parse_session_status(out PFCP_Session_Status ret, charstring str) return boolean {
	var PFCP_Session_Status st;
	if (not f_get_name_val(st.peer, str, "peer")) {
		return false;
	}
	if (not f_get_name_val_oct8(st.seid_l, str, "SEID-l")) {
		return false;
	}
	f_get_name_val_oct8(st.seid_r, str, "SEID-r");
	f_get_name_val(st.state, str, "state");

	/* parse 'PDR-active:1/2' */
	if (not f_get_name_val_2int(st.pdr_active_count, st.pdr_count, str, "PDR-active", "/")) {
		return false;
	}
	/* parse 'FAR-active:1/2' */
	if (not f_get_name_val_2int(st.far_active_count, st.far_count, str, "FAR-active", "/")) {
		return false;
	}

	f_get_name_val_int(st.gtp_active_count, str, "GTP-active");
	ret := st;
	return true;
}

private function f_vty_get_sessions(TELNETasp_PT vty_pt) return PFCP_Session_Status_List {
	var charstring sessions_str := f_vty_transceive_ret(vty_pt, "show session");
	var ro_charstring lines := f_str_split(sessions_str, "\n");
	var PFCP_Session_Status_List sessions := {};
	for (var integer i := 0; i < lengthof(lines); i := i + 1) {
		var charstring line := lines[i];
		var PFCP_Session_Status st;
		if (not f_parse_session_status(st, line)) {
			continue;
		}
		sessions := sessions & { st };
	}
	log("Sessions: ", sessions);
	return sessions;
}

private function f_vty_get_session_status(TELNETasp_PT vty_pt, PFCP_session s, out PFCP_Session_Status ret) return boolean {
	var PFCP_Session_Status_List sessions := f_vty_get_sessions(vty_pt);
	return f_get_session_status(sessions, s, ret);
}

private function f_get_session_status(PFCP_Session_Status_List sessions, PFCP_session s, out PFCP_Session_Status ret)
return boolean {
	var PFCP_Session_Status_List matches := {};
	for (var integer i := 0; i < lengthof(sessions); i := i + 1) {
		var PFCP_Session_Status st := sessions[i];
		if (st.seid_l != s.up_seid) {
			continue;
		}
		if (st.seid_r != s.cp_seid) {
			continue;
		}
		matches := matches & { st };
	}
	if (lengthof(matches) < 1) {
		log("no session with SEID-l = ", s.up_seid);
		return false;
	}
	if (lengthof(matches) > 1) {
		log("multiple sessions have ", s, ": ", matches);
		return false;
	}
	ret := matches[0];
	return true;
}

private function f_vty_expect_session_status(TELNETasp_PT vty_pt, PFCP_session s, template PFCP_Session_Status expect_st) {
	var PFCP_Session_Status st;
	if (not f_vty_get_session_status(vty_pt, s, st)) {
		log("Session ", s, " not found in VTY session list");
		setverdict(fail, "Session not found in VTY list");
		mtc.stop;
	}
	log("Session ", s, " status: ", st);
	if (not match(st, expect_st)) {
		log("ERROR: Session ", st, " does not match ", expect_st);
		setverdict(fail, "VTY shows unexpected state of PFCP session");
		mtc.stop;
	}

	setverdict(pass);
}

private function f_vty_expect_session_active(TELNETasp_PT vty_pt, PFCP_session s)
{
	f_vty_expect_session_status(vty_pt, s, PFCP_session_active);
	f_vty_expect_gtp_action(vty_pt, s.gtp);
	setverdict(pass);
}

private function f_vty_expect_no_active_sessions(TELNETasp_PT vty_pt) {
	var PFCP_Session_Status_List stl := f_vty_get_sessions(vty_pt);
	var integer active := 0;
	for (var integer i := 0; i < lengthof(stl); i := i + 1) {
		if (match(stl[i], PFCP_session_active)) {
			log("Active session: ", stl[i]);
			active := active + 1;
		}
	}
	if (active > 0) {
		setverdict(fail, "There are still active sessions");
		mtc.stop;
	}
	setverdict(pass);
}

private function f_vty_netinst_cfg(TELNETasp_PT vty_pt, ro_charstring netinst_cmds)
{
	f_vty_enter_config(vty_pt);
	f_vty_transceive(vty_pt, "netinst");
	for (var integer i := 0; i < lengthof(netinst_cmds); i := i + 1) {
		f_vty_transceive(vty_pt, netinst_cmds[i]);
	}
	f_vty_transceive_ret(vty_pt, "end");
}

function f_init_vty(charstring id := "foo") runs on test_CT {
	if (UPFVTY.checkstate("Mapped")) {
		/* skip initialization if already executed once */
		return;
	}
	map(self:UPFVTY, system:UPFVTY);
	f_vty_set_prompts(UPFVTY);
	f_vty_transceive(UPFVTY, "enable");
}

/* global initialization function */
function f_init(float guard_timeout := 30.0) runs on test_CT {
	var integer bssap_idx;

	T_guard.start(guard_timeout);
	activate(as_Tguard());

	f_init_vty("VirtCPF");

	/* Clear out and set up default network instance config */
	f_vty_netinst_cfg(UPFVTY,
			  { "clear",
			    "add access " & mp_netinst_access_ip_1,
			    "add access2 " & mp_netinst_access_ip_2,
			    "add core " & mp_netinst_core_ip_1,
			    "add core2 " & mp_netinst_core_ip_2
			    });
}

friend function f_shutdown_helper() runs on test_CT {
	all component.stop;
	setverdict(pass);
	mtc.stop;
}

private function f_gen_test_hdlr_pars() runs on test_CT return TestHdlrParams {
	var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
	pars.remote_upf_addr := mp_pfcp_ip_upf;
	pars.local_addr := mp_pfcp_ip_local;
	pars.local_node_id := valueof(ts_PFCP_Node_ID_ipv4(f_inet_addr(mp_pfcp_ip_local)));
	return pars;
}

type function void_fn(charstring id) runs on CPF_ConnHdlr;

function f_start_handler_create(TestHdlrParams pars)
runs on test_CT return CPF_ConnHdlr {
	var charstring id := testcasename();
	var CPF_ConnHdlr vc_conn;
	vc_conn := CPF_ConnHdlr.create(id);
	return vc_conn;
}

function f_start_handler_run(CPF_ConnHdlr vc_conn, void_fn fn, TestHdlrParams pars)
runs on test_CT return CPF_ConnHdlr {
	var charstring id := testcasename();
	/* Emit a marker to appear in the SUT's own logging output */
	f_logp(UPFVTY, id & "() start");
	vc_conn.start(f_handler_init(fn, id, pars));
	return vc_conn;
}

function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars_tmpl := omit)
runs on test_CT return CPF_ConnHdlr {
	var TestHdlrParams pars;
	if (isvalue(pars_tmpl)) {
		pars := valueof(pars_tmpl);
	} else {
		pars := valueof(f_gen_test_hdlr_pars());
	}
	return f_start_handler_run(f_start_handler_create(pars), fn, pars);
}

/* first function inside ConnHdlr component; sets g_pars + starts function */
private function f_handler_init(void_fn fn, charstring id, TestHdlrParams pars)
runs on CPF_ConnHdlr {
	f_CPF_ConnHdlr_init(id, pars);
	fn.apply(id);
}

/* Run a PFCP Association procedure */
private function f_assoc_setup() runs on CPF_ConnHdlr {
	PFCP.send(ts_PFCP_Assoc_Setup_Req(g_pars.local_node_id, g_recovery_timestamp));
	PFCP.receive(tr_PFCP_Assoc_Setup_Resp(cause := tr_PFCP_Cause(REQUEST_ACCEPTED)));
}

/* Release a PFCP Association */
private function f_assoc_release() runs on CPF_ConnHdlr {
	PFCP.send(ts_PFCP_Assoc_Release_Req(g_pars.local_node_id));
	PFCP.receive(tr_PFCP_Assoc_Release_Resp(cause := tr_PFCP_Cause(REQUEST_ACCEPTED)));
}

/* Collection of what a test intends to send to osmo-upf */
type record PFCP_Ruleset {
	Create_PDR_list pdr,
	Create_FAR_list far
};

/* Add to r a rule set that does GTP decapsulation (half of encapsulation/decapsulation):
 * Receive GTP on src_iface = ACCESS by a local F-TEID to be chosen by osmo-upf.
 * Dispatch GTP payload as plain IP on dest_iface = CORE. */
private function f_ruleset_add_GTP_decaps(inout PFCP_Ruleset r,
					  integer pdr_id,
					  charstring src_netinst,
					  integer far_id) {
	r.pdr := r.pdr & {
		valueof(
		ts_PFCP_Create_PDR(
			pdr_id,
			ts_PFCP_PDI(
				ACCESS,
				local_F_TEID := ts_PFCP_F_TEID_choose_v4(),
				network_instance := ts_PFCP_Network_Instance(src_netinst)),
			ts_PFCP_Outer_Header_Removal(GTP_U_UDP_IPV4),
			far_id
			)
		)
		};
	r.far := r.far & {
		valueof(
		ts_PFCP_Create_FAR(
			far_id,
			ts_PFCP_Apply_Action_FORW(),
			valueof(ts_PFCP_Forwarding_Parameters(CORE))
			)
		)
		};
}

/* Add to r a rule set that does GTP encapsulation (half of encapsulation/decapsulation) */
private function f_ruleset_add_GTP_encaps(inout PFCP_Ruleset r,
					  integer pdr_id,
					  charstring ue_addr_v4 := "192.168.23.42",
					  integer far_id,
					  OCT4 remote_teid,
					  OCT4 gtp_dest_addr_v4) {
	r.pdr := r.pdr & {
		valueof(
		ts_PFCP_Create_PDR(
			pdr_id,
			ts_PFCP_PDI(
				CORE,
				ue_addr_v4 := ts_PFCP_UE_IP_Address_v4(f_inet_addr(ue_addr_v4), is_destination := true)
				),
			far_id := far_id
			)
		)
		};
	r.far := r.far & {
		valueof(
		ts_PFCP_Create_FAR(
			far_id,
			ts_PFCP_Apply_Action_FORW(),
			valueof(ts_PFCP_Forwarding_Parameters(
				ACCESS,
				ts_PFCP_Outer_Header_Creation_GTP_ipv4(
					remote_teid,
					gtp_dest_addr_v4)
				))
			)
		)
		};
}

/* Add to r a rule set that forwards GTP from one tunnel to another, i.e. one direction of a tunmap */
private function f_ruleset_add_GTP_forw(inout PFCP_Ruleset r,
					integer pdr_id,
					e_PFCP_Src_Iface src_iface,
					charstring src_netinst,
					integer far_id,
					e_PFCP_Dest_Iface dest_iface,
					F_TEID dest_remote_f_teid) {
	r.pdr := r.pdr & {
		valueof(
		ts_PFCP_Create_PDR(
			pdr_id,
			ts_PFCP_PDI(
				src_iface,
				local_F_TEID := ts_PFCP_F_TEID_choose_v4(),
				network_instance := ts_PFCP_Network_Instance(src_netinst)),
			ts_PFCP_Outer_Header_Removal(GTP_U_UDP_IPV4),
			far_id
			)
		)
		};
	r.far := r.far & {
		valueof(
		ts_PFCP_Create_FAR(
			far_id,
			ts_PFCP_Apply_Action_FORW(),
			valueof(ts_PFCP_Forwarding_Parameters(dest_iface,
					ts_PFCP_Outer_Header_Creation_GTP_ipv4(dest_remote_f_teid.teid,
									       dest_remote_f_teid.ipv4_address)))
			)
		)
		};
}

/* Add to r a DROP rule from src_iface to dest_iface */
private function f_ruleset_add_GTP_drop(inout PFCP_Ruleset r,
					integer pdr_id,
					e_PFCP_Src_Iface src_iface,
					charstring src_netinst,
					integer far_id,
					e_PFCP_Dest_Iface dest_iface) {
	r.pdr := r.pdr & {
		valueof(
		ts_PFCP_Create_PDR(
			pdr_id,
			ts_PFCP_PDI(
				src_iface,
				local_F_TEID := ts_PFCP_F_TEID_choose_v4(),
				network_instance := ts_PFCP_Network_Instance(src_netinst)),
			ts_PFCP_Outer_Header_Removal(GTP_U_UDP_IPV4),
			far_id
			)
		)
		};
	r.far := r.far & {
		valueof(
		ts_PFCP_Create_FAR(
			far_id,
			ts_PFCP_Apply_Action_DROP,
			fp := omit
			)
		)
		};
}

private function f_tunmap_upd_far_to_core(GTP_Action gtp) return Update_FAR
{
	return valueof(
		ts_PFCP_Update_FAR(
			gtp.core.tunmap.far_id,
			ts_PFCP_Apply_Action_FORW(),
			valueof(ts_PFCP_Update_Forwarding_Parameters(
					CORE,
					ts_PFCP_Outer_Header_Creation_GTP_ipv4(gtp.core.tunmap.teid_r,
									       f_inet_addr(gtp.core.tunmap.gtp_ip_r))
					)
			       )
			)
		);
}

/* Return two PDR+FAR rulesets that involve a src=CP-Function. Such rulesets are emitted by certain third party CPF, and
 * osmo-upf should ACK the creation but ignore the rules (no-op). This function models rulesets seen in the field, so we
 * can confirm that osmo-upf ACKs and ignores. */
private function f_ruleset_noop() return PFCP_Ruleset
{
	var PFCP_Ruleset r := { {}, {} };
	var integer pdr_id := lengthof(r.pdr) + 1;
	var integer far_id := lengthof(r.far) + 1;

	r.pdr := r.pdr & {
		valueof(
		ts_PFCP_Create_PDR(
			pdr_id,
			ts_PFCP_PDI(
				CP_FUNCTION,
				local_F_TEID := ts_PFCP_F_TEID_choose_v4('17'O)),
			ts_PFCP_Outer_Header_Removal(GTP_U_UDP_IPV4),
			far_id
			)
		)
		};
	r.far := r.far & {
		valueof(
		ts_PFCP_Create_FAR(
			far_id,
			ts_PFCP_Apply_Action_FORW(),
			valueof(ts_PFCP_Forwarding_Parameters(ACCESS))
			)
		)
		};

	/* And another one (sic) */
	pdr_id := lengthof(r.pdr) + 1;
	far_id := lengthof(r.far) + 1;

	r.pdr := r.pdr & {
		valueof(
		ts_PFCP_Create_PDR(
			pdr_id,
			ts_PFCP_PDI(
				CP_FUNCTION,
				local_F_TEID := ts_PFCP_F_TEID_choose_v4('2a'O)),
			far_id := far_id
			)
		)
		};
	r.far := r.far & {
		valueof(
		ts_PFCP_Create_FAR(
			far_id,
			ts_PFCP_Apply_Action_FORW(),
			valueof(ts_PFCP_Forwarding_Parameters(ACCESS))
			)
		)
		};
	return r;
}

/* Return a rule set that does GTP encapsulation and decapsulation, in both directions. */
private function f_ruleset_tunend(GTP_Action gtp, charstring netinst_access := "access") return PFCP_Ruleset
{
	var PFCP_Ruleset rules := { {}, {} };
	f_ruleset_add_GTP_decaps(rules,
				 pdr_id := gtp.access.pdr_id,
				 src_netinst := netinst_access,
				 far_id := gtp.core.tunend.far_id);
	f_ruleset_add_GTP_encaps(rules,
				 gtp.core.tunend.pdr_id,
				 gtp.core.tunend.ip_l,
				 gtp.access.far_id,
				 gtp.access.teid_r,
				 f_inet_addr(gtp.access.gtp_ip_r));
	return rules;
}

/* Return a rule set that does GTP tunnel forwarding in both directions.
 * If core_gtp_known == true, place full FORW rules in both directions.
 * If core_gtp_known == false, keep the Core side as DROP: this allows testing the usual/realistic case, where upon
 * Session Establishment, the core side PGW has not yet provided the destination GTP F-TEID, which will follow later in
 * a Session Modification. (This test suite has already configured which GTP F-TEID will be used on the core side, but
 * we're omitting it from Session Establishment, until it is time to use it in f_session_mod()). */
private function f_ruleset_tunmap(GTP_Action gtp, boolean core_gtp_known := true,
				  charstring netinst_access := "access",
				  charstring netinst_core := "core") return PFCP_Ruleset
{
	var PFCP_Ruleset rules := { {}, {} };
	/* Access to Core */
	if (core_gtp_known) {
		f_ruleset_add_GTP_forw(rules,
				       pdr_id := gtp.access.pdr_id,
				       src_iface := ACCESS,
				       src_netinst := netinst_access,
				       far_id := gtp.core.tunmap.far_id,
				       dest_iface := CORE,
				       dest_remote_f_teid := valueof(ts_PFCP_F_TEID_ipv4(gtp.core.tunmap.teid_r,
											 f_inet_addr(gtp.core.tunmap.gtp_ip_r))));
	} else {
		/* The Core remote GTP will follow in a Session Modification, for now set Core->Access to DROP */
		f_ruleset_add_GTP_drop(rules,
				       pdr_id := gtp.access.pdr_id,
				       src_iface := ACCESS,
				       src_netinst := netinst_access,
				       far_id := gtp.core.tunmap.far_id,
				       dest_iface := CORE);
	}
	/* Core to Access */
	f_ruleset_add_GTP_forw(rules,
			       pdr_id := gtp.core.tunmap.pdr_id,
			       src_iface := CORE,
			       src_netinst := netinst_core,
			       far_id := gtp.access.far_id,
			       dest_iface := ACCESS,
			       dest_remote_f_teid := valueof(ts_PFCP_F_TEID_ipv4(gtp.access.teid_r,
										 f_inet_addr(gtp.access.gtp_ip_r))));
	return rules;
}

/* From a PFCP Session Establishment Response, retrieve the F_TEID returned in the Created PDR IE for the given PDR Id
 */
private function f_get_created_local_f_teid(PDU_PFCP sess_est_resp, integer pdr_id) return F_TEID
{
	for (var integer i := 0;
	     i < lengthof(sess_est_resp.message_body.pfcp_session_establishment_response.created_PDR_list);
	     i := i + 1) {
		var Created_PDR cpdr := sess_est_resp.message_body.pfcp_session_establishment_response.created_PDR_list[i];
		if (oct2int(cpdr.grouped_ie.pdr_id.rule_id) != pdr_id) {
			continue;
		}
		log("osmo-upf has chosen local F-TEID: PDR-" & int2str(pdr_id) & " = ", cpdr.grouped_ie.local_F_TEID);
		return cpdr.grouped_ie.local_F_TEID;
	}
	setverdict(fail, "PDR Id " & int2str(pdr_id) & " not found in PFCP message");
	mtc.stop;
}

/* Run a PFCP Session Establishment procedure */
private function f_session_est(inout PFCP_session s, PFCP_Ruleset rules) runs on CPF_ConnHdlr
{
	log("f_session_est: rules = ", rules);
	PFCP.send(ts_PFCP_Session_Est_Req(ts_PFCP_Node_ID_ipv4(f_inet_addr(g_pars.local_addr)),
					  ts_PFCP_F_SEID_ipv4(f_inet_addr(g_pars.local_addr), s.cp_seid),
					  rules.pdr, rules.far));

	var PDU_PFCP pfcp;
	PFCP.receive(tr_PFCP_Session_Est_Resp(s.cp_seid)) -> value pfcp;
	s.up_seid := pfcp.message_body.pfcp_session_establishment_response.UP_F_SEID.seid;
	s.gtp.seid_l := s.up_seid;

	var F_TEID access_local_f_teid := f_get_created_local_f_teid(pfcp, s.gtp.access.pdr_id);
	s.gtp.access.gtp_ip_l := f_inet_ntoa(access_local_f_teid.ipv4_address);
	s.gtp.access.teid_l := access_local_f_teid.teid;

	if (ischosen(s.gtp.core.tunmap)) {
		var F_TEID core_local_f_teid := f_get_created_local_f_teid(pfcp, s.gtp.core.tunmap.pdr_id);
		s.gtp.core.tunmap.gtp_ip_l := f_inet_ntoa(core_local_f_teid.ipv4_address);
		s.gtp.core.tunmap.teid_l := core_local_f_teid.teid;
	}
	log("established PFCP session: ", s);
}

/* Run a PFCP Session Modification procedure */
private function f_session_mod(inout PFCP_session s) runs on CPF_ConnHdlr
{
	PFCP.send(ts_PFCP_Session_Mod_Req(s.up_seid, f_tunmap_upd_far_to_core(s.gtp)));
	PFCP.receive(tr_PFCP_Session_Mod_Resp(s.cp_seid));
	log("modified PFCP session: ", s);
}

private function f_create_PFCP_session_tunend() runs on CPF_ConnHdlr return PFCP_session
{
	var PFCP_session s := {
		up_seid := -,
		cp_seid := f_next_seid(),
		gtp := {
			kind := "tunend",
			access := {
				pdr_id := 1,
				/* gtp_ip_l and teid_l will be returned by Session Establishment Response, Created PDR */
				gtp_ip_l := "",
				teid_l := '00000000'O,
				far_id := 2,
				gtp_ip_r := "127.0.0.2",
				teid_r := f_next_remote_teid()
			},
			core := {
				tunend := {
					pdr_id := 2,
					ip_l := f_next_ue_addr(),
					far_id := 1
				}
			},
			pfcp_peer := g_pars.local_addr,
			seid_l := '0000000000000000'O
			/* seid_l will be returned by Session Establishment Response */
		}
	};
	return s;
}

private function f_create_PFCP_session_tunmap() runs on CPF_ConnHdlr return PFCP_session
{
	var PFCP_session s := {
		up_seid := -,
		cp_seid := f_next_seid(),
		gtp := {
			kind := "tunmap",
			access := {
				pdr_id := 1,
				/* gtp_ip_l and teid_l will be returned by Session Establishment Response, Created PDR */
				gtp_ip_l := "",
				teid_l := '00000000'O,
				far_id := 2,
				gtp_ip_r := "127.0.0.2",
				teid_r := f_next_remote_teid()
			},
			core := {
				tunmap := {
					pdr_id := 2,
					/* gtp_ip_l and teid_l will be returned by Session Establishment Response, Created PDR */
					gtp_ip_l := "",
					teid_l := '00000000'O,
					far_id := 1,
					gtp_ip_r := "127.0.0.3",
					teid_r := f_next_remote_teid()
				}
			},
			pfcp_peer := g_pars.local_addr,
			seid_l := '0000000000000000'O
			/* seid_l will be returned by Session Establishment Response */
		}
	};
	return s;
}

/* Do a PFCP Session Establishment with default values (see f_create_PFCP_session_tunend()) */
private function f_session_est_tunend() runs on CPF_ConnHdlr return PFCP_session
{
	var PFCP_session s := f_create_PFCP_session_tunend();
	f_session_est(s, f_ruleset_tunend(s.gtp));
	return s;
}

private function f_session_del(PFCP_session s) runs on CPF_ConnHdlr {
	PFCP.send(ts_PFCP_Session_Del_Req(s.up_seid));
	PFCP.receive(tr_PFCP_Session_Del_Resp(s.cp_seid));
}

private function f_tc_assoc(charstring id) runs on CPF_ConnHdlr {
	f_assoc_setup();
	f_assoc_release();
	setverdict(pass);
}

/* Verify that the CPF can send a Node-ID of the IPv4 type */
testcase TC_assoc_node_id_v4() runs on test_CT {
	var CPF_ConnHdlr vc_conn;

	f_init(guard_timeout := 5.0);
	vc_conn := f_start_handler(refers(f_tc_assoc));
	vc_conn.done;
	f_shutdown_helper();
}

/* Verify that the CPF can send a Node-ID of the FQDN type */
testcase TC_assoc_node_id_fqdn() runs on test_CT {
	var CPF_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();

	pars.local_node_id := valueof(ts_PFCP_Node_ID_fqdn("\7example\3com"));

	f_init(guard_timeout := 5.0);
	vc_conn := f_start_handler(refers(f_tc_assoc), pars);
	vc_conn.done;
	f_shutdown_helper();
}

/* Verify PFCP Session Establishment and Deletion */
private function f_tc_session_est_tunend(charstring id) runs on CPF_ConnHdlr {
	f_assoc_setup();
	var PFCP_session s := f_session_est_tunend();
	f_sleep(1.0);
	f_vty_expect_session_active(UPFVTY, s);
	f_session_del(s);
	f_vty_expect_no_active_sessions(UPFVTY);
	f_vty_expect_no_gtp_actions(UPFVTY);
	f_assoc_release();
	setverdict(pass);
}
testcase TC_session_est_tunend() runs on test_CT {
	var CPF_ConnHdlr vc_conn;

	f_init(guard_timeout := 15.0);
	vc_conn := f_start_handler(refers(f_tc_session_est_tunend));
	vc_conn.done;
	f_shutdown_helper();
}

/* Verify that releasing a PFCP Association also releases all its sessions and GTP actions. */
private function f_tc_session_term_by_assoc_rel(charstring id) runs on CPF_ConnHdlr {
	f_assoc_setup();
	var PFCP_session s := f_session_est_tunend();
	f_sleep(1.0);
	f_vty_expect_session_active(UPFVTY, s);
	f_assoc_release();
	f_vty_expect_no_active_sessions(UPFVTY);
	f_vty_expect_no_gtp_actions(UPFVTY);
	setverdict(pass);
}
testcase TC_session_term_by_assoc_rel() runs on test_CT {
	var CPF_ConnHdlr vc_conn;

	f_init(guard_timeout := 15.0);
	vc_conn := f_start_handler(refers(f_tc_session_term_by_assoc_rel));
	vc_conn.done;
	f_shutdown_helper();
}

/* Verify that PFCP Sessions with a src-interface other than ACCESS or CORE are ACKed by osmo-upf but have no effect. */
private function f_tc_session_est_noop(charstring id) runs on CPF_ConnHdlr {
	f_assoc_setup();
	var PFCP_session s := f_create_PFCP_session_tunend();
	f_session_est(s, f_ruleset_noop());

	f_sleep(1.0);
	f_vty_expect_session_status(UPFVTY, s, PFCP_session_inactive);

	f_session_del(s);
	f_vty_expect_no_active_sessions(UPFVTY);
	f_vty_expect_no_gtp_actions(UPFVTY);
	f_assoc_release();
	setverdict(pass);
}
testcase TC_session_est_noop() runs on test_CT {
	var CPF_ConnHdlr vc_conn;

	f_init(guard_timeout := 15.0);
	vc_conn := f_start_handler(refers(f_tc_session_est_noop));
	vc_conn.done;
	f_shutdown_helper();
}

/* Verify that the Network Instance IE in Create PDR chooses the right local address for a tunmap session */
private function f_tc_session_est_tunmap(charstring id) runs on CPF_ConnHdlr {
	f_assoc_setup();
	var PFCP_session s := f_create_PFCP_session_tunmap();
	f_session_est(s, f_ruleset_tunmap(s.gtp));
	f_sleep(1.0);
	f_vty_expect_session_active(UPFVTY, s);
	f_session_del(s);
	f_vty_expect_no_active_sessions(UPFVTY);
	f_vty_expect_no_gtp_actions(UPFVTY);
	f_assoc_release();
	setverdict(pass);
}
testcase TC_session_est_tunmap() runs on test_CT {
	var CPF_ConnHdlr vc_conn;

	f_init(guard_timeout := 15.0);

	vc_conn := f_start_handler(refers(f_tc_session_est_tunmap));
	vc_conn.done;
	f_shutdown_helper();
}

/* Set up a tunmap session with a partial Session Establishment, followed by a Session Modification to complete it. */
private function f_session_est_mod_tunmap(charstring netinst_access, charstring expect_gtp_ip_access,
					  charstring netinst_core, charstring expect_gtp_ip_core) runs on CPF_ConnHdlr {
	f_assoc_setup();
	var PFCP_session s := f_create_PFCP_session_tunmap();
	f_session_est(s, f_ruleset_tunmap(s.gtp, core_gtp_known := false,
					  netinst_access := netinst_access, netinst_core := netinst_core));
	/* The locally chosen GTP IP addresses where osmo-upf receives GTP traffic were chosen by netinst_access /
	 * netinst_core and are returned in s.gtp.access.gtp_ip_l / s.gtp.core.tunmap.gtp_ip_l. Verify that the netinst
	 * names have returned their matching IP addresses. */
	if (s.gtp.access.gtp_ip_l != expect_gtp_ip_access) {
		setverdict(fail, "Network Instance '" & netinst_access & "' should have yielded GTP IP " &
			   expect_gtp_ip_access & " but osmo-upf chose " & s.gtp.access.gtp_ip_l);
		mtc.stop;
	}
	if (s.gtp.core.tunmap.gtp_ip_l != expect_gtp_ip_core) {
		setverdict(fail, "Network Instance '" & netinst_core & "' should have yielded GTP IP " &
			   expect_gtp_ip_core & " but osmo-upf chose " & s.gtp.core.tunmap.gtp_ip_l);
		mtc.stop;
	}

	f_sleep(1.0);
	f_vty_expect_session_status(UPFVTY, s, PFCP_session_inactive);

	f_session_mod(s);
	f_sleep(1.0);
	f_vty_expect_session_active(UPFVTY, s);
	f_session_del(s);
	f_vty_expect_no_active_sessions(UPFVTY);
	f_vty_expect_no_gtp_actions(UPFVTY);
	f_assoc_release();
	setverdict(pass);
}
/* Run f_session_est_mod_tunmap() with the first Network Instances */
private function f_tc_session_est_mod_tunmap(charstring id) runs on CPF_ConnHdlr {
	f_session_est_mod_tunmap("access", mp_netinst_access_ip_1, "core", mp_netinst_core_ip_1);
}
/* Run f_session_est_mod_tunmap() with the second Network Instances */
private function f_tc_session_est_mod_tunmap2(charstring id) runs on CPF_ConnHdlr {
	f_session_est_mod_tunmap("access2", mp_netinst_access_ip_2, "core2", mp_netinst_core_ip_2);
}
testcase TC_session_est_mod_tunmap() runs on test_CT {
	var CPF_ConnHdlr vc_conn;

	f_init(guard_timeout := 15.0);

	vc_conn := f_start_handler(refers(f_tc_session_est_mod_tunmap));
	vc_conn.done;
	f_shutdown_helper();
}
testcase TC_session_est_mod_tunmap2() runs on test_CT {
	var CPF_ConnHdlr vc_conn;

	f_init(guard_timeout := 15.0);

	vc_conn := f_start_handler(refers(f_tc_session_est_mod_tunmap2));
	vc_conn.done;
	f_shutdown_helper();
}

control {
	execute( TC_assoc_node_id_v4() );
	execute( TC_assoc_node_id_fqdn() );
	execute( TC_session_est_tunend() );
	execute( TC_session_term_by_assoc_rel() );
	execute( TC_session_est_noop() );
	execute( TC_session_est_tunmap() );
	execute( TC_session_est_mod_tunmap() );
	execute( TC_session_est_mod_tunmap2() );
}

}
