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

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_virtual_interface_sample, LOG_LEVEL_DBG);

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <errno.h>

#include <zephyr/net/net_core.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/virtual.h>
#include <zephyr/net/virtual_mgmt.h>

/* User data for the interface callback */
struct ud {
	struct net_if *my_iface;
	struct net_if *ethernet;
	struct net_if *ip_tunnel_1;
	struct net_if *ip_tunnel_2;
	struct net_if *ipip;
};

/* The MTU value here is just an arbitrary number for testing purposes */
#define VIRTUAL_TEST_MTU 1024

#define VIRTUAL_TEST "VIRTUAL_TEST"
#define VIRTUAL_TEST2 "VIRTUAL_TEST2"
#define VIRTUAL_TEST3 "VIRTUAL_TEST3"
static const char *dev_name = VIRTUAL_TEST;
static const char *ipip_dev_name = "IP_tunnel";

struct virtual_test_context {
	struct net_if *iface;
	struct net_if *attached_to;
	bool status;
	bool init_done;
};

static void virtual_test_iface_init(struct net_if *iface)
{
	struct virtual_test_context *ctx = net_if_get_device(iface)->data;
	char name[sizeof("VirtualTest-+##########")];
	static int count;

	if (ctx->init_done) {
		return;
	}

	ctx->iface = iface;
	net_if_flag_set(iface, NET_IF_NO_AUTO_START);

	snprintk(name, sizeof(name), "VirtualTest-%d", count + 1);
	count++;
	net_virtual_set_name(iface, name);
	(void)net_virtual_set_flags(iface, NET_L2_POINT_TO_POINT);

	ctx->init_done = true;
}

static struct virtual_test_context virtual_test_context_data1 = {
};

static struct virtual_test_context virtual_test_context_data2 = {
};

static struct virtual_test_context virtual_test_context_data3 = {
};

static enum virtual_interface_caps
virtual_test_get_capabilities(struct net_if *iface)
{
	ARG_UNUSED(iface);

	return (enum virtual_interface_caps)0;
}

static int virtual_test_interface_start(const struct device *dev)
{
	struct virtual_test_context *ctx = dev->data;

	if (ctx->status) {
		return -EALREADY;
	}

	ctx->status = true;

	LOG_DBG("Starting iface %d", net_if_get_by_iface(ctx->iface));

	/* You can implement here any special action that is needed
	 * when the network interface is coming up.
	 */

	return 0;
}

static int virtual_test_interface_stop(const struct device *dev)
{
	struct virtual_test_context *ctx = dev->data;

	if (!ctx->status) {
		return -EALREADY;
	}

	ctx->status = false;

	LOG_DBG("Stopping iface %d", net_if_get_by_iface(ctx->iface));

	/* You can implement here any special action that is needed
	 * when the network interface is going down.
	 */

	return 0;
}

static int virtual_test_interface_send(struct net_if *iface,
				       struct net_pkt *pkt)
{
	struct virtual_test_context *ctx = net_if_get_device(iface)->data;

	if (ctx->attached_to == NULL) {
		return -ENOENT;
	}

	return net_send_data(pkt);
}

static enum net_verdict virtual_test_interface_recv(struct net_if *iface,
						    struct net_pkt *pkt)
{
	ARG_UNUSED(iface);
	ARG_UNUSED(pkt);

	return NET_CONTINUE;
}

static int virtual_test_interface_attach(struct net_if *virtual_iface,
					 struct net_if *iface)
{
	struct virtual_test_context *ctx = net_if_get_device(virtual_iface)->data;

	LOG_INF("This interface %d/%p attached to %d/%p",
		net_if_get_by_iface(virtual_iface), virtual_iface,
		net_if_get_by_iface(iface), iface);

	ctx->attached_to = iface;

	return 0;
}

static const struct virtual_interface_api virtual_test_iface_api = {
	.iface_api.init = virtual_test_iface_init,

	.get_capabilities = virtual_test_get_capabilities,
	.start = virtual_test_interface_start,
	.stop = virtual_test_interface_stop,
	.send = virtual_test_interface_send,
	.recv = virtual_test_interface_recv,
	.attach = virtual_test_interface_attach,
};

NET_VIRTUAL_INTERFACE_INIT(virtual_test1, VIRTUAL_TEST, NULL, NULL,
			   &virtual_test_context_data1,
			   NULL,
			   CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
			   &virtual_test_iface_api,
			   VIRTUAL_TEST_MTU);

NET_VIRTUAL_INTERFACE_INIT(virtual_test2, VIRTUAL_TEST2, NULL, NULL,
			   &virtual_test_context_data2,
			   NULL,
			   CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
			   &virtual_test_iface_api,
			   VIRTUAL_TEST_MTU);

