// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * DLCI		Implementation of Frame Relay protocol for Linux, according to
 *		RFC 1490.  This generic device provides en/decapsulation for an
 *		underlying hardware driver.  Routes & IPs are assigned to these
 *		interfaces.  Requires 'dlcicfg' program to create usable 
 *		interfaces, the initial one, 'dlci' is for IOCTL use only.
 *
 * Version:	@(#)dlci.c	0.35	4 Jan 1997
 *
 * Author:	Mike McLagan <mike.mclagan@linux.org>
 *
 * Changes:
 *
 *		0.15	Mike Mclagan	Packet freeing, bug in kmalloc call
 *					DLCI_RET handling
 *		0.20	Mike McLagan	More conservative on which packets
 *					are returned for retry and which are
 *					are dropped.  If DLCI_RET_DROP is
 *					returned from the FRAD, the packet is
 *				 	sent back to Linux for re-transmission
 *		0.25	Mike McLagan	Converted to use SIOC IOCTL calls
 *		0.30	Jim Freeman	Fixed to allow IPX traffic
 *		0.35	Michael Elizabeth	Fixed incorrect memcpy_fromfs
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/if_frad.h>
#include <linux/bitops.h>

#include <net/sock.h>

#include <asm/io.h>
#include <asm/dma.h>
#include <linux/uaccess.h>

static const char version[] = "DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org";

static LIST_HEAD(dlci_devs);

static void dlci_setup(struct net_device *);

/* 
 * these encapsulate the RFC 1490 requirements as well as 
 * deal with packet transmission and reception, working with
 * the upper network layers 
 */

static int dlci_header(struct sk_buff *skb, struct net_device *dev, 
		       unsigned short type, const void *daddr,
		       const void *saddr, unsigned len)
{
	struct frhdr		hdr;
	unsigned int		hlen;
	char			*dest;

	hdr.control = FRAD_I_UI;
	switch (type)
	{
		case ETH_P_IP:
			hdr.IP_NLPID = FRAD_P_IP;
			hlen = sizeof(hdr.control) + sizeof(hdr.IP_NLPID);
			break;

		/* feel free to add other types, if necessary */

		default:
			hdr.pad = FRAD_P_PADDING;
			hdr.NLPID = FRAD_P_SNAP;
			memset(hdr.OUI, 0, sizeof(hdr.OUI));
			hdr.PID = htons(type);
			hlen = sizeof(hdr);
			break;
	}

	dest = skb_push(skb, hlen);
	if (!dest)
		return 0;

	memcpy(dest, &hdr, hlen);

	return hlen;
}

static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
{
	struct frhdr		*hdr;
	int					process, header;

	if (!pskb_may_pull(skb, sizeof(*hdr))) {
		netdev_notice(dev, "invalid data no header\n");
		dev->stats.rx_errors++;
		kfree_skb(skb);
		return;
	}

	hdr = (struct frhdr *) skb->data;
	process = 0;
	header = 0;
	skb->dev = dev;

	if (hdr->control != FRAD_I_UI)
	{
		netdev_notice(dev, "Invalid header flag 0x%02X\n",
			      hdr->control);
		dev->stats.rx_errors++;
	}
	else
		switch (hdr->IP_NLPID)
		{
			case FRAD_P_PADDING:
				if (hdr->NLPID != FRAD_P_SNAP)
				{
					netdev_notice(dev, "Unsupported NLPID 0x%02X\n",
						      hdr->NLPID);
					dev->stats.rx_errors++;
					break;
				}
	 
				if (hdr->OUI[0] + hdr->OUI[1] + hdr->OUI[2] != 0)
				{
					netdev_notice(dev, "Unsupported organizationally unique identifier 0x%02X-%02X-%02X\n",
						      hdr->OUI[0],
						      hdr->OUI[1],
						      hdr->OUI[2]);
					dev->stats.rx_errors++;
					break;
				}

				/* at this point, it's an EtherType frame */
				header = sizeof(struct frhdr);
				/* Already in network order ! */
				skb->protocol = hdr->PID;
				process = 1;
				break;

			case FRAD_P_IP:
				header = sizeof(hdr->control) + sizeof(hdr->IP_NLPID);
				skb->protocol = htons(ETH_P_IP);
				process = 1;
				break;

			case FRAD_P_SNAP:
			case FRAD_P_Q933:
			case FRAD_P_CLNP:
				netdev_notice(dev, "Unsupported NLPID 0x%02X\n",
					      hdr->pad);
				dev->stats.rx_errors++;
				break;

			default:
				netdev_notice(dev, "Invalid pad byte 0x%02X\n",
					      hdr->pad);
				dev->stats.rx_errors++;
				break;				
		}

	if (process)
	{
		/* we've set up the protocol, so discard the header */
		skb_reset_mac_header(skb);
		skb_pull(skb, header);
		dev->stats.rx_bytes += skb->len;
		netif_rx(skb);
		dev->stats.rx_packets++;
	}
	else
		dev_kfree_skb(skb);
}

static netdev_tx_t dlci_transmit(struct sk_buff *skb, struct net_device *dev)
{
	struct dlci_local *dlp = netdev_priv(dev);

	if (skb) {
		struct netdev_queue *txq = skb_get_tx_queue(dev, skb);
		netdev_start_xmit(skb, dlp->slave, txq, false);
	}
	return NETDEV_TX_OK;
}

static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, int get)
{
	struct dlci_conf	config;
	struct dlci_local	*dlp;
	struct frad_local	*flp;
	int			err;

	dlp = netdev_priv(dev);

	flp = netdev_priv(dlp->slave);

	if (!get)
	{
		if (copy_from_user(&config, conf, sizeof(struct dlci_conf)))
			return -EFAULT;
		if (config.flags & ~DLCI_VALID_FLAGS)
			return -EINVAL;
		memcpy(&dlp->config, &config, sizeof(struct dlci_conf));
		dlp->configured = 1;
	}

	err = (*flp->dlci_conf)(dlp->slave, dev, get);
	if (err)
		return err;

	if (get)
	{
		if (copy_to_user(conf, &dlp->config, sizeof(struct dlci_conf)))
			return -EFAULT;
	}

	return 0;
}

