/* main.c - Application main entry point */

/*
 * Copyright (c) 2021 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define NET_LOG_LEVEL CONFIG_NET_L2_VIRTUAL_LOG_LEVEL

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL);

#include <zephyr/types.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <zephyr/sys/printk.h>
#include <zephyr/random/rand32.h>

#include <ztest.h>

#include <zephyr/net/dummy.h>
#include <zephyr/net/buf.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/virtual.h>
#include <zephyr/net/virtual_mgmt.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/net_l2.h>

#include "ipv4.h"
#include "ipv6.h"
#include "udp_internal.h"

bool arp_add(struct net_if *iface, struct in_addr *src,
	     struct net_eth_addr *hwaddr);

#define NET_LOG_ENABLED 1
#include "net_private.h"

#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
#else
#define DBG(fmt, ...)
#endif

#define PKT_ALLOC_TIME K_MSEC(50)
#define TEST_PORT 9999

static char *test_data = "Test data to be sent";

/* Interface 1 addresses */
static struct in6_addr my_addr1 = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 0, 0x1 } } };
static struct in_addr my_addr = { { { 192, 0, 2, 1 } } };

/* Interface 2 addresses */
static struct in6_addr my_addr2 = { { { 0x20, 0x01, 0x0d, 0xb8, 2, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 0, 0x1 } } };

/* Interface 3 addresses */
static struct in6_addr my_addr3 = { { { 0x20, 0x01, 0x0d, 0xb8, 3, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 0, 0x1 } } };

/* Extra address is assigned to ll_addr */
static struct in6_addr ll_addr = { { { 0xfe, 0x80, 0x43, 0xb8, 0, 0, 0, 0,
				       0, 0, 0, 0xf2, 0xaa, 0x29, 0x02,
				       0x04 } } };

struct sockaddr virtual_addr;
struct sockaddr peer_addr;

#define MTU 1024

/* Keep track of all virtual interfaces */
static struct net_if *virtual_interfaces[1];
static struct net_if *eth_interfaces[2];
static struct net_if *dummy_interfaces[2];

static struct net_context *udp_ctx;

static bool test_failed;
static bool test_started;
static bool data_received;

static K_SEM_DEFINE(wait_data, 0, UINT_MAX);

#define WAIT_TIME K_SECONDS(1)

struct eth_context {
	struct net_if *iface;
	uint8_t mac_addr[6];
};

static struct eth_context eth_context;
static uint8_t expecting_outer;
static uint8_t expecting_inner;
static int header_len;

static void eth_iface_init(struct net_if *iface)
{
	const struct device *dev = net_if_get_device(iface);
	struct eth_context *context = dev->data;

	net_if_set_link_addr(iface, context->mac_addr,
			     sizeof(context->mac_addr),
			     NET_LINK_ETHERNET);

	ethernet_init(iface);
}

static int eth_tx(const struct device *dev, struct net_pkt *pkt)
{
	struct eth_context *context = dev->data;

	zassert_equal_ptr(&eth_context, context,
			  "Context pointers do not match (%p vs %p)",
			  eth_context, context);

	if (!pkt->buffer) {
		DBG("No data to send!\n");
		return -ENODATA;
	}

	if (test_started) {
		uint8_t outer, inner;
		int ret;

		net_pkt_set_overwrite(pkt, true);

		net_pkt_hexdump(pkt, "pkt");
		net_pkt_skip(pkt, sizeof(struct net_eth_hdr));

		ret = net_pkt_read_u8(pkt, &outer);
		zassert_equal(ret, 0, "Cannot read outer protocol type");
		zassert_equal(outer, expecting_outer,
			      "Unexpected outer protocol 0x%02x, "
			      "expecting 0x%02x",
			      outer, expecting_outer);
		net_pkt_skip(pkt, header_len - 1);

		ret = net_pkt_read_u8(pkt, &inner);
		zassert_equal(ret, 0, "Cannot read inner protocol type");
		zassert_equal(inner, expecting_inner,
			      "Unexpected inner protocol 0x%02x, "
			      "expecting 0x%02x",
			      inner, expecting_inner);

		k_sem_give(&wait_data);
	}

	net_pkt_unref(pkt);

	return 0;
}

static enum ethernet_hw_caps eth_capabilities(const struct device *dev)
{
	return 0;
}

static struct ethernet_api api_funcs = {
	.iface_api.init = eth_iface_init,

	.get_capabilities = eth_capabilities,
	.send = eth_tx,
};

