// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
 * James Leu (jleu@mindspring.net).
 * Copyright (C) 2001 by various other people who didn't put their name here.
 */

#include <linux/memblock.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/inetdevice.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/rtnetlink.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <init.h>
#include <irq_kern.h>
#include <irq_user.h>
#include "mconsole_kern.h"
#include <net_kern.h>
#include <net_user.h>

#define DRIVER_NAME "uml-netdev"

static DEFINE_SPINLOCK(opened_lock);
static LIST_HEAD(opened);

/*
 * The drop_skb is used when we can't allocate an skb.  The
 * packet is read into drop_skb in order to get the data off the
 * connection to the host.
 * It is reallocated whenever a maximum packet size is seen which is
 * larger than any seen before.  update_drop_skb is called from
 * eth_configure when a new interface is added.
 */
static DEFINE_SPINLOCK(drop_lock);
static struct sk_buff *drop_skb;
static int drop_max;

static int update_drop_skb(int max)
{
	struct sk_buff *new;
	unsigned long flags;
	int err = 0;

	spin_lock_irqsave(&drop_lock, flags);

	if (max <= drop_max)
		goto out;

	err = -ENOMEM;
	new = dev_alloc_skb(max);
	if (new == NULL)
		goto out;

	skb_put(new, max);

	kfree_skb(drop_skb);
	drop_skb = new;
	drop_max = max;
	err = 0;
out:
	spin_unlock_irqrestore(&drop_lock, flags);

	return err;
}

static int uml_net_rx(struct net_device *dev)
{
	struct uml_net_private *lp = netdev_priv(dev);
	int pkt_len;
	struct sk_buff *skb;

	/* If we can't allocate memory, try again next round. */
	skb = dev_alloc_skb(lp->max_packet);
	if (skb == NULL) {
		drop_skb->dev = dev;
		/* Read a packet into drop_skb and don't do anything with it. */
		(*lp->read)(lp->fd, drop_skb, lp);
		dev->stats.rx_dropped++;
		return 0;
	}

	skb->dev = dev;
	skb_put(skb, lp->max_packet);
	skb_reset_mac_header(skb);
	pkt_len = (*lp->read)(lp->fd, skb, lp);

	if (pkt_len > 0) {
		skb_trim(skb, pkt_len);
		skb->protocol = (*lp->protocol)(skb);

		dev->stats.rx_bytes += skb->len;
		dev->stats.rx_packets++;
		netif_rx(skb);
		return pkt_len;
	}

	kfree_skb(skb);
	return pkt_len;
}

static void uml_dev_close(struct work_struct *work)
{
	struct uml_net_private *lp =
		container_of(work, struct uml_net_private, work);
	dev_close(lp->dev);
}

static irqreturn_t uml_net_interrupt(int irq, void *dev_id)
{
	struct net_device *dev = dev_id;
	struct uml_net_private *lp = netdev_priv(dev);
	int err;

	if (!netif_running(dev))
		return IRQ_NONE;

	spin_lock(&lp->lock);
	while ((err = uml_net_rx(dev)) > 0) ;
	if (err < 0) {
		printk(KERN_ERR
		       "Device '%s' read returned %d, shutting it down\n",
		       dev->name, err);
		/* dev_close can't be called in interrupt context, and takes
		 * again lp->lock.
		 * And dev_close() can be safely called multiple times on the
		 * same device, since it tests for (dev->flags & IFF_UP). So
		 * there's no harm in delaying the device shutdown.
		 * Furthermore, the workqueue will not re-enqueue an already
		 * enqueued work item. */
		schedule_work(&lp->work);
		goto out;
	}
out:
	spin_unlock(&lp->lock);
	return IRQ_HANDLED;
}

