// SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2020 Facebook Inc.

#include <linux/debugfs.h>
#include <linux/netdevice.h>
#include <linux/slab.h>
#include <net/udp_tunnel.h>

#include "netdevsim.h"

static int
nsim_udp_tunnel_set_port(struct net_device *dev, unsigned int table,
			 unsigned int entry, struct udp_tunnel_info *ti)
{
	struct netdevsim *ns = netdev_priv(dev);
	int ret;

	ret = -ns->udp_ports.inject_error;
	ns->udp_ports.inject_error = 0;

	if (!ret) {
		if (ns->udp_ports.ports[table][entry]) {
			WARN(1, "entry already in use\n");
			ret = -EBUSY;
		} else {
			ns->udp_ports.ports[table][entry] =
				be16_to_cpu(ti->port) << 16 | ti->type;
		}
	}

	netdev_info(dev, "set [%d, %d] type %d family %d port %d - %d\n",
		    table, entry, ti->type, ti->sa_family, ntohs(ti->port),
		    ret);
	return ret;
}

static int
nsim_udp_tunnel_unset_port(struct net_device *dev, unsigned int table,
			   unsigned int entry, struct udp_tunnel_info *ti)
{
	struct netdevsim *ns = netdev_priv(dev);
	int ret;

	ret = -ns->udp_ports.inject_error;
	ns->udp_ports.inject_error = 0;

	if (!ret) {
		u32 val = be16_to_cpu(ti->port) << 16 | ti->type;

		if (val == ns->udp_ports.ports[table][entry]) {
			ns->udp_ports.ports[table][entry] = 0;
		} else {
			WARN(1, "entry not installed %x vs %x\n",
			     val, ns->udp_ports.ports[table][entry]);
			ret = -ENOENT;
		}
	}

	netdev_info(dev, "unset [%d, %d] type %d family %d port %d - %d\n",
		    table, entry, ti->type, ti->sa_family, ntohs(ti->port),
		    ret);
	return ret;
}

static int
nsim_udp_tunnel_sync_table(struct net_device *dev, unsigned int table)
{
	struct netdevsim *ns = netdev_priv(dev);
	struct udp_tunnel_info ti;
	unsigned int i;
	int ret;

	ret = -ns->udp_ports.inject_error;
	ns->udp_ports.inject_error = 0;

	for (i = 0; i < NSIM_UDP_TUNNEL_N_PORTS; i++) {
		udp_tunnel_nic_get_port(dev, table, i, &ti);
		ns->udp_ports.ports[table][i] =
			be16_to_cpu(ti.port) << 16 | ti.type;
	}

	return ret;
}

static const struct udp_tunnel_nic_info nsim_udp_tunnel_info = {
	.set_port	= nsim_udp_tunnel_set_port,
	.unset_port	= nsim_udp_tunnel_unset_port,
	.sync_table	= nsim_udp_tunnel_sync_table,

	.tables = {
		{
			.n_entries	= NSIM_UDP_TUNNEL_N_PORTS,
			.tunnel_types	= UDP_TUNNEL_TYPE_VXLAN,
		},
		{
			.n_entries	= NSIM_UDP_TUNNEL_N_PORTS,
			.tunnel_types	= UDP_TUNNEL_TYPE_GENEVE |
					  UDP_TUNNEL_TYPE_VXLAN_GPE,
		},
	},
};

static ssize_t
nsim_udp_tunnels_info_reset_write(struct file *file, const char __user *data,
				  size_t count, loff_t *ppos)
{
	struct net_device *dev = file->private_data;
	struct netdevsim *ns = netdev_priv(dev);

	if (dev->reg_state == NETREG_REGISTERED) {
		memset(ns->udp_ports.ports, 0, sizeof(ns->udp_ports.__ports));
		udp_tunnel_nic_reset_ntf(dev);
	}

	return count;
}

static const struct file_operations nsim_udp_tunnels_info_reset_fops = {
	.open = simple_open,
	.write = nsim_udp_tunnels_info_reset_write,
	.llseek = generic_file_llseek,
	.owner = THIS_MODULE,
};