static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct dlci_local *dlp;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	dlp = netdev_priv(dev);

	switch (cmd)
	{
		case DLCI_GET_SLAVE:
			if (!*(short *)(dev->dev_addr))
				return -EINVAL;

			strncpy(ifr->ifr_slave, dlp->slave->name, sizeof(ifr->ifr_slave));
			break;

		case DLCI_GET_CONF:
		case DLCI_SET_CONF:
			if (!*(short *)(dev->dev_addr))
				return -EINVAL;

			return dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF);

		default: 
			return -EOPNOTSUPP;
	}
	return 0;
}

static int dlci_change_mtu(struct net_device *dev, int new_mtu)
{
	struct dlci_local *dlp = netdev_priv(dev);

	return dev_set_mtu(dlp->slave, new_mtu);
}

static int dlci_open(struct net_device *dev)
{
	struct dlci_local	*dlp;
	struct frad_local	*flp;
	int			err;

	dlp = netdev_priv(dev);

	if (!*(short *)(dev->dev_addr))
		return -EINVAL;

	if (!netif_running(dlp->slave))
		return -ENOTCONN;

	flp = netdev_priv(dlp->slave);
	err = (*flp->activate)(dlp->slave, dev);
	if (err)
		return err;

	netif_start_queue(dev);

	return 0;
}

static int dlci_close(struct net_device *dev)
{
	struct dlci_local	*dlp;
	struct frad_local	*flp;
	int			err;

	netif_stop_queue(dev);

	dlp = netdev_priv(dev);

	flp = netdev_priv(dlp->slave);
	err = (*flp->deactivate)(dlp->slave, dev);

	return 0;
}

static int dlci_add(struct dlci_add *dlci)
{
	struct net_device	*master, *slave;
	struct dlci_local	*dlp;
	struct frad_local	*flp;
	int			err = -EINVAL;


	/* validate slave device */
	slave = dev_get_by_name(&init_net, dlci->devname);
	if (!slave)
		return -ENODEV;

	if (slave->type != ARPHRD_FRAD || netdev_priv(slave) == NULL)
		goto err1;

	/* create device name */
	master = alloc_netdev(sizeof(struct dlci_local), "dlci%d",
			      NET_NAME_UNKNOWN, dlci_setup);
	if (!master) {
		err = -ENOMEM;
		goto err1;
	}

	/* make sure same slave not already registered */
	rtnl_lock();
	list_for_each_entry(dlp, &dlci_devs, list) {
		if (dlp->slave == slave) {
			err = -EBUSY;
			goto err2;
		}
	}

	*(short *)(master->dev_addr) = dlci->dlci;

	dlp = netdev_priv(master);
	dlp->slave = slave;
	dlp->master = master;

	flp = netdev_priv(slave);
	err = (*flp->assoc)(slave, master);
	if (err < 0)
		goto err2;

	err = register_netdevice(master);
	if (err < 0) 
		goto err2;

	strcpy(dlci->devname, master->name);

	list_add(&dlp->list, &dlci_devs);
	rtnl_unlock();

	return 0;

 err2:
	rtnl_unlock();
	free_netdev(master);
 err1:
	dev_put(slave);
	return err;
}

