// SPDX-License-Identifier: GPL-2.0
/* ATM ioctl handling */

/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
/* 2003 John Levon  <levon@movementarian.org> */

#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__

#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/net.h>		/* struct socket, struct proto_ops */
#include <linux/atm.h>		/* ATM stuff */
#include <linux/atmdev.h>
#include <linux/capability.h>
#include <linux/mutex.h>
#include <asm/ioctls.h>
#include <net/compat.h>

#include "resources.h"
#include "common.h"


static DEFINE_MUTEX(ioctl_mutex);
static LIST_HEAD(ioctl_list);


void register_atm_ioctl(struct atm_ioctl *ioctl)
{
	mutex_lock(&ioctl_mutex);
	list_add_tail(&ioctl->list, &ioctl_list);
	mutex_unlock(&ioctl_mutex);
}
EXPORT_SYMBOL(register_atm_ioctl);

void deregister_atm_ioctl(struct atm_ioctl *ioctl)
{
	mutex_lock(&ioctl_mutex);
	list_del(&ioctl->list);
	mutex_unlock(&ioctl_mutex);
}
EXPORT_SYMBOL(deregister_atm_ioctl);

static int do_vcc_ioctl(struct socket *sock, unsigned int cmd,
			unsigned long arg, int compat)
{
	struct sock *sk = sock->sk;
	struct atm_vcc *vcc;
	int error;
	struct list_head *pos;
	void __user *argp = (void __user *)arg;
	void __user *buf;
	int __user *len;

	vcc = ATM_SD(sock);
	switch (cmd) {
	case SIOCOUTQ:
		if (sock->state != SS_CONNECTED ||
		    !test_bit(ATM_VF_READY, &vcc->flags)) {
			error =  -EINVAL;
			goto done;
		}
		error = put_user(sk->sk_sndbuf - sk_wmem_alloc_get(sk),
				 (int __user *)argp);
		goto done;
	case SIOCINQ:
	{
		struct sk_buff *skb;
		int amount;

		if (sock->state != SS_CONNECTED) {
			error = -EINVAL;
			goto done;
		}
		spin_lock_irq(&sk->sk_receive_queue.lock);
		skb = skb_peek(&sk->sk_receive_queue);
		amount = skb ? skb->len : 0;
		spin_unlock_irq(&sk->sk_receive_queue.lock);
		error = put_user(amount, (int __user *)argp);
		goto done;
	}
	case ATM_SETSC:
		net_warn_ratelimited("ATM_SETSC is obsolete; used by %s:%d\n",
				     current->comm, task_pid_nr(current));
		error = 0;
		goto done;
	case ATM_SETBACKEND:
	case ATM_NEWBACKENDIF:
	{
		atm_backend_t backend;
		error = get_user(backend, (atm_backend_t __user *)argp);
		if (error)
			goto done;
		switch (backend) {
		case ATM_BACKEND_PPP:
			request_module("pppoatm");
			break;
		case ATM_BACKEND_BR2684:
			request_module("br2684");
			break;
		}
		break;
	}
	}

	error = -ENOIOCTLCMD;

	mutex_lock(&ioctl_mutex);
	list_for_each(pos, &ioctl_list) {
		struct atm_ioctl *ic = list_entry(pos, struct atm_ioctl, list);
		if (try_module_get(ic->owner)) {
			error = ic->ioctl(sock, cmd, arg);
			module_put(ic->owner);
			if (error != -ENOIOCTLCMD)
				break;
		}
	}
	mutex_unlock(&ioctl_mutex);

	if (error != -ENOIOCTLCMD)
		goto done;

	if (cmd == ATM_GETNAMES) {
		if (IS_ENABLED(CONFIG_COMPAT) && compat) {
#ifdef CONFIG_COMPAT
			struct compat_atm_iobuf __user *ciobuf = argp;
			compat_uptr_t cbuf;
			len = &ciobuf->length;
			if (get_user(cbuf, &ciobuf->buffer))
				return -EFAULT;
			buf = compat_ptr(cbuf);
#endif
		} else {
			struct atm_iobuf __user *iobuf = argp;
			len = &iobuf->length;
			if (get_user(buf, &iobuf->buffer))
				return -EFAULT;
		}
		error = atm_getnames(buf, len);
	} else {
		int number;

		if (IS_ENABLED(CONFIG_COMPAT) && compat) {
#ifdef CONFIG_COMPAT
			struct compat_atmif_sioc __user *csioc = argp;
			compat_uptr_t carg;

			len = &csioc->length;
			if (get_user(carg, &csioc->arg))
				return -EFAULT;
			buf = compat_ptr(carg);
			if (get_user(number, &csioc->number))
				return -EFAULT;
#endif
		} else {
			struct atmif_sioc __user *sioc = argp;

			len = &sioc->length;
			if (get_user(buf, &sioc->arg))
				return -EFAULT;
			if (get_user(number, &sioc->number))
				return -EFAULT;
		}
		error = atm_dev_ioctl(cmd, buf, len, number, compat);
	}

done:
	return error;
}

int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
	return do_vcc_ioctl(sock, cmd, arg, 0);
}