static int uml_net_open(struct net_device *dev)
{
	struct uml_net_private *lp = netdev_priv(dev);
	int err;

	if (lp->fd >= 0) {
		err = -ENXIO;
		goto out;
	}

	lp->fd = (*lp->open)(&lp->user);
	if (lp->fd < 0) {
		err = lp->fd;
		goto out;
	}

	err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
			     IRQF_SHARED, dev->name, dev);
	if (err < 0) {
		printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
		err = -ENETUNREACH;
		goto out_close;
	}

	netif_start_queue(dev);

	/* clear buffer - it can happen that the host side of the interface
	 * is full when we get here.  In this case, new data is never queued,
	 * SIGIOs never arrive, and the net never works.
	 */
	while ((err = uml_net_rx(dev)) > 0) ;

	spin_lock(&opened_lock);
	list_add(&lp->list, &opened);
	spin_unlock(&opened_lock);

	return 0;
out_close:
	if (lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
	lp->fd = -1;
out:
	return err;
}

static int uml_net_close(struct net_device *dev)
{
	struct uml_net_private *lp = netdev_priv(dev);

	netif_stop_queue(dev);

	um_free_irq(dev->irq, dev);
	if (lp->close != NULL)
		(*lp->close)(lp->fd, &lp->user);
	lp->fd = -1;

	spin_lock(&opened_lock);
	list_del(&lp->list);
	spin_unlock(&opened_lock);

	return 0;
}

static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct uml_net_private *lp = netdev_priv(dev);
	unsigned long flags;
	int len;

	netif_stop_queue(dev);

	spin_lock_irqsave(&lp->lock, flags);

	len = (*lp->write)(lp->fd, skb, lp);
	skb_tx_timestamp(skb);

	if (len == skb->len) {
		dev->stats.tx_packets++;
		dev->stats.tx_bytes += skb->len;
		netif_trans_update(dev);
		netif_start_queue(dev);

		/* this is normally done in the interrupt when tx finishes */
		netif_wake_queue(dev);
	}
	else if (len == 0) {
		netif_start_queue(dev);
		dev->stats.tx_dropped++;
	}
	else {
		netif_start_queue(dev);
		printk(KERN_ERR "uml_net_start_xmit: failed(%d)\n", len);
	}

	spin_unlock_irqrestore(&lp->lock, flags);

	dev_consume_skb_any(skb);

	return NETDEV_TX_OK;
}

static void uml_net_set_multicast_list(struct net_device *dev)
{
	return;
}

static void uml_net_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
	netif_trans_update(dev);
	netif_wake_queue(dev);
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void uml_net_poll_controller(struct net_device *dev)
{
	disable_irq(dev->irq);
	uml_net_interrupt(dev->irq, dev);
	enable_irq(dev->irq);
}
#endif

static void uml_net_get_drvinfo(struct net_device *dev,
				struct ethtool_drvinfo *info)
{
	strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver));
}

static const struct ethtool_ops uml_net_ethtool_ops = {
	.get_drvinfo	= uml_net_get_drvinfo,
	.get_link	= ethtool_op_get_link,
	.get_ts_info	= ethtool_op_get_ts_info,
};

void uml_net_setup_etheraddr(struct net_device *dev, char *str)
{
	unsigned char *addr = dev->dev_addr;
	char *end;
	int i;

	if (str == NULL)
		goto random;

	for (i = 0; i < 6; i++) {
		addr[i] = simple_strtoul(str, &end, 16);
		if ((end == str) ||
		   ((*end != ':') && (*end != ',') && (*end != '\0'))) {
			printk(KERN_ERR
			       "setup_etheraddr: failed to parse '%s' "
			       "as an ethernet address\n", str);
			goto random;
		}
		str = end + 1;
	}
	if (is_multicast_ether_addr(addr)) {
		printk(KERN_ERR
		       "Attempt to assign a multicast ethernet address to a "
		       "device disallowed\n");
		goto random;
	}
	if (!is_valid_ether_addr(addr)) {
		printk(KERN_ERR
		       "Attempt to assign an invalid ethernet address to a "
		       "device disallowed\n");
		goto random;
	}
	if (!is_local_ether_addr(addr)) {
		printk(KERN_WARNING
		       "Warning: Assigning a globally valid ethernet "
		       "address to a device\n");
		printk(KERN_WARNING "You should set the 2nd rightmost bit in "
		       "the first byte of the MAC,\n");
		printk(KERN_WARNING "i.e. %02x:%02x:%02x:%02x:%02x:%02x\n",
		       addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4],
		       addr[5]);
	}
	return;

