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;
		}
}

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 Misc_Helpers.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 Misc_Helpers.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 Misc_Helpers.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, Misc_Helpers.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() );
}

}