static void generate_mac(uint8_t *mac_addr)
{
	/* 00-00-5E-00-53-xx Documentation RFC 7042 */
	mac_addr[0] = 0x00;
	mac_addr[1] = 0x00;
	mac_addr[2] = 0x5E;
	mac_addr[3] = 0x00;
	mac_addr[4] = 0x53;
	mac_addr[5] = sys_rand32_get();
}

static int eth_init(const struct device *dev)
{
	struct eth_context *context = dev->data;

	generate_mac(context->mac_addr);

	return 0;
}

ETH_NET_DEVICE_INIT(eth_test, "eth_test",
		    eth_init, NULL,
		    &eth_context, NULL, CONFIG_ETH_INIT_PRIORITY,
		    &api_funcs, NET_ETH_MTU);

struct net_if_test {
	uint8_t idx; /* not used for anything, just a dummy value */
	uint8_t mac_addr[sizeof(struct net_eth_addr)];
	struct net_linkaddr ll_addr;
};

static int net_iface_dev_init(const struct device *dev)
{
	return 0;
}

static uint8_t *net_iface_get_mac(const struct device *dev)
{
	struct net_if_test *data = dev->data;

	if (data->mac_addr[2] == 0x00) {
		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
		data->mac_addr[0] = 0x00;
		data->mac_addr[1] = 0x00;
		data->mac_addr[2] = 0x5E;
		data->mac_addr[3] = 0x00;
		data->mac_addr[4] = 0x53;
		data->mac_addr[5] = sys_rand32_get();
	}

	data->ll_addr.addr = data->mac_addr;
	data->ll_addr.len = 6U;

	return data->mac_addr;
}

static void net_iface_init(struct net_if *iface)
{
	uint8_t *mac = net_iface_get_mac(net_if_get_device(iface));

	net_if_set_link_addr(iface, mac, sizeof(struct net_eth_addr),
			     NET_LINK_ETHERNET);
}

static int sender_iface(const struct device *dev, struct net_pkt *pkt)
{
	return 0;
}

struct net_if_test net_iface1_data;
struct net_if_test net_iface2_data;

static struct dummy_api net_iface_api = {
	.iface_api.init = net_iface_init,
	.send = sender_iface,
};

/* For testing purposes, create two dummy network interfaces so we can check
 * that attaching virtual interface work ok.
 */
NET_DEVICE_INIT_INSTANCE(eth_test_dummy1,
			 "iface1",
			 iface1,
			 net_iface_dev_init,
			 NULL,
			 &net_iface1_data,
			 NULL,
			 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
			 &net_iface_api,
			 DUMMY_L2,
			 NET_L2_GET_CTX_TYPE(DUMMY_L2),
			 127);

NET_DEVICE_INIT_INSTANCE(eth_test_dummy2,
			 "iface2",
			 iface2,
			 net_iface_dev_init,
			 NULL,
			 &net_iface2_data,
			 NULL,
			 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
			 &net_iface_api,
			 DUMMY_L2,
			 NET_L2_GET_CTX_TYPE(DUMMY_L2),
			 127);

struct user_data {
	int eth_if_count;
	int dummy_if_count;
	int virtual_if_count;
	int total_if_count;
};

#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
static const char *iface2str(struct net_if *iface)
{
	if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) {
		return "Ethernet";
	}

	if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) {
		return "Dummy";
	}

	if (net_if_l2(iface) == &NET_L2_GET_NAME(VIRTUAL)) {
		return "Virtual";
	}

	return "<unknown type>";
}
#endif

static void iface_cb(struct net_if *iface, void *user_data)
{
	struct user_data *ud = user_data;
	static int starting_eth_idx = 1;

	/*
	 * The below code is to only use struct net_if devices defined in this
	 * test as board on which it is run can have its own set of interfaces.
	 *
	 * As a result one will not rely on linker's specific 'net_if_area'
	 * placement.
	 */
	if ((iface != net_if_lookup_by_dev(DEVICE_GET(eth_test_dummy1))) &&
	    (iface != net_if_lookup_by_dev(DEVICE_GET(eth_test_dummy2))) &&
	    (iface != net_if_lookup_by_dev(DEVICE_GET(eth_test))) &&
	    (net_if_l2(iface) != &NET_L2_GET_NAME(VIRTUAL)))
		return;

	DBG("Interface %p (%s) [%d]\n", iface, iface2str(iface),
	    net_if_get_by_iface(iface));

	if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) {
		if (PART_OF_ARRAY(NET_IF_GET_NAME(eth_test, 0), iface)) {
			if (!eth_interfaces[0]) {
				/* Just use the first interface */
				eth_interfaces[0] = iface;
				ud->eth_if_count++;
			}
		} else {
			if (ud->eth_if_count > ARRAY_SIZE(eth_interfaces)) {
				goto out;
			}

			eth_interfaces[starting_eth_idx++] = iface;
			ud->eth_if_count++;
		}
	}

	if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) {
		dummy_interfaces[ud->dummy_if_count++] = iface;

		zassert_true(ud->dummy_if_count <= 2,
			     "Too many dummy interfaces");
	}

	if (net_if_l2(iface) == &NET_L2_GET_NAME(VIRTUAL)) {
		virtual_interfaces[ud->virtual_if_count++] = iface;

		zassert_true(ud->virtual_if_count <= 3,
			     "Too many virtual interfaces");
	} else {
		/* By default all interfaces are down initially */
		/* Virtual interfaces are down initially */
		net_if_down(iface);
	}