#ifdef CONFIG_COMPAT
/*
 * FIXME:
 * The compat_ioctl handling is duplicated, using both these conversion
 * routines and the compat argument to the actual handlers. Both
 * versions are somewhat incomplete and should be merged, e.g. by
 * moving the ioctl number translation into the actual handlers and
 * killing the conversion code.
 *
 * -arnd, November 2009
 */
#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct compat_atmif_sioc)
#define ATM_GETNAMES32    _IOW('a', ATMIOC_ITF+3, struct compat_atm_iobuf)
#define ATM_GETTYPE32     _IOW('a', ATMIOC_ITF+4, struct compat_atmif_sioc)
#define ATM_GETESI32	  _IOW('a', ATMIOC_ITF+5, struct compat_atmif_sioc)
#define ATM_GETCIRANGE32  _IOW('a', ATMIOC_ITF+10, struct compat_atmif_sioc)
#define ATM_SETCIRANGE32  _IOW('a', ATMIOC_ITF+11, struct compat_atmif_sioc)
#define ATM_SETESI32      _IOW('a', ATMIOC_ITF+12, struct compat_atmif_sioc)
#define ATM_SETESIF32     _IOW('a', ATMIOC_ITF+13, struct compat_atmif_sioc)
#define ATM_GETSTAT32     _IOW('a', ATMIOC_SARCOM+0, struct compat_atmif_sioc)
#define ATM_GETSTATZ32    _IOW('a', ATMIOC_SARCOM+1, struct compat_atmif_sioc)
#define ATM_GETLOOP32	  _IOW('a', ATMIOC_SARCOM+2, struct compat_atmif_sioc)
#define ATM_SETLOOP32	  _IOW('a', ATMIOC_SARCOM+3, struct compat_atmif_sioc)
#define ATM_QUERYLOOP32	  _IOW('a', ATMIOC_SARCOM+4, struct compat_atmif_sioc)

static struct {
	unsigned int cmd32;
	unsigned int cmd;
} atm_ioctl_map[] = {
	{ ATM_GETLINKRATE32, ATM_GETLINKRATE },
	{ ATM_GETNAMES32,    ATM_GETNAMES },
	{ ATM_GETTYPE32,     ATM_GETTYPE },
	{ ATM_GETESI32,	     ATM_GETESI },
	{ ATM_GETCIRANGE32,  ATM_GETCIRANGE },
	{ ATM_SETCIRANGE32,  ATM_SETCIRANGE },
	{ ATM_SETESI32,	     ATM_SETESI },
	{ ATM_SETESIF32,     ATM_SETESIF },
	{ ATM_GETSTAT32,     ATM_GETSTAT },
	{ ATM_GETSTATZ32,    ATM_GETSTATZ },
	{ ATM_GETLOOP32,     ATM_GETLOOP },
	{ ATM_SETLOOP32,     ATM_SETLOOP },
	{ ATM_QUERYLOOP32,   ATM_QUERYLOOP },
};

#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)

static int do_atm_iobuf(struct socket *sock, unsigned int cmd,
			unsigned long arg)
{
	struct compat_atm_iobuf __user *iobuf32 = compat_ptr(arg);
	u32 data;

	if (get_user(data, &iobuf32->buffer))
		return -EFAULT;

	return atm_getnames(&iobuf32->length, compat_ptr(data));
}

static int do_atmif_sioc(struct socket *sock, unsigned int cmd,
			 unsigned long arg)
{
	struct compat_atmif_sioc __user *sioc32 = compat_ptr(arg);
	int number;
	u32 data;

	if (get_user(data, &sioc32->arg) || get_user(number, &sioc32->number))
		return -EFAULT;
	return atm_dev_ioctl(cmd, compat_ptr(data), &sioc32->length, number, 0);
}

static int do_atm_ioctl(struct socket *sock, unsigned int cmd32,
			unsigned long arg)
{
	int i;
	unsigned int cmd = 0;

	for (i = 0; i < NR_ATM_IOCTL; i++) {
		if (cmd32 == atm_ioctl_map[i].cmd32) {
			cmd = atm_ioctl_map[i].cmd;
			break;
		}
	}
	if (i == NR_ATM_IOCTL)
		return -EINVAL;

	switch (cmd) {
	case ATM_GETNAMES:
		return do_atm_iobuf(sock, cmd, arg);

	case ATM_GETLINKRATE:
	case ATM_GETTYPE:
	case ATM_GETESI:
	case ATM_GETCIRANGE:
	case ATM_SETCIRANGE:
	case ATM_SETESI:
	case ATM_SETESIF:
	case ATM_GETSTAT:
	case ATM_GETSTATZ:
	case ATM_GETLOOP:
	case ATM_SETLOOP:
	case ATM_QUERYLOOP:
		return do_atmif_sioc(sock, cmd, arg);
	}

	return -EINVAL;
}

int vcc_compat_ioctl(struct socket *sock, unsigned int cmd,
		     unsigned long arg)
{
	int ret;

	ret = do_vcc_ioctl(sock, cmd, arg, 1);
	if (ret != -ENOIOCTLCMD)
		return ret;

	return do_atm_ioctl(sock, cmd, arg);
}
#endif
