162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/* ATM ioctl handling */
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
562306a36Sopenharmony_ci/* 2003 John Levon  <levon@movementarian.org> */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/module.h>
1062306a36Sopenharmony_ci#include <linux/kmod.h>
1162306a36Sopenharmony_ci#include <linux/net.h>		/* struct socket, struct proto_ops */
1262306a36Sopenharmony_ci#include <linux/atm.h>		/* ATM stuff */
1362306a36Sopenharmony_ci#include <linux/atmdev.h>
1462306a36Sopenharmony_ci#include <linux/atmclip.h>	/* CLIP_*ENCAP */
1562306a36Sopenharmony_ci#include <linux/atmarp.h>	/* manifest constants */
1662306a36Sopenharmony_ci#include <linux/capability.h>
1762306a36Sopenharmony_ci#include <linux/sonet.h>	/* for ioctls */
1862306a36Sopenharmony_ci#include <linux/atmsvc.h>
1962306a36Sopenharmony_ci#include <linux/atmmpc.h>
2062306a36Sopenharmony_ci#include <net/atmclip.h>
2162306a36Sopenharmony_ci#include <linux/atmlec.h>
2262306a36Sopenharmony_ci#include <linux/mutex.h>
2362306a36Sopenharmony_ci#include <asm/ioctls.h>
2462306a36Sopenharmony_ci#include <net/compat.h>
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#include "resources.h"
2762306a36Sopenharmony_ci#include "signaling.h"		/* for WAITING and sigd_attach */
2862306a36Sopenharmony_ci#include "common.h"
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistatic DEFINE_MUTEX(ioctl_mutex);
3262306a36Sopenharmony_cistatic LIST_HEAD(ioctl_list);
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_civoid register_atm_ioctl(struct atm_ioctl *ioctl)
3662306a36Sopenharmony_ci{
3762306a36Sopenharmony_ci	mutex_lock(&ioctl_mutex);
3862306a36Sopenharmony_ci	list_add_tail(&ioctl->list, &ioctl_list);
3962306a36Sopenharmony_ci	mutex_unlock(&ioctl_mutex);
4062306a36Sopenharmony_ci}
4162306a36Sopenharmony_ciEXPORT_SYMBOL(register_atm_ioctl);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_civoid deregister_atm_ioctl(struct atm_ioctl *ioctl)
4462306a36Sopenharmony_ci{
4562306a36Sopenharmony_ci	mutex_lock(&ioctl_mutex);
4662306a36Sopenharmony_ci	list_del(&ioctl->list);
4762306a36Sopenharmony_ci	mutex_unlock(&ioctl_mutex);
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ciEXPORT_SYMBOL(deregister_atm_ioctl);
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic int do_vcc_ioctl(struct socket *sock, unsigned int cmd,
5262306a36Sopenharmony_ci			unsigned long arg, int compat)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	struct sock *sk = sock->sk;
5562306a36Sopenharmony_ci	struct atm_vcc *vcc;
5662306a36Sopenharmony_ci	int error;
5762306a36Sopenharmony_ci	struct list_head *pos;
5862306a36Sopenharmony_ci	void __user *argp = (void __user *)arg;
5962306a36Sopenharmony_ci	void __user *buf;
6062306a36Sopenharmony_ci	int __user *len;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	vcc = ATM_SD(sock);
6362306a36Sopenharmony_ci	switch (cmd) {
6462306a36Sopenharmony_ci	case SIOCOUTQ:
6562306a36Sopenharmony_ci		if (sock->state != SS_CONNECTED ||
6662306a36Sopenharmony_ci		    !test_bit(ATM_VF_READY, &vcc->flags)) {
6762306a36Sopenharmony_ci			error =  -EINVAL;
6862306a36Sopenharmony_ci			goto done;
6962306a36Sopenharmony_ci		}
7062306a36Sopenharmony_ci		error = put_user(sk->sk_sndbuf - sk_wmem_alloc_get(sk),
7162306a36Sopenharmony_ci				 (int __user *)argp) ? -EFAULT : 0;
7262306a36Sopenharmony_ci		goto done;
7362306a36Sopenharmony_ci	case SIOCINQ:
7462306a36Sopenharmony_ci	{
7562306a36Sopenharmony_ci		struct sk_buff *skb;
7662306a36Sopenharmony_ci		int amount;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci		if (sock->state != SS_CONNECTED) {
7962306a36Sopenharmony_ci			error = -EINVAL;
8062306a36Sopenharmony_ci			goto done;
8162306a36Sopenharmony_ci		}
8262306a36Sopenharmony_ci		spin_lock_irq(&sk->sk_receive_queue.lock);
8362306a36Sopenharmony_ci		skb = skb_peek(&sk->sk_receive_queue);
8462306a36Sopenharmony_ci		amount = skb ? skb->len : 0;
8562306a36Sopenharmony_ci		spin_unlock_irq(&sk->sk_receive_queue.lock);
8662306a36Sopenharmony_ci		error = put_user(amount, (int __user *)argp) ? -EFAULT : 0;
8762306a36Sopenharmony_ci		goto done;
8862306a36Sopenharmony_ci	}
8962306a36Sopenharmony_ci	case ATM_SETSC:
9062306a36Sopenharmony_ci		net_warn_ratelimited("ATM_SETSC is obsolete; used by %s:%d\n",
9162306a36Sopenharmony_ci				     current->comm, task_pid_nr(current));
9262306a36Sopenharmony_ci		error = 0;
9362306a36Sopenharmony_ci		goto done;
9462306a36Sopenharmony_ci	case ATMSIGD_CTRL:
9562306a36Sopenharmony_ci		if (!capable(CAP_NET_ADMIN)) {
9662306a36Sopenharmony_ci			error = -EPERM;
9762306a36Sopenharmony_ci			goto done;
9862306a36Sopenharmony_ci		}
9962306a36Sopenharmony_ci		/*
10062306a36Sopenharmony_ci		 * The user/kernel protocol for exchanging signalling
10162306a36Sopenharmony_ci		 * info uses kernel pointers as opaque references,
10262306a36Sopenharmony_ci		 * so the holder of the file descriptor can scribble
10362306a36Sopenharmony_ci		 * on the kernel... so we should make sure that we
10462306a36Sopenharmony_ci		 * have the same privileges that /proc/kcore needs
10562306a36Sopenharmony_ci		 */
10662306a36Sopenharmony_ci		if (!capable(CAP_SYS_RAWIO)) {
10762306a36Sopenharmony_ci			error = -EPERM;
10862306a36Sopenharmony_ci			goto done;
10962306a36Sopenharmony_ci		}
11062306a36Sopenharmony_ci#ifdef CONFIG_COMPAT
11162306a36Sopenharmony_ci		/* WTF? I don't even want to _think_ about making this
11262306a36Sopenharmony_ci		   work for 32-bit userspace. TBH I don't really want
11362306a36Sopenharmony_ci		   to think about it at all. dwmw2. */
11462306a36Sopenharmony_ci		if (compat) {
11562306a36Sopenharmony_ci			net_warn_ratelimited("32-bit task cannot be atmsigd\n");
11662306a36Sopenharmony_ci			error = -EINVAL;
11762306a36Sopenharmony_ci			goto done;
11862306a36Sopenharmony_ci		}
11962306a36Sopenharmony_ci#endif
12062306a36Sopenharmony_ci		error = sigd_attach(vcc);
12162306a36Sopenharmony_ci		if (!error)
12262306a36Sopenharmony_ci			sock->state = SS_CONNECTED;
12362306a36Sopenharmony_ci		goto done;
12462306a36Sopenharmony_ci	case ATM_SETBACKEND:
12562306a36Sopenharmony_ci	case ATM_NEWBACKENDIF:
12662306a36Sopenharmony_ci	{
12762306a36Sopenharmony_ci		atm_backend_t backend;
12862306a36Sopenharmony_ci		error = get_user(backend, (atm_backend_t __user *)argp);
12962306a36Sopenharmony_ci		if (error)
13062306a36Sopenharmony_ci			goto done;
13162306a36Sopenharmony_ci		switch (backend) {
13262306a36Sopenharmony_ci		case ATM_BACKEND_PPP:
13362306a36Sopenharmony_ci			request_module("pppoatm");
13462306a36Sopenharmony_ci			break;
13562306a36Sopenharmony_ci		case ATM_BACKEND_BR2684:
13662306a36Sopenharmony_ci			request_module("br2684");
13762306a36Sopenharmony_ci			break;
13862306a36Sopenharmony_ci		}
13962306a36Sopenharmony_ci		break;
14062306a36Sopenharmony_ci	}
14162306a36Sopenharmony_ci	case ATMMPC_CTRL:
14262306a36Sopenharmony_ci	case ATMMPC_DATA:
14362306a36Sopenharmony_ci		request_module("mpoa");
14462306a36Sopenharmony_ci		break;
14562306a36Sopenharmony_ci	case ATMARPD_CTRL:
14662306a36Sopenharmony_ci		request_module("clip");
14762306a36Sopenharmony_ci		break;
14862306a36Sopenharmony_ci	case ATMLEC_CTRL:
14962306a36Sopenharmony_ci		request_module("lec");
15062306a36Sopenharmony_ci		break;
15162306a36Sopenharmony_ci	}
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	error = -ENOIOCTLCMD;
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	mutex_lock(&ioctl_mutex);
15662306a36Sopenharmony_ci	list_for_each(pos, &ioctl_list) {
15762306a36Sopenharmony_ci		struct atm_ioctl *ic = list_entry(pos, struct atm_ioctl, list);
15862306a36Sopenharmony_ci		if (try_module_get(ic->owner)) {
15962306a36Sopenharmony_ci			error = ic->ioctl(sock, cmd, arg);
16062306a36Sopenharmony_ci			module_put(ic->owner);
16162306a36Sopenharmony_ci			if (error != -ENOIOCTLCMD)
16262306a36Sopenharmony_ci				break;
16362306a36Sopenharmony_ci		}
16462306a36Sopenharmony_ci	}
16562306a36Sopenharmony_ci	mutex_unlock(&ioctl_mutex);
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci	if (error != -ENOIOCTLCMD)
16862306a36Sopenharmony_ci		goto done;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	if (cmd == ATM_GETNAMES) {
17162306a36Sopenharmony_ci		if (IS_ENABLED(CONFIG_COMPAT) && compat) {
17262306a36Sopenharmony_ci#ifdef CONFIG_COMPAT
17362306a36Sopenharmony_ci			struct compat_atm_iobuf __user *ciobuf = argp;
17462306a36Sopenharmony_ci			compat_uptr_t cbuf;
17562306a36Sopenharmony_ci			len = &ciobuf->length;
17662306a36Sopenharmony_ci			if (get_user(cbuf, &ciobuf->buffer))
17762306a36Sopenharmony_ci				return -EFAULT;
17862306a36Sopenharmony_ci			buf = compat_ptr(cbuf);
17962306a36Sopenharmony_ci#endif
18062306a36Sopenharmony_ci		} else {
18162306a36Sopenharmony_ci			struct atm_iobuf __user *iobuf = argp;
18262306a36Sopenharmony_ci			len = &iobuf->length;
18362306a36Sopenharmony_ci			if (get_user(buf, &iobuf->buffer))
18462306a36Sopenharmony_ci				return -EFAULT;
18562306a36Sopenharmony_ci		}
18662306a36Sopenharmony_ci		error = atm_getnames(buf, len);
18762306a36Sopenharmony_ci	} else {
18862306a36Sopenharmony_ci		int number;
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci		if (IS_ENABLED(CONFIG_COMPAT) && compat) {
19162306a36Sopenharmony_ci#ifdef CONFIG_COMPAT
19262306a36Sopenharmony_ci			struct compat_atmif_sioc __user *csioc = argp;
19362306a36Sopenharmony_ci			compat_uptr_t carg;
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci			len = &csioc->length;
19662306a36Sopenharmony_ci			if (get_user(carg, &csioc->arg))
19762306a36Sopenharmony_ci				return -EFAULT;
19862306a36Sopenharmony_ci			buf = compat_ptr(carg);
19962306a36Sopenharmony_ci			if (get_user(number, &csioc->number))
20062306a36Sopenharmony_ci				return -EFAULT;
20162306a36Sopenharmony_ci#endif
20262306a36Sopenharmony_ci		} else {
20362306a36Sopenharmony_ci			struct atmif_sioc __user *sioc = argp;
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci			len = &sioc->length;
20662306a36Sopenharmony_ci			if (get_user(buf, &sioc->arg))
20762306a36Sopenharmony_ci				return -EFAULT;
20862306a36Sopenharmony_ci			if (get_user(number, &sioc->number))
20962306a36Sopenharmony_ci				return -EFAULT;
21062306a36Sopenharmony_ci		}
21162306a36Sopenharmony_ci		error = atm_dev_ioctl(cmd, buf, len, number, compat);
21262306a36Sopenharmony_ci	}
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_cidone:
21562306a36Sopenharmony_ci	return error;
21662306a36Sopenharmony_ci}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ciint vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	return do_vcc_ioctl(sock, cmd, arg, 0);
22162306a36Sopenharmony_ci}
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci#ifdef CONFIG_COMPAT
22462306a36Sopenharmony_ci/*
22562306a36Sopenharmony_ci * FIXME:
22662306a36Sopenharmony_ci * The compat_ioctl handling is duplicated, using both these conversion
22762306a36Sopenharmony_ci * routines and the compat argument to the actual handlers. Both
22862306a36Sopenharmony_ci * versions are somewhat incomplete and should be merged, e.g. by
22962306a36Sopenharmony_ci * moving the ioctl number translation into the actual handlers and
23062306a36Sopenharmony_ci * killing the conversion code.
23162306a36Sopenharmony_ci *
23262306a36Sopenharmony_ci * -arnd, November 2009
23362306a36Sopenharmony_ci */
23462306a36Sopenharmony_ci#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct compat_atmif_sioc)
23562306a36Sopenharmony_ci#define ATM_GETNAMES32    _IOW('a', ATMIOC_ITF+3, struct compat_atm_iobuf)
23662306a36Sopenharmony_ci#define ATM_GETTYPE32     _IOW('a', ATMIOC_ITF+4, struct compat_atmif_sioc)
23762306a36Sopenharmony_ci#define ATM_GETESI32	  _IOW('a', ATMIOC_ITF+5, struct compat_atmif_sioc)
23862306a36Sopenharmony_ci#define ATM_GETADDR32	  _IOW('a', ATMIOC_ITF+6, struct compat_atmif_sioc)
23962306a36Sopenharmony_ci#define ATM_RSTADDR32	  _IOW('a', ATMIOC_ITF+7, struct compat_atmif_sioc)
24062306a36Sopenharmony_ci#define ATM_ADDADDR32	  _IOW('a', ATMIOC_ITF+8, struct compat_atmif_sioc)
24162306a36Sopenharmony_ci#define ATM_DELADDR32	  _IOW('a', ATMIOC_ITF+9, struct compat_atmif_sioc)
24262306a36Sopenharmony_ci#define ATM_GETCIRANGE32  _IOW('a', ATMIOC_ITF+10, struct compat_atmif_sioc)
24362306a36Sopenharmony_ci#define ATM_SETCIRANGE32  _IOW('a', ATMIOC_ITF+11, struct compat_atmif_sioc)
24462306a36Sopenharmony_ci#define ATM_SETESI32      _IOW('a', ATMIOC_ITF+12, struct compat_atmif_sioc)
24562306a36Sopenharmony_ci#define ATM_SETESIF32     _IOW('a', ATMIOC_ITF+13, struct compat_atmif_sioc)
24662306a36Sopenharmony_ci#define ATM_GETSTAT32     _IOW('a', ATMIOC_SARCOM+0, struct compat_atmif_sioc)
24762306a36Sopenharmony_ci#define ATM_GETSTATZ32    _IOW('a', ATMIOC_SARCOM+1, struct compat_atmif_sioc)
24862306a36Sopenharmony_ci#define ATM_GETLOOP32	  _IOW('a', ATMIOC_SARCOM+2, struct compat_atmif_sioc)
24962306a36Sopenharmony_ci#define ATM_SETLOOP32	  _IOW('a', ATMIOC_SARCOM+3, struct compat_atmif_sioc)
25062306a36Sopenharmony_ci#define ATM_QUERYLOOP32	  _IOW('a', ATMIOC_SARCOM+4, struct compat_atmif_sioc)
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_cistatic struct {
25362306a36Sopenharmony_ci	unsigned int cmd32;
25462306a36Sopenharmony_ci	unsigned int cmd;
25562306a36Sopenharmony_ci} atm_ioctl_map[] = {
25662306a36Sopenharmony_ci	{ ATM_GETLINKRATE32, ATM_GETLINKRATE },
25762306a36Sopenharmony_ci	{ ATM_GETNAMES32,    ATM_GETNAMES },
25862306a36Sopenharmony_ci	{ ATM_GETTYPE32,     ATM_GETTYPE },
25962306a36Sopenharmony_ci	{ ATM_GETESI32,	     ATM_GETESI },
26062306a36Sopenharmony_ci	{ ATM_GETADDR32,     ATM_GETADDR },
26162306a36Sopenharmony_ci	{ ATM_RSTADDR32,     ATM_RSTADDR },
26262306a36Sopenharmony_ci	{ ATM_ADDADDR32,     ATM_ADDADDR },
26362306a36Sopenharmony_ci	{ ATM_DELADDR32,     ATM_DELADDR },
26462306a36Sopenharmony_ci	{ ATM_GETCIRANGE32,  ATM_GETCIRANGE },
26562306a36Sopenharmony_ci	{ ATM_SETCIRANGE32,  ATM_SETCIRANGE },
26662306a36Sopenharmony_ci	{ ATM_SETESI32,	     ATM_SETESI },
26762306a36Sopenharmony_ci	{ ATM_SETESIF32,     ATM_SETESIF },
26862306a36Sopenharmony_ci	{ ATM_GETSTAT32,     ATM_GETSTAT },
26962306a36Sopenharmony_ci	{ ATM_GETSTATZ32,    ATM_GETSTATZ },
27062306a36Sopenharmony_ci	{ ATM_GETLOOP32,     ATM_GETLOOP },
27162306a36Sopenharmony_ci	{ ATM_SETLOOP32,     ATM_SETLOOP },
27262306a36Sopenharmony_ci	{ ATM_QUERYLOOP32,   ATM_QUERYLOOP },
27362306a36Sopenharmony_ci};
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_cistatic int do_atm_iobuf(struct socket *sock, unsigned int cmd,
27862306a36Sopenharmony_ci			unsigned long arg)
27962306a36Sopenharmony_ci{
28062306a36Sopenharmony_ci	struct compat_atm_iobuf __user *iobuf32 = compat_ptr(arg);
28162306a36Sopenharmony_ci	u32 data;
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	if (get_user(data, &iobuf32->buffer))
28462306a36Sopenharmony_ci		return -EFAULT;
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	return atm_getnames(&iobuf32->length, compat_ptr(data));
28762306a36Sopenharmony_ci}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_cistatic int do_atmif_sioc(struct socket *sock, unsigned int cmd,
29062306a36Sopenharmony_ci			 unsigned long arg)
29162306a36Sopenharmony_ci{
29262306a36Sopenharmony_ci	struct compat_atmif_sioc __user *sioc32 = compat_ptr(arg);
29362306a36Sopenharmony_ci	int number;
29462306a36Sopenharmony_ci	u32 data;
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	if (get_user(data, &sioc32->arg) || get_user(number, &sioc32->number))
29762306a36Sopenharmony_ci		return -EFAULT;
29862306a36Sopenharmony_ci	return atm_dev_ioctl(cmd, compat_ptr(data), &sioc32->length, number, 0);
29962306a36Sopenharmony_ci}
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_cistatic int do_atm_ioctl(struct socket *sock, unsigned int cmd32,
30262306a36Sopenharmony_ci			unsigned long arg)
30362306a36Sopenharmony_ci{
30462306a36Sopenharmony_ci	int i;
30562306a36Sopenharmony_ci	unsigned int cmd = 0;
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci	switch (cmd32) {
30862306a36Sopenharmony_ci	case SONET_GETSTAT:
30962306a36Sopenharmony_ci	case SONET_GETSTATZ:
31062306a36Sopenharmony_ci	case SONET_GETDIAG:
31162306a36Sopenharmony_ci	case SONET_SETDIAG:
31262306a36Sopenharmony_ci	case SONET_CLRDIAG:
31362306a36Sopenharmony_ci	case SONET_SETFRAMING:
31462306a36Sopenharmony_ci	case SONET_GETFRAMING:
31562306a36Sopenharmony_ci	case SONET_GETFRSENSE:
31662306a36Sopenharmony_ci		return do_atmif_sioc(sock, cmd32, arg);
31762306a36Sopenharmony_ci	}
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci	for (i = 0; i < NR_ATM_IOCTL; i++) {
32062306a36Sopenharmony_ci		if (cmd32 == atm_ioctl_map[i].cmd32) {
32162306a36Sopenharmony_ci			cmd = atm_ioctl_map[i].cmd;
32262306a36Sopenharmony_ci			break;
32362306a36Sopenharmony_ci		}
32462306a36Sopenharmony_ci	}
32562306a36Sopenharmony_ci	if (i == NR_ATM_IOCTL)
32662306a36Sopenharmony_ci		return -EINVAL;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	switch (cmd) {
32962306a36Sopenharmony_ci	case ATM_GETNAMES:
33062306a36Sopenharmony_ci		return do_atm_iobuf(sock, cmd, arg);
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci	case ATM_GETLINKRATE:
33362306a36Sopenharmony_ci	case ATM_GETTYPE:
33462306a36Sopenharmony_ci	case ATM_GETESI:
33562306a36Sopenharmony_ci	case ATM_GETADDR:
33662306a36Sopenharmony_ci	case ATM_RSTADDR:
33762306a36Sopenharmony_ci	case ATM_ADDADDR:
33862306a36Sopenharmony_ci	case ATM_DELADDR:
33962306a36Sopenharmony_ci	case ATM_GETCIRANGE:
34062306a36Sopenharmony_ci	case ATM_SETCIRANGE:
34162306a36Sopenharmony_ci	case ATM_SETESI:
34262306a36Sopenharmony_ci	case ATM_SETESIF:
34362306a36Sopenharmony_ci	case ATM_GETSTAT:
34462306a36Sopenharmony_ci	case ATM_GETSTATZ:
34562306a36Sopenharmony_ci	case ATM_GETLOOP:
34662306a36Sopenharmony_ci	case ATM_SETLOOP:
34762306a36Sopenharmony_ci	case ATM_QUERYLOOP:
34862306a36Sopenharmony_ci		return do_atmif_sioc(sock, cmd, arg);
34962306a36Sopenharmony_ci	}
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci	return -EINVAL;
35262306a36Sopenharmony_ci}
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ciint vcc_compat_ioctl(struct socket *sock, unsigned int cmd,
35562306a36Sopenharmony_ci		     unsigned long arg)
35662306a36Sopenharmony_ci{
35762306a36Sopenharmony_ci	int ret;
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	ret = do_vcc_ioctl(sock, cmd, arg, 1);
36062306a36Sopenharmony_ci	if (ret != -ENOIOCTLCMD)
36162306a36Sopenharmony_ci		return ret;
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	return do_atm_ioctl(sock, cmd, arg);
36462306a36Sopenharmony_ci}
36562306a36Sopenharmony_ci#endif
366