NET_VIRTUAL_INTERFACE_INIT(virtual_test3, VIRTUAL_TEST3, NULL, NULL,
			   &virtual_test_context_data3,
			   NULL,
			   CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
			   &virtual_test_iface_api,
			   VIRTUAL_TEST_MTU);

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

	if ((net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) &&
	    (net_if_l2(iface) != &NET_L2_GET_NAME(VIRTUAL))) {
		return;
	}

	if (!ud->ethernet && net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) {
		ud->ethernet = iface;
		return;
	}

	if (!ud->ipip && net_if_l2(iface) == &NET_L2_GET_NAME(VIRTUAL) &&
	    net_if_get_device(iface) == device_get_binding(ipip_dev_name)) {
		ud->ipip = iface;
		return;
	}

	if (!ud->my_iface && net_if_l2(iface) == &NET_L2_GET_NAME(VIRTUAL) &&
	    net_if_get_device(iface)->data == &virtual_test_context_data1) {
		ud->my_iface = iface;
		return;
	}

	if (!ud->ip_tunnel_1 && net_if_l2(iface) == &NET_L2_GET_NAME(VIRTUAL)) {
		ud->ip_tunnel_1 = iface;
		return;
	}

	if (!ud->ip_tunnel_2 && net_if_l2(iface) == &NET_L2_GET_NAME(VIRTUAL)) {
		ud->ip_tunnel_2 = iface;
		return;
	}
}

static int setup_iface(struct net_if *iface,
		       const char *ipv6_addr,
		       const char *ipv4_addr,
		       const char *peer6addr,
		       const char *peer4addr,
		       const char *netmask)
{
	struct virtual_interface_req_params params = { 0 };
	struct net_if_addr *ifaddr;
	struct in_addr addr4;
	struct in6_addr addr6;
	int ret;

	if (IS_ENABLED(CONFIG_NET_IPV6) &&
	    net_if_flag_is_set(iface, NET_IF_IPV6)) {

		if (net_addr_pton(AF_INET6, ipv6_addr, &addr6)) {
			LOG_ERR("Invalid address: %s", ipv6_addr);
			return -EINVAL;
		}

		ifaddr = net_if_ipv6_addr_add(iface, &addr6,
					      NET_ADDR_MANUAL, 0);
		if (!ifaddr) {
			LOG_ERR("Cannot add %s to interface %p",
				ipv6_addr, iface);
			return -EINVAL;
		}

		if (!peer6addr || *peer6addr == '\0') {
			goto try_ipv4;
		}

		params.family = AF_INET6;

		if (net_addr_pton(AF_INET6, peer6addr, &addr6)) {
			LOG_ERR("Cannot parse peer %s address %s to tunnel",
				"IPv6", peer6addr);
		} else {
			net_ipaddr_copy(&params.peer6addr, &addr6);

			ret = net_mgmt(
				NET_REQUEST_VIRTUAL_INTERFACE_SET_PEER_ADDRESS,
				iface, &params, sizeof(params));
			if (ret < 0 && ret != -ENOTSUP) {
				LOG_ERR("Cannot set peer %s address %s to "
					"interface %d (%d)",
					"IPv6", peer6addr,
					net_if_get_by_iface(iface),
					ret);
			}
		}

		params.mtu = NET_ETH_MTU - sizeof(struct net_ipv6_hdr);

		ret = net_mgmt(NET_REQUEST_VIRTUAL_INTERFACE_SET_MTU,
			       iface, &params, sizeof(params));
		if (ret < 0 && ret != -ENOTSUP) {
			LOG_ERR("Cannot set interface %d MTU to %d (%d)",
				net_if_get_by_iface(iface), params.mtu, ret);
		}
	}

try_ipv4:
	if (IS_ENABLED(CONFIG_NET_IPV4) &&
	    net_if_flag_is_set(iface, NET_IF_IPV4)) {

		if (net_addr_pton(AF_INET, ipv4_addr, &addr4)) {
			LOG_ERR("Invalid address: %s", ipv4_addr);
			return -EINVAL;
		}

		ifaddr = net_if_ipv4_addr_add(iface, &addr4,
					      NET_ADDR_MANUAL, 0);
		if (!ifaddr) {
			LOG_ERR("Cannot add %s to interface %p",
				ipv4_addr, iface);
			return -EINVAL;
		}

		if (netmask) {
			struct in_addr nm;

			if (net_addr_pton(AF_INET, netmask, &nm)) {
				LOG_ERR("Invalid netmask: %s", netmask);
				return -EINVAL;
			}

			net_if_ipv4_set_netmask_by_addr(iface, &addr4, &nm);
		}

		if (!peer4addr || *peer4addr == '\0') {
			goto done;
		}

		params.family = AF_INET;

		if (net_addr_pton(AF_INET, peer4addr, &addr4)) {
			LOG_ERR("Cannot parse peer %s address %s to tunnel",
				"IPv4", peer4addr);
		} else {
			net_ipaddr_copy(&params.peer4addr, &addr4);

			ret = net_mgmt(
				NET_REQUEST_VIRTUAL_INTERFACE_SET_PEER_ADDRESS,
				iface, &params, sizeof(params));
			if (ret < 0 && ret != -ENOTSUP) {
				LOG_ERR("Cannot set peer %s address %s to "
					"interface %d (%d)",
					"IPv4", peer4addr,
					net_if_get_by_iface(iface),
					ret);
			}
		}

		params.mtu = NET_ETH_MTU - sizeof(struct net_ipv4_hdr);

		ret = net_mgmt(NET_REQUEST_VIRTUAL_INTERFACE_SET_MTU,
			       iface, &params,
			       sizeof(struct virtual_interface_req_params));
		if (ret < 0 && ret != -ENOTSUP) {
			LOG_ERR("Cannot set interface %d MTU to %d (%d)",
				net_if_get_by_iface(iface), params.mtu, ret);
		}
	}

done:
	return 0;
}