out:
	ud->total_if_count++;
}

static void test_virtual_setup(void)
{
	struct user_data ud = { 0 };

	/* Make sure we have enough virtual interfaces */
	net_if_foreach(iface_cb, &ud);

	zassert_equal(ud.virtual_if_count, ARRAY_SIZE(virtual_interfaces),
		      "Invalid number of virtual interfaces, "
		      "was %d should be %zu",
		      ud.virtual_if_count, ARRAY_SIZE(virtual_interfaces));

	zassert_true(ud.eth_if_count <= ARRAY_SIZE(eth_interfaces),
		      "Invalid number of eth interfaces, "
		      "was %d should be %zu",
		      ud.eth_if_count, ARRAY_SIZE(eth_interfaces));

	zassert_equal(ud.dummy_if_count, ARRAY_SIZE(dummy_interfaces),
		      "Invalid number of dummy interfaces, "
		      "was %d should be %zu",
		      ud.dummy_if_count, ARRAY_SIZE(dummy_interfaces));
}

static void test_address_setup(void)
{
	struct net_if_addr *ifaddr;
	struct net_if *eth, *virt, *dummy1, *dummy2;
	int ret;

	eth = eth_interfaces[0];
	virt = virtual_interfaces[0];
	dummy1 = dummy_interfaces[0];
	dummy2 = dummy_interfaces[1];

	zassert_not_null(eth, "Eth Interface");
	zassert_not_null(virt, "Virtual Interface");
	zassert_not_null(dummy1, "Dummy Interface 1");
	zassert_not_null(dummy2, "Dummy Interface 2");

	ifaddr = net_if_ipv6_addr_add(eth, &my_addr1, NET_ADDR_MANUAL, 0);
	if (!ifaddr) {
		DBG("Cannot add IPv6 address %s\n",
		    net_sprint_ipv6_addr(&my_addr1));
		zassert_not_null(ifaddr, "eth addr");
	}

	/* For testing purposes we need to set the addresses preferred */
	ifaddr->addr_state = NET_ADDR_PREFERRED;

	ifaddr = net_if_ipv4_addr_add(eth, &my_addr, NET_ADDR_MANUAL, 0);
	if (!ifaddr) {
		DBG("Cannot add IPv4 address %s\n",
		    net_sprint_ipv4_addr(&my_addr));
		zassert_not_null(ifaddr, "eth addr");
	}

	ifaddr->addr_state = NET_ADDR_PREFERRED;

	ifaddr = net_if_ipv6_addr_add(eth, &ll_addr, NET_ADDR_MANUAL, 0);
	if (!ifaddr) {
		DBG("Cannot add IPv6 address %s\n",
		    net_sprint_ipv6_addr(&ll_addr));
		zassert_not_null(ifaddr, "ll_addr");
	}

	ifaddr->addr_state = NET_ADDR_PREFERRED;

	ifaddr = net_if_ipv6_addr_add(virt, &my_addr2, NET_ADDR_MANUAL, 0);
	if (!ifaddr) {
		DBG("Cannot add IPv6 address %s\n",
		    net_sprint_ipv6_addr(&my_addr2));
		zassert_not_null(ifaddr, "virt addr");
	}

	ifaddr->addr_state = NET_ADDR_PREFERRED;

	ifaddr = net_if_ipv6_addr_add(dummy1, &my_addr3, NET_ADDR_MANUAL, 0);
	if (!ifaddr) {
		DBG("Cannot add IPv6 address %s\n",
		       net_sprint_ipv6_addr(&my_addr3));
		zassert_not_null(ifaddr, "dummy1 addr");
	}

	net_if_up(eth);
	net_if_up(dummy1);
	net_if_up(dummy2);

	/* Set the virtual interface addresses */
	ret = net_ipaddr_parse(CONFIG_NET_TEST_TUNNEL_MY_ADDR,
			       strlen(CONFIG_NET_TEST_TUNNEL_MY_ADDR),
			       &virtual_addr);
	zassert_equal(ret, 1, "Cannot parse \"%s\"",
		      CONFIG_NET_TEST_TUNNEL_MY_ADDR);

	if (virtual_addr.sa_family == AF_INET) {
		ifaddr = net_if_ipv4_addr_add(virt,
					&net_sin(&virtual_addr)->sin_addr,
					NET_ADDR_MANUAL, 0);
		if (!ifaddr) {
			DBG("Cannot add IPv4 address %s\n",
			    net_sprint_ipv4_addr(
				    &net_sin(&virtual_addr)->sin_addr));
			zassert_not_null(ifaddr, "virt addr");
		}

		net_sin(&virtual_addr)->sin_port = htons(4242);
	} else if (virtual_addr.sa_family == AF_INET6) {
		ifaddr = net_if_ipv6_addr_add(virt,
					&net_sin6(&virtual_addr)->sin6_addr,
					NET_ADDR_MANUAL, 0);
		if (!ifaddr) {
			DBG("Cannot add IPv6 address %s\n",
			    net_sprint_ipv6_addr(
				    &net_sin6(&virtual_addr)->sin6_addr));
			zassert_not_null(ifaddr, "virt addr");
		}

		net_sin6(&virtual_addr)->sin6_port = htons(4242);
	} else {
		zassert_not_null(NULL, "Invalid address family (%d)",
				 virtual_addr.sa_family);
	}

	ifaddr->addr_state = NET_ADDR_PREFERRED;

	ret = net_ipaddr_parse(CONFIG_NET_TEST_TUNNEL_PEER_ADDR,
			       strlen(CONFIG_NET_TEST_TUNNEL_PEER_ADDR),
			       &peer_addr);
	zassert_equal(ret, 1, "Cannot parse \"%s\"",
		      CONFIG_NET_TEST_TUNNEL_PEER_ADDR);

	/* The interface might receive data which might fail the checks
	 * in the iface sending function, so we need to reset the failure
	 * flag.
	 */
	test_failed = false;
}

