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

}
