2005-04-17 02:20:36 +04:00
/* ATM ioctl handling */
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
/* 2003 John Levon <levon@movementarian.org> */
2010-01-26 14:40:00 +03:00
# define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
2005-04-17 02:20:36 +04:00
# 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/atmclip.h> /* CLIP_*ENCAP */
# include <linux/atmarp.h> /* manifest constants */
2006-01-11 23:17:47 +03:00
# include <linux/capability.h>
2005-04-17 02:20:36 +04:00
# include <linux/sonet.h> /* for ioctls */
# include <linux/atmsvc.h>
# include <linux/atmmpc.h>
# include <net/atmclip.h>
# include <linux/atmlec.h>
2006-03-21 09:33:17 +03:00
# include <linux/mutex.h>
2005-04-17 02:20:36 +04:00
# include <asm/ioctls.h>
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-12-04 09:12:38 +03:00
# include <net/compat.h>
2005-04-17 02:20:36 +04:00
# include "resources.h"
# include "signaling.h" /* for WAITING and sigd_attach */
2005-09-06 05:04:28 +04:00
# include "common.h"
2005-04-17 02:20:36 +04:00
2006-03-21 09:33:17 +03:00
static DEFINE_MUTEX ( ioctl_mutex ) ;
2005-04-17 02:20:36 +04:00
static LIST_HEAD ( ioctl_list ) ;
void register_atm_ioctl ( struct atm_ioctl * ioctl )
{
2006-03-21 09:33:17 +03:00
mutex_lock ( & ioctl_mutex ) ;
2005-04-17 02:20:36 +04:00
list_add_tail ( & ioctl - > list , & ioctl_list ) ;
2006-03-21 09:33:17 +03:00
mutex_unlock ( & ioctl_mutex ) ;
2005-04-17 02:20:36 +04:00
}
2010-01-26 14:40:07 +03:00
EXPORT_SYMBOL ( register_atm_ioctl ) ;
2005-04-17 02:20:36 +04:00
void deregister_atm_ioctl ( struct atm_ioctl * ioctl )
{
2006-03-21 09:33:17 +03:00
mutex_lock ( & ioctl_mutex ) ;
2005-04-17 02:20:36 +04:00
list_del ( & ioctl - > list ) ;
2006-03-21 09:33:17 +03:00
mutex_unlock ( & ioctl_mutex ) ;
2005-04-17 02:20:36 +04:00
}
EXPORT_SYMBOL ( deregister_atm_ioctl ) ;
2010-01-26 14:40:07 +03:00
static int do_vcc_ioctl ( struct socket * sock , unsigned int cmd ,
unsigned long arg , int compat )
2005-04-17 02:20:36 +04:00
{
struct sock * sk = sock - > sk ;
struct atm_vcc * vcc ;
int error ;
2010-01-26 14:40:07 +03:00
struct list_head * pos ;
2005-04-17 02:20:36 +04:00
void __user * argp = ( void __user * ) arg ;
vcc = ATM_SD ( sock ) ;
switch ( cmd ) {
2010-01-26 14:40:07 +03:00
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 ) ? - EFAULT : 0 ;
goto done ;
case SIOCINQ :
{
struct sk_buff * skb ;
if ( sock - > state ! = SS_CONNECTED ) {
error = - EINVAL ;
2005-04-17 02:20:36 +04:00
goto done ;
2010-01-26 14:40:07 +03:00
}
skb = skb_peek ( & sk - > sk_receive_queue ) ;
error = put_user ( skb ? skb - > len : 0 ,
( int __user * ) argp ) ? - EFAULT : 0 ;
goto done ;
}
case SIOCGSTAMP : /* borrowed from IP */
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-12-04 09:12:38 +03:00
# ifdef CONFIG_COMPAT
2010-01-26 14:40:07 +03:00
if ( compat )
error = compat_sock_get_timestamp ( sk , argp ) ;
else
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-12-04 09:12:38 +03:00
# endif
2010-01-26 14:40:07 +03:00
error = sock_get_timestamp ( sk , argp ) ;
goto done ;
case SIOCGSTAMPNS : /* borrowed from IP */
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-12-04 09:12:38 +03:00
# ifdef CONFIG_COMPAT
2010-01-26 14:40:07 +03:00
if ( compat )
error = compat_sock_get_timestampns ( sk , argp ) ;
else
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-12-04 09:12:38 +03:00
# endif
2010-01-26 14:40:07 +03:00
error = sock_get_timestampns ( sk , argp ) ;
goto done ;
case ATM_SETSC :
2012-05-14 01:56:26 +04:00
net_warn_ratelimited ( " ATM_SETSC is obsolete; used by %s:%d \n " ,
current - > comm , task_pid_nr ( current ) ) ;
2010-01-26 14:40:07 +03:00
error = 0 ;
goto done ;
case ATMSIGD_CTRL :
if ( ! capable ( CAP_NET_ADMIN ) ) {
error = - EPERM ;
2007-03-19 03:33:16 +03:00
goto done ;
2010-01-26 14:40:07 +03:00
}
/*
* The user / kernel protocol for exchanging signalling
* info uses kernel pointers as opaque references ,
* so the holder of the file descriptor can scribble
* on the kernel . . . so we should make sure that we
* have the same privileges that / proc / kcore needs
*/
if ( ! capable ( CAP_SYS_RAWIO ) ) {
error = - EPERM ;
2005-04-17 02:20:36 +04:00
goto done ;
2010-01-26 14:40:07 +03:00
}
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-12-04 09:12:38 +03:00
# ifdef CONFIG_COMPAT
2010-01-26 14:40:07 +03:00
/* WTF? I don't even want to _think_ about making this
work for 32 - bit userspace . TBH I don ' t really want
to think about it at all . dwmw2 . */
if ( compat ) {
2012-05-14 01:56:26 +04:00
net_warn_ratelimited ( " 32-bit task cannot be atmsigd \n " ) ;
2010-01-26 14:40:07 +03:00
error = - EINVAL ;
goto done ;
}
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-12-04 09:12:38 +03:00
# endif
2010-01-26 14:40:07 +03:00
error = sigd_attach ( vcc ) ;
if ( ! error )
sock - > state = SS_CONNECTED ;
goto done ;
case ATM_SETBACKEND :
case ATM_NEWBACKENDIF :
{
atm_backend_t backend ;
error = get_user ( backend , ( atm_backend_t __user * ) argp ) ;
if ( error )
2005-04-17 02:20:36 +04:00
goto done ;
2010-01-26 14:40:07 +03:00
switch ( backend ) {
case ATM_BACKEND_PPP :
request_module ( " pppoatm " ) ;
2005-09-29 03:34:24 +04:00
break ;
2010-01-26 14:40:07 +03:00
case ATM_BACKEND_BR2684 :
request_module ( " br2684 " ) ;
2005-04-17 02:20:36 +04:00
break ;
2010-01-26 14:40:07 +03:00
}
break ;
}
case ATMMPC_CTRL :
case ATMMPC_DATA :
request_module ( " mpoa " ) ;
break ;
case ATMARPD_CTRL :
request_module ( " clip " ) ;
break ;
case ATMLEC_CTRL :
request_module ( " lec " ) ;
break ;
2005-04-17 02:20:36 +04:00
}
error = - ENOIOCTLCMD ;
2006-03-21 09:33:17 +03:00
mutex_lock ( & ioctl_mutex ) ;
2005-04-17 02:20:36 +04:00
list_for_each ( pos , & ioctl_list ) {
2010-01-26 14:40:07 +03:00
struct atm_ioctl * ic = list_entry ( pos , struct atm_ioctl , list ) ;
2005-04-17 02:20:36 +04:00
if ( try_module_get ( ic - > owner ) ) {
error = ic - > ioctl ( sock , cmd , arg ) ;
module_put ( ic - > owner ) ;
if ( error ! = - ENOIOCTLCMD )
break ;
}
}
2006-03-21 09:33:17 +03:00
mutex_unlock ( & ioctl_mutex ) ;
2005-04-17 02:20:36 +04:00
if ( error ! = - ENOIOCTLCMD )
goto done ;
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-12-04 09:12:38 +03:00
error = atm_dev_ioctl ( cmd , argp , compat ) ;
2005-04-17 02:20:36 +04:00
done :
return error ;
}
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-12-04 09:12:38 +03:00
int vcc_ioctl ( struct socket * sock , unsigned int cmd , unsigned long arg )
{
return do_vcc_ioctl ( sock , cmd , arg , 0 ) ;
}
# ifdef CONFIG_COMPAT
2009-11-11 06:45:22 +03:00
/*
* 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_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct compat_atmif_sioc)
# define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct compat_atmif_sioc)
# define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct compat_atmif_sioc)
# define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, 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_GETADDR32 , ATM_GETADDR } ,
{ ATM_RSTADDR32 , ATM_RSTADDR } ,
{ ATM_ADDADDR32 , ATM_ADDADDR } ,
{ ATM_DELADDR32 , ATM_DELADDR } ,
{ 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 atm_iobuf __user * iobuf ;
struct compat_atm_iobuf __user * iobuf32 ;
u32 data ;
void __user * datap ;
int len , err ;
iobuf = compat_alloc_user_space ( sizeof ( * iobuf ) ) ;
iobuf32 = compat_ptr ( arg ) ;
if ( get_user ( len , & iobuf32 - > length ) | |
get_user ( data , & iobuf32 - > buffer ) )
return - EFAULT ;
datap = compat_ptr ( data ) ;
if ( put_user ( len , & iobuf - > length ) | |
put_user ( datap , & iobuf - > buffer ) )
return - EFAULT ;
err = do_vcc_ioctl ( sock , cmd , ( unsigned long ) iobuf , 0 ) ;
if ( ! err ) {
if ( copy_in_user ( & iobuf32 - > length , & iobuf - > length ,
sizeof ( int ) ) )
err = - EFAULT ;
}
return err ;
}
static int do_atmif_sioc ( struct socket * sock , unsigned int cmd ,
unsigned long arg )
{
struct atmif_sioc __user * sioc ;
struct compat_atmif_sioc __user * sioc32 ;
u32 data ;
void __user * datap ;
int err ;
sioc = compat_alloc_user_space ( sizeof ( * sioc ) ) ;
sioc32 = compat_ptr ( arg ) ;
2010-01-26 14:40:07 +03:00
if ( copy_in_user ( & sioc - > number , & sioc32 - > number , 2 * sizeof ( int ) ) | |
get_user ( data , & sioc32 - > arg ) )
2009-11-11 06:45:22 +03:00
return - EFAULT ;
datap = compat_ptr ( data ) ;
if ( put_user ( datap , & sioc - > arg ) )
return - EFAULT ;
err = do_vcc_ioctl ( sock , cmd , ( unsigned long ) sioc , 0 ) ;
if ( ! err ) {
if ( copy_in_user ( & sioc32 - > length , & sioc - > length ,
sizeof ( int ) ) )
err = - EFAULT ;
}
return err ;
}
static int do_atm_ioctl ( struct socket * sock , unsigned int cmd32 ,
unsigned long arg )
{
int i ;
unsigned int cmd = 0 ;
switch ( cmd32 ) {
case SONET_GETSTAT :
case SONET_GETSTATZ :
case SONET_GETDIAG :
case SONET_SETDIAG :
case SONET_CLRDIAG :
case SONET_SETFRAMING :
case SONET_GETFRAMING :
case SONET_GETFRSENSE :
return do_atmif_sioc ( sock , cmd32 , arg ) ;
}
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_GETADDR :
case ATM_RSTADDR :
case ATM_ADDADDR :
case ATM_DELADDR :
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 )
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-12-04 09:12:38 +03:00
{
2009-11-11 06:45:22 +03:00
int ret ;
ret = do_vcc_ioctl ( sock , cmd , arg , 1 ) ;
if ( ret ! = - ENOIOCTLCMD )
return ret ;
return do_atm_ioctl ( sock , cmd , arg ) ;
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-12-04 09:12:38 +03:00
}
# endif