int main(void)
{
#define MAX_NAME_LEN 32
	char buf[MAX_NAME_LEN];
	struct ud ud;
	int ret;

	LOG_INF("Start application (dev %s/%p)", dev_name,
		device_get_binding(dev_name));

	memset(&ud, 0, sizeof(ud));
	net_if_foreach(iface_cb, &ud);

	LOG_INF("My example tunnel interface %d (%s / %p)",
		net_if_get_by_iface(ud.my_iface),
		net_virtual_get_name(ud.my_iface, buf, sizeof(buf)),
		ud.my_iface);
	LOG_INF("Tunnel interface %d (%s / %p)",
		net_if_get_by_iface(ud.ip_tunnel_1),
		net_virtual_get_name(ud.ip_tunnel_1, buf, sizeof(buf)),
		ud.ip_tunnel_1);
	LOG_INF("Tunnel interface %d (%s / %p)",
		net_if_get_by_iface(ud.ip_tunnel_2),
		net_virtual_get_name(ud.ip_tunnel_2, buf, sizeof(buf)),
		ud.ip_tunnel_2);
	LOG_INF("IPIP interface %d (%p)",
		net_if_get_by_iface(ud.ipip), ud.ipip);
	LOG_INF("Ethernet interface %d (%p)",
		net_if_get_by_iface(ud.ethernet), ud.ethernet);

	/* Attach the network interfaces on top of the Ethernet interface */
	net_virtual_interface_attach(ud.ip_tunnel_1, ud.ethernet);

	/* Attach our example virtual interface on top of the IPv4 one.
	 * This is just an example how to stack the interface on top of
	 * each other.
	 */
	net_virtual_interface_attach(ud.my_iface, ud.ip_tunnel_1);
	net_virtual_interface_attach(ud.my_iface, ud.ip_tunnel_2);

	ret = setup_iface(ud.my_iface,
			  CONFIG_NET_SAMPLE_IFACE3_MY_IPV6_ADDR,
			  CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_ADDR,
			  NULL, NULL,
			  CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_NETMASK);
	if (ret < 0) {
		LOG_ERR("Cannot set IP address to test interface");
	}

	if (ud.ethernet) {
		ret = setup_iface(ud.ethernet,
				  CONFIG_NET_CONFIG_MY_IPV6_ADDR,
				  CONFIG_NET_CONFIG_MY_IPV4_ADDR,
				  NULL, NULL,
				  CONFIG_NET_CONFIG_MY_IPV4_NETMASK);
		if (ret < 0) {
			LOG_ERR("Cannot set IP address to Ethernet interface");
		}
	}

	ret = setup_iface(ud.ipip,
			  CONFIG_NET_SAMPLE_IFACE2_MY_IPV6_ADDR,
			  CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_ADDR,
			  CONFIG_NET_CONFIG_PEER_IPV6_ADDR,
			  CONFIG_NET_CONFIG_PEER_IPV4_ADDR,
			  CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_NETMASK);
	if (ret < 0) {
		LOG_ERR("Cannot set IP address to IPIP tunnel");
	}

	/* This sample application does nothing itself. You can use
	 * net-shell to send ping or UDP/TCP packets for testing
	 * purposes.
	 */
	return 0;
}