random:
	printk(KERN_INFO
	       "Choosing a random ethernet address for device %s\n", dev->name);
	eth_hw_addr_random(dev);
}

static DEFINE_SPINLOCK(devices_lock);
static LIST_HEAD(devices);

static struct platform_driver uml_net_driver = {
	.driver = {
		.name  = DRIVER_NAME,
	},
};

static void net_device_release(struct device *dev)
{
	struct uml_net *device = dev_get_drvdata(dev);
	struct net_device *netdev = device->dev;
	struct uml_net_private *lp = netdev_priv(netdev);

	if (lp->remove != NULL)
		(*lp->remove)(&lp->user);
	list_del(&device->list);
	kfree(device);
	free_netdev(netdev);
}

static const struct net_device_ops uml_netdev_ops = {
	.ndo_open 		= uml_net_open,
	.ndo_stop 		= uml_net_close,
	.ndo_start_xmit 	= uml_net_start_xmit,
	.ndo_set_rx_mode	= uml_net_set_multicast_list,
	.ndo_tx_timeout 	= uml_net_tx_timeout,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller = uml_net_poll_controller,
#endif
};

/*
 * Ensures that platform_driver_register is called only once by
 * eth_configure.  Will be set in an initcall.
 */
static int driver_registered;

static void eth_configure(int n, void *init, char *mac,
			  struct transport *transport, gfp_t gfp_mask)
{
	struct uml_net *device;
	struct net_device *dev;
	struct uml_net_private *lp;
	int err, size;

	size = transport->private_size + sizeof(struct uml_net_private);

	device = kzalloc(sizeof(*device), gfp_mask);
	if (device == NULL) {
		printk(KERN_ERR "eth_configure failed to allocate struct "
		       "uml_net\n");
		return;
	}

	dev = alloc_etherdev(size);
	if (dev == NULL) {
		printk(KERN_ERR "eth_configure: failed to allocate struct "
		       "net_device for eth%d\n", n);
		goto out_free_device;
	}

	INIT_LIST_HEAD(&device->list);
	device->index = n;

	/* If this name ends up conflicting with an existing registered
	 * netdevice, that is OK, register_netdev{,ice}() will notice this
	 * and fail.
	 */
	snprintf(dev->name, sizeof(dev->name), "eth%d", n);

	uml_net_setup_etheraddr(dev, mac);

	printk(KERN_INFO "Netdevice %d (%pM) : ", n, dev->dev_addr);

	lp = netdev_priv(dev);
	/* This points to the transport private data. It's still clear, but we
	 * must memset it to 0 *now*. Let's help the drivers. */
	memset(lp, 0, size);
	INIT_WORK(&lp->work, uml_dev_close);

	/* sysfs register */
	if (!driver_registered) {
		platform_driver_register(&uml_net_driver);
		driver_registered = 1;
	}
	device->pdev.id = n;
	device->pdev.name = DRIVER_NAME;
	device->pdev.dev.release = net_device_release;
	dev_set_drvdata(&device->pdev.dev, device);
	if (platform_device_register(&device->pdev))
		goto out_free_netdev;
	SET_NETDEV_DEV(dev,&device->pdev.dev);

	device->dev = dev;

	/*
	 * These just fill in a data structure, so there's no failure
	 * to be worried about.
	 */
	(*transport->kern->init)(dev, init);