static bool add_neighbor(struct net_if *iface, struct in6_addr *addr)
{
	struct net_linkaddr_storage llstorage;
	struct net_linkaddr lladdr;
	struct net_nbr *nbr;

	llstorage.addr[0] = 0x01;
	llstorage.addr[1] = 0x02;
	llstorage.addr[2] = 0x33;
	llstorage.addr[3] = 0x44;
	llstorage.addr[4] = 0x05;
	llstorage.addr[5] = 0x06;

	lladdr.len = 6U;
	lladdr.addr = llstorage.addr;
	lladdr.type = NET_LINK_ETHERNET;

	nbr = net_ipv6_nbr_add(iface, addr, &lladdr, false,
			       NET_IPV6_NBR_STATE_REACHABLE);
	if (!nbr) {
		DBG("Cannot add dst %s to neighbor cache\n",
		    net_sprint_ipv6_addr(addr));
		return false;
	}

	return true;
}

static bool add_to_arp(struct net_if *iface, struct in_addr *addr)
{
#if defined(CONFIG_NET_ARP)
	struct net_eth_addr lladdr;

	lladdr.addr[0] = sys_rand32_get();
	lladdr.addr[1] = 0x08;
	lladdr.addr[2] = 0x09;
	lladdr.addr[3] = 0x10;
	lladdr.addr[4] = 0x11;
	lladdr.addr[5] = sys_rand32_get();

	return arp_add(iface, addr, &lladdr);
#else
	ARG_UNUSED(iface);
	ARG_UNUSED(addr);

	return true;
#endif
}

static void test_virtual_attach_and_detach(void)
{
	struct net_if *iface = virtual_interfaces[0];
	int ret;

	/* Attach virtual interface on top of Ethernet */

	ret = net_virtual_interface_attach(iface, eth_interfaces[0]);
	zassert_equal(ret, 0, "Cannot attach %d on top of %d (%d)",
		      net_if_get_by_iface(iface),
		      net_if_get_by_iface(eth_interfaces[0]),
		      ret);

	zassert_false(net_if_is_up(iface),
		      "Virtual interface %d should be down",
		      net_if_get_by_iface(iface));

	ret = net_if_up(iface);
	zassert_equal(ret, 0, "Cannot take virtual interface %d up (%d)",
		      net_if_get_by_iface(iface), ret);

	ret = net_virtual_interface_attach(iface,
					   NULL);
	zassert_equal(ret, 0, "Cannot deattach %d from %d (%d)",
		      net_if_get_by_iface(iface),
		      net_if_get_by_iface(eth_interfaces[0]),
		      ret);

	zassert_false(net_if_is_up(iface), "Virtual interface %d is still up",
		      net_if_get_by_iface(iface));
}