static int dlci_del(struct dlci_add *dlci)
{
	struct dlci_local	*dlp;
	struct frad_local	*flp;
	struct net_device	*master, *slave;
	int			err;
	bool			found = false;

	rtnl_lock();

	/* validate slave device */
	master = __dev_get_by_name(&init_net, dlci->devname);
	if (!master) {
		err = -ENODEV;
		goto out;
	}

	list_for_each_entry(dlp, &dlci_devs, list) {
		if (dlp->master == master) {
			found = true;
			break;
		}
	}
	if (!found) {
		err = -ENODEV;
		goto out;
	}

	if (netif_running(master)) {
		err = -EBUSY;
		goto out;
	}

	dlp = netdev_priv(master);
	slave = dlp->slave;
	flp = netdev_priv(slave);

	err = (*flp->deassoc)(slave, master);
	if (!err) {
		list_del(&dlp->list);

		unregister_netdevice(master);

		dev_put(slave);
	}
out:
	rtnl_unlock();
	return err;
}

static int dlci_ioctl(unsigned int cmd, void __user *arg)
{
	struct dlci_add add;
	int err;
	
	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	if (copy_from_user(&add, arg, sizeof(struct dlci_add)))
		return -EFAULT;

	switch (cmd)
	{
		case SIOCADDDLCI:
			err = dlci_add(&add);

			if (!err)
				if (copy_to_user(arg, &add, sizeof(struct dlci_add)))
					return -EFAULT;
			break;

		case SIOCDELDLCI:
			err = dlci_del(&add);
			break;

		default:
			err = -EINVAL;
	}

	return err;
}

static const struct header_ops dlci_header_ops = {
	.create	= dlci_header,
};

static const struct net_device_ops dlci_netdev_ops = {
	.ndo_open	= dlci_open,
	.ndo_stop	= dlci_close,
	.ndo_do_ioctl	= dlci_dev_ioctl,
	.ndo_start_xmit	= dlci_transmit,
	.ndo_change_mtu	= dlci_change_mtu,
};

static void dlci_setup(struct net_device *dev)
{
	struct dlci_local *dlp = netdev_priv(dev);

	dev->flags		= 0;
	dev->header_ops		= &dlci_header_ops;
	dev->netdev_ops		= &dlci_netdev_ops;
	dev->needs_free_netdev	= true;

	dlp->receive		= dlci_receive;

	dev->type		= ARPHRD_DLCI;
	dev->hard_header_len	= sizeof(struct frhdr);
	dev->addr_len		= sizeof(short);

}

/* if slave is unregistering, then cleanup master */
static int dlci_dev_event(struct notifier_block *unused,
			  unsigned long event, void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);

	if (dev_net(dev) != &init_net)
		return NOTIFY_DONE;

	if (event == NETDEV_UNREGISTER) {
		struct dlci_local *dlp;

		list_for_each_entry(dlp, &dlci_devs, list) {
			if (dlp->slave == dev) {
				list_del(&dlp->list);
				unregister_netdevice(dlp->master);
				dev_put(dlp->slave);
				break;
			}
		}
	}
	return NOTIFY_DONE;
}

static struct notifier_block dlci_notifier = {
	.notifier_call = dlci_dev_event,
};

static int __init init_dlci(void)
{
	dlci_ioctl_set(dlci_ioctl);
	register_netdevice_notifier(&dlci_notifier);

	printk("%s.\n", version);

	return 0;
}

static void __exit dlci_exit(void)
{
	struct dlci_local	*dlp, *nxt;
	
	dlci_ioctl_set(NULL);
	unregister_netdevice_notifier(&dlci_notifier);

	rtnl_lock();
	list_for_each_entry_safe(dlp, nxt, &dlci_devs, list) {
		unregister_netdevice(dlp->master);
		dev_put(dlp->slave);
	}
	rtnl_unlock();
}

module_init(init_dlci);
module_exit(dlci_exit);

MODULE_AUTHOR("Mike McLagan");
MODULE_DESCRIPTION("Frame Relay DLCI layer");
MODULE_LICENSE("GPL");