	*lp = ((struct uml_net_private)
		{ .list  		= LIST_HEAD_INIT(lp->list),
		  .dev 			= dev,
		  .fd 			= -1,
		  .mac 			= { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
		  .max_packet		= transport->user->max_packet,
		  .protocol 		= transport->kern->protocol,
		  .open 		= transport->user->open,
		  .close 		= transport->user->close,
		  .remove 		= transport->user->remove,
		  .read 		= transport->kern->read,
		  .write 		= transport->kern->write,
		  .add_address 		= transport->user->add_address,
		  .delete_address  	= transport->user->delete_address });

	spin_lock_init(&lp->lock);
	memcpy(lp->mac, dev->dev_addr, sizeof(lp->mac));

	if ((transport->user->init != NULL) &&
	    ((*transport->user->init)(&lp->user, dev) != 0))
		goto out_unregister;

	dev->mtu = transport->user->mtu;
	dev->netdev_ops = &uml_netdev_ops;
	dev->ethtool_ops = &uml_net_ethtool_ops;
	dev->watchdog_timeo = (HZ >> 1);
	dev->irq = UM_ETH_IRQ;

	err = update_drop_skb(lp->max_packet);
	if (err)
		goto out_undo_user_init;

	rtnl_lock();
	err = register_netdevice(dev);
	rtnl_unlock();
	if (err)
		goto out_undo_user_init;

	spin_lock(&devices_lock);
	list_add(&device->list, &devices);
	spin_unlock(&devices_lock);

	return;

out_undo_user_init:
	if (transport->user->remove != NULL)
		(*transport->user->remove)(&lp->user);
out_unregister:
	platform_device_unregister(&device->pdev);
	return; /* platform_device_unregister frees dev and device */
out_free_netdev:
	free_netdev(dev);
out_free_device:
	kfree(device);
}

static struct uml_net *find_device(int n)
{
	struct uml_net *device;
	struct list_head *ele;