static void test_virtual_set_mtu(void)
{
	struct virtual_interface_req_params params = { 0 };
	struct net_if *iface = virtual_interfaces[0];
	int ret;

	ret = net_if_up(iface);
	zassert_equal(ret, 0, "Cannot take virtual interface %d up (%d)",
		      net_if_get_by_iface(iface), ret);

	params.mtu = MTU;

	ret = net_mgmt(NET_REQUEST_VIRTUAL_INTERFACE_SET_MTU,
		       iface, &params, sizeof(params));
	zassert_equal(ret, -EACCES, "Could set interface %d MTU to %d (%d)",
		      net_if_get_by_iface(iface), params.mtu, ret);

	ret = net_if_down(iface);
	zassert_equal(ret, 0, "Cannot take virtual interface %d down (%d)",
		      net_if_get_by_iface(iface), ret);

	ret = net_mgmt(NET_REQUEST_VIRTUAL_INTERFACE_SET_MTU,
		       iface, &params, sizeof(params));
	zassert_equal(ret, 0, "Cannot set interface %d MTU to %d (%d)",
		      net_if_get_by_iface(iface), params.mtu, ret);
}

static void test_virtual_get_mtu(void)
{
	struct virtual_interface_req_params params = { 0 };
	struct net_if *iface = virtual_interfaces[0];
	int ret;

	params.mtu = 0;

	ret = net_mgmt(NET_REQUEST_VIRTUAL_INTERFACE_GET_MTU,
		       iface, &params, sizeof(params));
	zassert_equal(ret, 0, "Cannot get interface %d MTU (%d)",
		      net_if_get_by_iface(iface), params.mtu, ret);

	zassert_equal(params.mtu, MTU,
		      "MTU mismatch from interface %d, got %d should be %d",
		      net_if_get_by_iface(iface), params.mtu, MTU);
}

static void test_virtual_set_peer(void)
{
	struct virtual_interface_req_params params = { 0 };
	struct net_if *iface = virtual_interfaces[0];
	int ret;

	ret = net_if_up(iface);
	zassert_equal(ret, 0, "Cannot take virtual interface %d up (%d)",
		      net_if_get_by_iface(iface), ret);

	params.family = peer_addr.sa_family;
	if (params.family == AF_INET) {
		net_ipaddr_copy(&params.peer4addr,
				&net_sin(&peer_addr)->sin_addr);
	} else if (params.family == AF_INET6) {
		net_ipaddr_copy(&params.peer6addr,
				&net_sin6(&peer_addr)->sin6_addr);
	} else {
		zassert_true(false, "Invalid family (%d)", params.family);
	}

	ret = net_mgmt(NET_REQUEST_VIRTUAL_INTERFACE_SET_PEER_ADDRESS,
		       iface, &params, sizeof(params));
	zassert_equal(ret, -EACCES, "Could set interface %d peer to %s (%d)",
		      net_if_get_by_iface(iface),
		      CONFIG_NET_TEST_TUNNEL_PEER_ADDR, ret);

	ret = net_if_down(iface);
	zassert_equal(ret, 0, "Cannot take virtual interface %d down (%d)",
		      net_if_get_by_iface(iface), ret);

	ret = net_mgmt(NET_REQUEST_VIRTUAL_INTERFACE_SET_PEER_ADDRESS,
		       iface, &params, sizeof(params));
	zassert_equal(ret, 0, "Cannot set interface %d peer to %s (%d)",
		      net_if_get_by_iface(iface),
		      CONFIG_NET_TEST_TUNNEL_PEER_ADDR, ret);

	/* We should be attached now */
	ret = net_virtual_interface_attach(iface, dummy_interfaces[0]);
	zassert_equal(ret, -EALREADY, "Could attach %d on top of %d (%d)",
		      net_if_get_by_iface(iface),
		      net_if_get_by_iface(dummy_interfaces[0]),
		      ret);
}