int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev,
				 struct net_device *dev)
{
	struct netdevsim *ns = netdev_priv(dev);
	struct udp_tunnel_nic_info *info;

	if (nsim_dev->udp_ports.shared && nsim_dev->udp_ports.open_only) {
		dev_err(&nsim_dev->nsim_bus_dev->dev,
			"shared can't be used in conjunction with open_only\n");
		return -EINVAL;
	}

	if (!nsim_dev->udp_ports.shared)
		ns->udp_ports.ports = ns->udp_ports.__ports;
	else
		ns->udp_ports.ports = nsim_dev->udp_ports.__ports;

	ns->udp_ports.ddir = debugfs_create_dir("udp_ports",
						ns->nsim_dev_port->ddir);

	debugfs_create_u32("inject_error", 0600, ns->udp_ports.ddir,
			   &ns->udp_ports.inject_error);

	ns->udp_ports.dfs_ports[0].array = ns->udp_ports.ports[0];
	ns->udp_ports.dfs_ports[0].n_elements = NSIM_UDP_TUNNEL_N_PORTS;
	debugfs_create_u32_array("table0", 0400, ns->udp_ports.ddir,
				 &ns->udp_ports.dfs_ports[0]);

	ns->udp_ports.dfs_ports[1].array = ns->udp_ports.ports[1];
	ns->udp_ports.dfs_ports[1].n_elements = NSIM_UDP_TUNNEL_N_PORTS;
	debugfs_create_u32_array("table1", 0400, ns->udp_ports.ddir,
				 &ns->udp_ports.dfs_ports[1]);

	debugfs_create_file("reset", 0200, ns->udp_ports.ddir,
			    dev, &nsim_udp_tunnels_info_reset_fops);

	/* Note: it's not normal to allocate the info struct like this!
	 * Drivers are expected to use a static const one, here we're testing.
	 */
	info = kmemdup(&nsim_udp_tunnel_info, sizeof(nsim_udp_tunnel_info),
		       GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	if (nsim_dev->udp_ports.sync_all) {
		info->set_port = NULL;
		info->unset_port = NULL;
	} else {
		info->sync_table = NULL;
	}

	if (nsim_dev->udp_ports.open_only)
		info->flags |= UDP_TUNNEL_NIC_INFO_OPEN_ONLY;
	if (nsim_dev->udp_ports.ipv4_only)
		info->flags |= UDP_TUNNEL_NIC_INFO_IPV4_ONLY;
	if (nsim_dev->udp_ports.shared)
		info->shared = &nsim_dev->udp_ports.utn_shared;
	if (nsim_dev->udp_ports.static_iana_vxlan)
		info->flags |= UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN;

	dev->udp_tunnel_nic_info = info;
	return 0;
}

void nsim_udp_tunnels_info_destroy(struct net_device *dev)
{
	struct netdevsim *ns = netdev_priv(dev);

	debugfs_remove_recursive(ns->udp_ports.ddir);
	kfree(dev->udp_tunnel_nic_info);
	dev->udp_tunnel_nic_info = NULL;
}

void nsim_udp_tunnels_debugfs_create(struct nsim_dev *nsim_dev)
{
	debugfs_create_bool("udp_ports_sync_all", 0600, nsim_dev->ddir,
			    &nsim_dev->udp_ports.sync_all);
	debugfs_create_bool("udp_ports_open_only", 0600, nsim_dev->ddir,
			    &nsim_dev->udp_ports.open_only);
	debugfs_create_bool("udp_ports_ipv4_only", 0600, nsim_dev->ddir,
			    &nsim_dev->udp_ports.ipv4_only);
	debugfs_create_bool("udp_ports_shared", 0600, nsim_dev->ddir,
			    &nsim_dev->udp_ports.shared);
	debugfs_create_bool("udp_ports_static_iana_vxlan", 0600, nsim_dev->ddir,
			    &nsim_dev->udp_ports.static_iana_vxlan);
}