	spin_lock(&devices_lock);
	list_for_each(ele, &devices) {
		device = list_entry(ele, struct uml_net, list);
		if (device->index == n)
			goto out;
	}
	device = NULL;
 out:
	spin_unlock(&devices_lock);
	return device;
}

static int eth_parse(char *str, int *index_out, char **str_out,
		     char **error_out)
{
	char *end;
	int n, err = -EINVAL;

	n = simple_strtoul(str, &end, 0);
	if (end == str) {
		*error_out = "Bad device number";
		return err;
	}

	str = end;
	if (*str != '=') {
		*error_out = "Expected '=' after device number";
		return err;
	}

	str++;
	if (find_device(n)) {
		*error_out = "Device already configured";
		return err;
	}

	*index_out = n;
	*str_out = str;
	return 0;
}

struct eth_init {
	struct list_head list;
	char *init;
	int index;
};

static DEFINE_SPINLOCK(transports_lock);
static LIST_HEAD(transports);

/* Filled in during early boot */
static LIST_HEAD(eth_cmd_line);

static int check_transport(struct transport *transport, char *eth, int n,
			   void **init_out, char **mac_out, gfp_t gfp_mask)
{
	int len;

	len = strlen(transport->name);
	if (strncmp(eth, transport->name, len))
		return 0;

	eth += len;
	if (*eth == ',')
		eth++;
	else if (*eth != '\0')
		return 0;

	*init_out = kmalloc(transport->setup_size, gfp_mask);
	if (*init_out == NULL)
		return 1;

	if (!transport->setup(eth, mac_out, *init_out)) {
		kfree(*init_out);
		*init_out = NULL;
	}
	return 1;
}

void register_transport(struct transport *new)
{
	struct list_head *ele, *next;
	struct eth_init *eth;
	void *init;
	char *mac = NULL;
	int match;

	spin_lock(&transports_lock);
	BUG_ON(!list_empty(&new->list));
	list_add(&new->list, &transports);
	spin_unlock(&transports_lock);

	list_for_each_safe(ele, next, &eth_cmd_line) {
		eth = list_entry(ele, struct eth_init, list);
		match = check_transport(new, eth->init, eth->index, &init,
					&mac, GFP_KERNEL);
		if (!match)
			continue;
		else if (init != NULL) {
			eth_configure(eth->index, init, mac, new, GFP_KERNEL);
			kfree(init);
		}
		list_del(&eth->list);
	}
}

static int eth_setup_common(char *str, int index)
{
	struct list_head *ele;
	struct transport *transport;
	void *init;
	char *mac = NULL;
	int found = 0;

	spin_lock(&transports_lock);
	list_for_each(ele, &transports) {
		transport = list_entry(ele, struct transport, list);
	        if (!check_transport(transport, str, index, &init,
					&mac, GFP_ATOMIC))
			continue;
		if (init != NULL) {
			eth_configure(index, init, mac, transport, GFP_ATOMIC);
			kfree(init);
		}
		found = 1;
		break;
	}

	spin_unlock(&transports_lock);
	return found;
}

static int __init eth_setup(char *str)
{
	struct eth_init *new;
	char *error;
	int n, err;

	err = eth_parse(str, &n, &str, &error);
	if (err) {
		printk(KERN_ERR "eth_setup - Couldn't parse '%s' : %s\n",
		       str, error);
		return 1;
	}

	new = memblock_alloc(sizeof(*new), SMP_CACHE_BYTES);
	if (!new)
		panic("%s: Failed to allocate %zu bytes\n", __func__,
		      sizeof(*new));

	INIT_LIST_HEAD(&new->list);
	new->index = n;
	new->init = str;

	list_add_tail(&new->list, &eth_cmd_line);
	return 1;
}

__setup("eth", eth_setup);
__uml_help(eth_setup,
"eth[0-9]+=<transport>,<options>\n"
"    Configure a network device.\n\n"
);

static int net_config(char *str, char **error_out)
{
	int n, err;

	err = eth_parse(str, &n, &str, error_out);
	if (err)
		return err;

	/* This string is broken up and the pieces used by the underlying
	 * driver.  So, it is freed only if eth_setup_common fails.
	 */
	str = kstrdup(str, GFP_KERNEL);
	if (str == NULL) {
	        *error_out = "net_config failed to strdup string";
		return -ENOMEM;
	}
	err = !eth_setup_common(str, n);
	if (err)
		kfree(str);
	return err;
}

static int net_id(char **str, int *start_out, int *end_out)
{
	char *end;
	int n;

	n = simple_strtoul(*str, &end, 0);
	if ((*end != '\0') || (end == *str))
		return -1;

	*start_out = n;
	*end_out = n;
	*str = end;
	return n;
}

static int net_remove(int n, char **error_out)
{
	struct uml_net *device;
	struct net_device *dev;
	struct uml_net_private *lp;

	device = find_device(n);
	if (device == NULL)
		return -ENODEV;

	dev = device->dev;
	lp = netdev_priv(dev);
	if (lp->fd > 0)
		return -EBUSY;
	unregister_netdev(dev);
	platform_device_unregister(&device->pdev);

	return 0;
}

static struct mc_device net_mc = {
	.list		= LIST_HEAD_INIT(net_mc.list),
	.name		= "eth",
	.config		= net_config,
	.get_config	= NULL,
	.id		= net_id,
	.remove		= net_remove,
};

#ifdef CONFIG_INET
static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
			      void *ptr)
{
	struct in_ifaddr *ifa = ptr;
	struct net_device *dev = ifa->ifa_dev->dev;
	struct uml_net_private *lp;
	void (*proc)(unsigned char *, unsigned char *, void *);
	unsigned char addr_buf[4], netmask_buf[4];

	if (dev->netdev_ops->ndo_open != uml_net_open)
		return NOTIFY_DONE;

	lp = netdev_priv(dev);

	proc = NULL;
	switch (event) {
	case NETDEV_UP:
		proc = lp->add_address;
		break;
	case NETDEV_DOWN:
		proc = lp->delete_address;
		break;
	}
	if (proc != NULL) {
		memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf));
		memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf));
		(*proc)(addr_buf, netmask_buf, &lp->user);
	}
	return NOTIFY_DONE;
}

