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