static void test_virtual_get_peer(void)
{
	struct virtual_interface_req_params params = { 0 };
	struct net_if *iface = virtual_interfaces[0];
	int ret;

	ret = net_mgmt(NET_REQUEST_VIRTUAL_INTERFACE_GET_PEER_ADDRESS,
		       iface, &params, sizeof(params));
	zassert_equal(ret, 0, "Cannot get interface %d peer (%d)",
		      net_if_get_by_iface(iface), ret);

	zassert_equal(params.family, peer_addr.sa_family,
		      "Invalid family, should be %d was %d",
		      peer_addr.sa_family, params.family);
	if (params.family == AF_INET) {
		zassert_mem_equal(&params.peer4addr,
				  &net_sin(&peer_addr)->sin_addr,
				  sizeof(struct in_addr),
				  "Peer IPv4 address invalid");
	} else if (params.family == AF_INET6) {
		zassert_mem_equal(&params.peer6addr,
				  &net_sin6(&peer_addr)->sin6_addr,
				  sizeof(struct in6_addr),
				  "Peer IPv6 address invalid");
	} else {
		zassert_true(false, "Invalid family (%d)", params.family);
	}
}

static void test_virtual_verify_name(void)
{
#define NAME "foobar"
#define NAME2 "123456789"
	struct net_if *iface = virtual_interfaces[0];
	char *tmp = NAME;
	char buf[sizeof(NAME2)];
	char *name;

	net_virtual_set_name(iface, NAME);
	name = net_virtual_get_name(iface, buf, sizeof(buf));
	zassert_mem_equal(name, tmp, strlen(name), "Cannot get name");

	/* Check that the string is truncated */
	tmp = NAME2;
	net_virtual_set_name(iface, tmp);
	name = net_virtual_get_name(iface, buf, sizeof(buf));
	zassert_mem_equal(name, tmp, strlen(name), "Cannot get name");
	zassert_mem_equal(name, tmp, strlen(tmp) -
			  (sizeof(NAME2) - CONFIG_NET_L2_VIRTUAL_MAX_NAME_LEN),
			  "Cannot get name");
}

static void test_virtual_send_data_to_tunnel(void)
{
	struct virtual_interface_req_params params = { 0 };
	struct net_if *iface = virtual_interfaces[0];
	struct net_if *attached;
	struct sockaddr dst_addr, src_addr;
	struct in_addr netmask = {{{ 255, 255, 255, 0 }}};
	void *addr;
	int addrlen;
	int ret;

	params.family = peer_addr.sa_family;
	if (params.family == AF_INET) {
		net_ipaddr_copy(&params.peer4addr,
				&net_sin(&peer_addr)->sin_addr);
		expecting_outer = 0x45;
		header_len = sizeof(struct net_ipv4_hdr);

		ret = add_to_arp(eth_interfaces[0],
				 &net_sin(&peer_addr)->sin_addr);
		zassert_true(ret, "Cannot add to arp");
	} else if (params.family == AF_INET6) {
		net_ipaddr_copy(&params.peer6addr,
				&net_sin6(&peer_addr)->sin6_addr);
		expecting_outer = 0x60;
		header_len = sizeof(struct net_ipv6_hdr);

		ret = add_neighbor(eth_interfaces[0],
				   &net_sin6(&peer_addr)->sin6_addr);
		zassert_true(ret, "Cannot add neighbor");
	} else {
		zassert_true(false, "Invalid family (%d)", params.family);
	}

	net_if_ipv4_set_netmask(iface, &netmask);
	net_if_ipv4_set_netmask(eth_interfaces[0], &netmask);

	ret = net_mgmt(NET_REQUEST_VIRTUAL_INTERFACE_SET_PEER_ADDRESS,
		       iface, &params, sizeof(params));
	zassert_equal(ret, 0, "Cannot set interface %d peer to %s (%d)",
		      net_if_get_by_iface(iface),
		      CONFIG_NET_TEST_TUNNEL_PEER_ADDR, ret);

	net_virtual_set_name(iface, CONFIG_NET_TEST_TUNNEL_NAME);

	attached = net_virtual_get_iface(iface);
	zassert_equal(eth_interfaces[0], attached,
		      "Not attached to Ethernet interface");

	ret = net_if_up(iface);
	zassert_equal(ret, 0, "Cannot take virtual interface %d up (%d)",
		      net_if_get_by_iface(iface), ret);

	memcpy(&dst_addr, &virtual_addr, sizeof(dst_addr));
	memcpy(&src_addr, &virtual_addr, sizeof(src_addr));

	if (dst_addr.sa_family == AF_INET) {
		net_sin(&dst_addr)->sin_addr.s4_addr[3] = 2;

		addr = &src_addr;
		addrlen = sizeof(struct sockaddr_in);

		expecting_inner = 0x45; /* IPv4 */

	} else if (dst_addr.sa_family == AF_INET6) {
		net_sin6(&dst_addr)->sin6_addr.s6_addr[15] = 2;

		addr = &src_addr;
		addrlen = sizeof(struct sockaddr_in6);

		expecting_inner = 0x60; /* IPv6 */
	} else {
		zassert_true(false, "Invalid family (%d)", dst_addr.sa_family);
		addrlen = 0;
	}

	ret = net_context_get(virtual_addr.sa_family, SOCK_DGRAM, IPPROTO_UDP,
			      &udp_ctx);
	zassert_equal(ret, 0, "Create IP UDP context failed");

	ret = net_context_bind(udp_ctx, (struct sockaddr *)addr, addrlen);
	zassert_equal(ret, 0, "Context bind failure test failed");

	test_started = true;

	ret = net_context_sendto(udp_ctx, test_data, strlen(test_data),
				 &dst_addr, addrlen,
				 NULL, K_NO_WAIT, NULL);
	zassert_true(ret > 0, "Send UDP pkt failed");

	if (k_sem_take(&wait_data, WAIT_TIME)) {
		DBG("Timeout while waiting interface data\n");
		zassert_false(true, "Timeout");
	}

	net_context_unref(udp_ctx);
}

