/*
 * Copyright (c) 2015 Intel Corporation
 * Copyright (c) 2017 Linaro Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 *
 * Network loopback interface implementation.
 */

#define LOG_MODULE_NAME netlo
#define LOG_LEVEL CONFIG_NET_LOOPBACK_LOG_LEVEL

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

#include <zephyr/net/net_pkt.h>
#include <zephyr/net_buf.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/loopback.h>

#include <zephyr/net/dummy.h>

/* Allow network tests to control the IP addresses swapping */
#if defined(CONFIG_NET_TEST)
static bool loopback_dont_swap_addresses;

void loopback_enable_address_swap(bool swap_addresses)
{
	loopback_dont_swap_addresses = !swap_addresses;
}
#endif /* CONFIG_NET_TEST */

int loopback_dev_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	return 0;
}

static void loopback_init(struct net_if *iface)
{
	struct net_if_addr *ifaddr;

	/* RFC 7042, s.2.1.1. address to use in documentation */
	net_if_set_link_addr(iface, "\x00\x00\x5e\x00\x53\xff", 6,
			     NET_LINK_DUMMY);

	if (IS_ENABLED(CONFIG_NET_IPV4)) {
		struct in_addr ipv4_loopback = INADDR_LOOPBACK_INIT;
		struct in_addr netmask = { { { 255, 0, 0, 0 } } };

		ifaddr = net_if_ipv4_addr_add(iface, &ipv4_loopback,
					      NET_ADDR_AUTOCONF, 0);
		if (!ifaddr) {
			LOG_ERR("Failed to register IPv4 loopback address");
		}

		net_if_ipv4_set_netmask_by_addr(iface, &ipv4_loopback, &netmask);
	}

	if (IS_ENABLED(CONFIG_NET_IPV6)) {
		struct in6_addr ipv6_loopback = IN6ADDR_LOOPBACK_INIT;

		ifaddr = net_if_ipv6_addr_add(iface, &ipv6_loopback,
					      NET_ADDR_AUTOCONF, 0);
		if (!ifaddr) {
			LOG_ERR("Failed to register IPv6 loopback address");
		}
	}

	if (IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) {
		int ret;

		ret = net_if_set_name(iface, "lo");
		if (ret < 0) {
			LOG_ERR("Failed to set loopback interface name (%d)", ret);
		}
	}
}

#ifdef CONFIG_NET_LOOPBACK_SIMULATE_PACKET_DROP
static float loopback_packet_drop_ratio = 0.0f;
static float loopback_packet_drop_state = 0.0f;
static int loopback_packet_dropped_count;

int loopback_set_packet_drop_ratio(float ratio)
{
	if (ratio < 0.0f || ratio > 1.0f) {
		return -EINVAL;
	}
	loopback_packet_drop_ratio = ratio;
	return 0;
}

int loopback_get_num_dropped_packets(void)
{
	return loopback_packet_dropped_count;
}

#endif

static int loopback_send(const struct device *dev, struct net_pkt *pkt)
{
	struct net_pkt *cloned;
	int res;

	ARG_UNUSED(dev);

#ifdef CONFIG_NET_LOOPBACK_SIMULATE_PACKET_DROP
	/* Drop packets based on the loopback_packet_drop_ratio
	 * a ratio of 0.2 will drop one every 5 packets
	 */
	loopback_packet_drop_state += loopback_packet_drop_ratio;
	if (loopback_packet_drop_state >= 1.0f) {
		/* Administrate we dropped a packet */
		loopback_packet_drop_state -= 1.0f;
		loopback_packet_dropped_count++;
		return 0;
	}
#endif

	if (!pkt->frags) {
		LOG_ERR("No data to send");
		return -ENODATA;
	}

	/* We should simulate normal driver meaning that if the packet is
	 * properly sent (which is always in this driver), then the packet
	 * must be dropped. This is very much needed for TCP packets where
	 * the packet is reference counted in various stages of sending.
	 */
	cloned = net_pkt_rx_clone(pkt, K_MSEC(100));
	if (!cloned) {
		res = -ENOMEM;
		goto out;
	}

	/* We need to swap the IP addresses because otherwise
	 * the packet will be dropped.
	 *
	 * Some of the network tests require that addresses are not swapped so allow
	 * the test to control this remotely.
	 */
	if (!COND_CODE_1(CONFIG_NET_TEST, (loopback_dont_swap_addresses), (false))) {
		if (net_pkt_family(pkt) == AF_INET6) {
			net_ipv6_addr_copy_raw(NET_IPV6_HDR(cloned)->src,
					       NET_IPV6_HDR(pkt)->dst);
			net_ipv6_addr_copy_raw(NET_IPV6_HDR(cloned)->dst,
					       NET_IPV6_HDR(pkt)->src);
		} else {
			net_ipv4_addr_copy_raw(NET_IPV4_HDR(cloned)->src,
					       NET_IPV4_HDR(pkt)->dst);
			net_ipv4_addr_copy_raw(NET_IPV4_HDR(cloned)->dst,
					       NET_IPV4_HDR(pkt)->src);
		}
	}

	res = net_recv_data(net_pkt_iface(cloned), cloned);
	if (res < 0) {
		LOG_ERR("Data receive failed.");
	}

out:
	/* Let the receiving thread run now */
	k_yield();

	return res;
}

static struct dummy_api loopback_api = {
	.iface_api.init = loopback_init,

	.send = loopback_send,
};

NET_DEVICE_INIT(loopback, "lo",
		loopback_dev_init, NULL, NULL, NULL,
		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
		&loopback_api, DUMMY_L2,
		NET_L2_GET_CTX_TYPE(DUMMY_L2), CONFIG_NET_LOOPBACK_MTU);