/* uml_net_init shouldn't be called twice on two CPUs at the same time */
static struct notifier_block uml_inetaddr_notifier = {
	.notifier_call		= uml_inetaddr_event,
};

static void inet_register(void)
{
	struct list_head *ele;
	struct uml_net_private *lp;
	struct in_device *ip;
	struct in_ifaddr *in;

	register_inetaddr_notifier(&uml_inetaddr_notifier);

	/* Devices may have been opened already, so the uml_inetaddr_notifier
	 * didn't get a chance to run for them.  This fakes it so that
	 * addresses which have already been set up get handled properly.
	 */
	spin_lock(&opened_lock);
	list_for_each(ele, &opened) {
		lp = list_entry(ele, struct uml_net_private, list);
		ip = lp->dev->ip_ptr;
		if (ip == NULL)
			continue;
		in = ip->ifa_list;
		while (in != NULL) {
			uml_inetaddr_event(NULL, NETDEV_UP, in);
			in = in->ifa_next;
		}
	}
	spin_unlock(&opened_lock);
}
#else
static inline void inet_register(void)
{
}
#endif

static int uml_net_init(void)
{
	mconsole_register_dev(&net_mc);
	inet_register();
	return 0;
}

__initcall(uml_net_init);

static void close_devices(void)
{
	struct list_head *ele;
	struct uml_net_private *lp;

	spin_lock(&opened_lock);
	list_for_each(ele, &opened) {
		lp = list_entry(ele, struct uml_net_private, list);
		um_free_irq(lp->dev->irq, lp->dev);
		if ((lp->close != NULL) && (lp->fd >= 0))
			(*lp->close)(lp->fd, &lp->user);
		if (lp->remove != NULL)
			(*lp->remove)(&lp->user);
	}
	spin_unlock(&opened_lock);
}

__uml_exitcall(close_devices);

void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
					void *),
		    void *arg)
{
	struct net_device *dev = d;
	struct in_device *ip = dev->ip_ptr;
	struct in_ifaddr *in;
	unsigned char address[4], netmask[4];

	if (ip == NULL) return;
	in = ip->ifa_list;
	while (in != NULL) {
		memcpy(address, &in->ifa_address, sizeof(address));
		memcpy(netmask, &in->ifa_mask, sizeof(netmask));
		(*cb)(address, netmask, arg);
		in = in->ifa_next;
	}
}

int dev_netmask(void *d, void *m)
{
	struct net_device *dev = d;
	struct in_device *ip = dev->ip_ptr;
	struct in_ifaddr *in;
	__be32 *mask_out = m;

	if (ip == NULL)
		return 1;

	in = ip->ifa_list;
	if (in == NULL)
		return 1;

	*mask_out = in->ifa_mask;
	return 0;
}

void *get_output_buffer(int *len_out)
{
	void *ret;

	ret = (void *) __get_free_pages(GFP_KERNEL, 0);
	if (ret) *len_out = PAGE_SIZE;
	else *len_out = 0;
	return ret;
}

void free_output_buffer(void *buffer)
{
	free_pages((unsigned long) buffer, 0);
}

int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out,
		     char **gate_addr)
{
	char *remain;

	remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
	if (remain != NULL) {
		printk(KERN_ERR "tap_setup_common - Extra garbage on "
		       "specification : '%s'\n", remain);
		return 1;
	}

	return 0;
}

unsigned short eth_protocol(struct sk_buff *skb)
{
	return eth_type_trans(skb, skb->dev);
}