static struct net_pkt *create_outer(struct net_if *iface,
				    sa_family_t family,
				    enum net_ip_protocol proto,
				    size_t inner_len,
				    size_t outer_len)
{
	return net_pkt_alloc_with_buffer(iface, inner_len + outer_len,
					 family, proto, PKT_ALLOC_TIME);
}

static struct net_pkt *create_inner(struct net_if *iface,
				    sa_family_t family,
				    enum net_ip_protocol proto,
				    size_t inner_len,
				    size_t data_len)
{
	return net_pkt_alloc_with_buffer(iface, inner_len + data_len,
					 family, proto, PKT_ALLOC_TIME);
}

static void recv_data(struct net_context *context,
		      struct net_pkt *pkt,
		      union net_ip_header *ip_hdr,
		      union net_proto_header *proto_hdr,
		      int status,
		      void *user_data)
{
	data_received = true;
}

static void test_virtual_recv_data_from_tunnel(int remote_ip,
					       bool expected_ok)
{
	struct net_if *iface = virtual_interfaces[0];
	struct net_if *attached = eth_interfaces[0];
	struct sockaddr dst_addr, src_addr, inner_src;
	struct in_addr *outerv4, *innerv4;
	struct in6_addr *outerv6, *innerv6;
	size_t inner_len = sizeof(struct net_udp_hdr) +
		strlen(test_data);
	struct net_pkt *outer, *inner;
	enum net_verdict verdict;
	uint16_t src_port = 4242, dst_port = 4242;
	uint8_t next_header;
	size_t addrlen;
	int ret;

	memcpy(&dst_addr, &peer_addr, sizeof(dst_addr));
	memcpy(&src_addr, &peer_addr, sizeof(src_addr));
	memcpy(&inner_src, &virtual_addr, sizeof(inner_src));

	if (peer_addr.sa_family == AF_INET) {
		net_sin(&dst_addr)->sin_addr.s4_addr[3] = 1;
		net_sin(&src_addr)->sin_addr.s4_addr[3] = remote_ip;
		outerv4 = &net_sin(&peer_addr)->sin_addr;
	} else {
		net_sin6(&dst_addr)->sin6_addr.s6_addr[15] = 1;
		net_sin6(&src_addr)->sin6_addr.s6_addr[15] = remote_ip;
		outerv6 = &net_sin6(&peer_addr)->sin6_addr;
	}

	if (virtual_addr.sa_family == AF_INET) {
		net_sin(&inner_src)->sin_addr.s4_addr[3] = 2;
		innerv4 = &net_sin(&virtual_addr)->sin_addr;
		inner_len += sizeof(struct net_ipv4_hdr);
	} else {
		net_sin6(&inner_src)->sin6_addr.s6_addr[15] = 2;
		innerv6 = &net_sin6(&virtual_addr)->sin6_addr;
		inner_len += sizeof(struct net_ipv6_hdr);
	}

	if (peer_addr.sa_family == AF_INET) {
		outer = create_outer(attached, AF_INET, IPPROTO_IP,
				     sizeof(struct net_ipv4_hdr), 0);
		zassert_not_null(outer, "Cannot allocate %s pkt", outer);

		ret = net_ipv4_create(outer, &net_sin(&src_addr)->sin_addr,
				      &net_sin(&dst_addr)->sin_addr);
		zassert_equal(ret, 0, "Cannot create %s packet (%d)", "IPv4",
			      ret);
	} else {
		outer = create_outer(attached, AF_INET6, IPPROTO_IPV6,
				     sizeof(struct net_ipv6_hdr), 0);
		zassert_not_null(outer, "Cannot allocate %s pkt", outer);

		ret = net_ipv6_create(outer, &net_sin6(&src_addr)->sin6_addr,
				      &net_sin6(&dst_addr)->sin6_addr);
		zassert_equal(ret, 0, "Cannot create %s packet (%d)", "IPv6",
			      ret);
	}

	if (virtual_addr.sa_family == AF_INET) {
		inner = create_inner(iface, AF_INET, IPPROTO_IP,
				     sizeof(struct net_ipv4_hdr),
				     sizeof(struct net_udp_hdr) +
				     strlen(test_data));
		zassert_not_null(inner, "Cannot allocate %s pkt", inner);

		ret = net_ipv4_create(inner, &net_sin(&inner_src)->sin_addr,
				      innerv4);
		zassert_equal(ret, 0, "Cannot create outer %s (%d)", "IPv4",
			      ret);
		next_header = IPPROTO_IPIP;
		addrlen = sizeof(struct sockaddr_in);
	} else {
		inner = create_inner(iface, AF_INET6, IPPROTO_IPV6,
				     sizeof(struct net_ipv6_hdr),
				     sizeof(struct net_udp_hdr) +
				     strlen(test_data));
		zassert_not_null(inner, "Cannot allocate %s pkt", inner);

		ret = net_ipv6_create(inner, &net_sin6(&inner_src)->sin6_addr,
				      innerv6);
		zassert_equal(ret, 0, "Cannot create outer %s (%d)", "IPv6",
			      ret);
		next_header = IPPROTO_IPV6;
		addrlen = sizeof(struct sockaddr_in6);
	}

	ret = net_udp_create(inner, htons(src_port), htons(dst_port));
	zassert_equal(ret, 0, "Cannot create UDP (%d)", ret);

	net_pkt_write(inner, test_data, strlen(test_data));

	net_pkt_cursor_init(inner);
	net_ipv4_finalize(inner, IPPROTO_UDP);

	net_buf_frag_add(outer->buffer, inner->buffer);
	inner->buffer = NULL;
	net_pkt_unref(inner);

	net_pkt_cursor_init(outer);

	if (peer_addr.sa_family == AF_INET) {
		net_ipv4_finalize(outer, next_header);
	} else {
		net_ipv6_finalize(outer, next_header);
	}

	ret = net_context_get(virtual_addr.sa_family, SOCK_DGRAM, IPPROTO_UDP,
			      &udp_ctx);
	zassert_equal(ret, 0, "Create IP UDP context failed");

	net_context_set_iface(udp_ctx, iface);

	ret = net_context_bind(udp_ctx, (struct sockaddr *)&virtual_addr,
			       addrlen);
	zassert_equal(ret, 0, "Context bind failure test failed");

	test_started = true;
	data_received = false;

	ret = net_context_recv(udp_ctx, recv_data, K_NO_WAIT, &wait_data);
	zassert_equal(ret, 0, "UDP recv failed");

	net_pkt_cursor_init(outer);

	if (peer_addr.sa_family == AF_INET) {
		verdict = net_ipv4_input(outer);
	} else {
		verdict = net_ipv6_input(outer, false);
	}

	if (expected_ok) {
		zassert_equal(verdict, NET_CONTINUE,
			      "Packet not accepted (%d)",
			      verdict);
	} else {
		zassert_equal(verdict, NET_DROP,
			      "Packet not dropped (%d)",
			      verdict);
	}

	net_context_put(udp_ctx);
}

static void test_virtual_recv_data_from_tunnel_ok(void)
{
	test_virtual_recv_data_from_tunnel(2, true);
}

static void test_virtual_recv_data_from_tunnel_fail(void)
{
	test_virtual_recv_data_from_tunnel(3, false);
}

void test_main(void)
{
	ztest_test_suite(net_virtual_test,
			 ztest_unit_test(test_virtual_setup),
			 ztest_unit_test(test_address_setup),
			 ztest_unit_test(test_virtual_attach_and_detach),
			 ztest_unit_test(test_virtual_set_mtu),
			 ztest_unit_test(test_virtual_get_mtu),
			 ztest_unit_test(test_virtual_set_peer),
			 ztest_unit_test(test_virtual_get_peer),
			 ztest_unit_test(test_virtual_verify_name),
			 ztest_unit_test(test_virtual_send_data_to_tunnel),
			 ztest_unit_test(test_virtual_recv_data_from_tunnel_ok),
			 ztest_unit_test(test_virtual_recv_data_from_tunnel_fail)
			 );

	ztest_run_test_suite(net_virtual_test);
}
