2005-04-16 15:20:36 -07:00
/* ATM ioctl handling */
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
/* 2003 John Levon <levon@movementarian.org> */
# 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 12:17:47 -08:00
# include <linux/capability.h>
2005-04-16 15:20:36 -07: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-20 22:33:17 -08:00
# include <linux/mutex.h>
2005-04-16 15:20:36 -07: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-03 22:12:38 -08:00
# include <net/compat.h>
2005-04-16 15:20:36 -07:00
# include "resources.h"
# include "signaling.h" /* for WAITING and sigd_attach */
2005-09-05 18:04:28 -07:00
# include "common.h"
2005-04-16 15:20:36 -07:00
2006-03-20 22:33:17 -08:00
static DEFINE_MUTEX ( ioctl_mutex ) ;
2005-04-16 15:20:36 -07:00
static LIST_HEAD ( ioctl_list ) ;
void register_atm_ioctl ( struct atm_ioctl * ioctl )
{
2006-03-20 22:33:17 -08:00
mutex_lock ( & ioctl_mutex ) ;
2005-04-16 15:20:36 -07:00
list_add_tail ( & ioctl - > list , & ioctl_list ) ;
2006-03-20 22:33:17 -08:00
mutex_unlock ( & ioctl_mutex ) ;
2005-04-16 15:20:36 -07:00
}
void deregister_atm_ioctl ( struct atm_ioctl * ioctl )
{
2006-03-20 22:33:17 -08:00
mutex_lock ( & ioctl_mutex ) ;
2005-04-16 15:20:36 -07:00
list_del ( & ioctl - > list ) ;
2006-03-20 22:33:17 -08:00
mutex_unlock ( & ioctl_mutex ) ;
2005-04-16 15:20:36 -07:00
}
EXPORT_SYMBOL ( register_atm_ioctl ) ;
EXPORT_SYMBOL ( deregister_atm_ioctl ) ;
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-03 22:12:38 -08:00
static int do_vcc_ioctl ( struct socket * sock , unsigned int cmd , unsigned long arg , int compat )
2005-04-16 15:20:36 -07:00
{
struct sock * sk = sock - > sk ;
struct atm_vcc * vcc ;
int error ;
struct list_head * pos ;
void __user * argp = ( void __user * ) arg ;
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 -
atomic_read ( & sk - > sk_wmem_alloc ) ,
( int __user * ) argp ) ? - EFAULT : 0 ;
goto done ;
case SIOCINQ :
{
struct sk_buff * skb ;
if ( sock - > state ! = SS_CONNECTED ) {
error = - EINVAL ;
goto done ;
}
skb = skb_peek ( & sk - > sk_receive_queue ) ;
error = put_user ( skb ? skb - > len : 0 ,
2007-02-09 23:24:29 +09:00
( int __user * ) argp ) ? - EFAULT : 0 ;
2005-04-16 15:20:36 -07:00
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-03 22:12:38 -08:00
# ifdef CONFIG_COMPAT
if ( compat )
error = compat_sock_get_timestamp ( sk , argp ) ;
else
# endif
error = sock_get_timestamp ( sk , argp ) ;
2005-04-16 15:20:36 -07:00
goto done ;
2007-03-18 17:33:16 -07:00
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-03 22:12:38 -08:00
# ifdef CONFIG_COMPAT
if ( compat )
error = compat_sock_get_timestampns ( sk , argp ) ;
else
# endif
error = sock_get_timestampns ( sk , argp ) ;
2007-03-18 17:33:16 -07:00
goto done ;
2005-04-16 15:20:36 -07:00
case ATM_SETSC :
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-03 22:12:38 -08:00
if ( net_ratelimit ( ) )
printk ( KERN_WARNING " ATM_SETSC is obsolete; used by %s:%d \n " ,
current - > comm , task_pid_nr ( current ) ) ;
2005-04-16 15:20:36 -07:00
error = 0 ;
goto done ;
case ATMSIGD_CTRL :
if ( ! capable ( CAP_NET_ADMIN ) ) {
error = - EPERM ;
goto done ;
}
/*
* 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
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-03 22:12:38 -08:00
* have the same privileges that / proc / kcore needs
2005-04-16 15:20:36 -07:00
*/
if ( ! capable ( CAP_SYS_RAWIO ) ) {
error = - EPERM ;
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-03 22:12:38 -08:00
# ifdef CONFIG_COMPAT
/* 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 ) {
if ( net_ratelimit ( ) )
printk ( KERN_WARNING " 32-bit task cannot be atmsigd \n " ) ;
error = - EINVAL ;
goto done ;
}
# endif
2005-04-16 15:20:36 -07:00
error = sigd_attach ( vcc ) ;
if ( ! error )
sock - > state = SS_CONNECTED ;
goto done ;
2005-09-28 16:34:24 -07:00
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 ;
case ATMMPC_CTRL :
case ATMMPC_DATA :
request_module ( " mpoa " ) ;
break ;
case ATMARPD_CTRL :
request_module ( " clip " ) ;
break ;
case ATMLEC_CTRL :
request_module ( " lec " ) ;
2005-04-16 15:20:36 -07:00
break ;
}
error = - ENOIOCTLCMD ;
2006-03-20 22:33:17 -08:00
mutex_lock ( & ioctl_mutex ) ;
2005-04-16 15:20:36 -07:00
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 ;
}
}
2006-03-20 22:33:17 -08:00
mutex_unlock ( & ioctl_mutex ) ;
2005-04-16 15:20:36 -07: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-03 22:12:38 -08:00
error = atm_dev_ioctl ( cmd , argp , compat ) ;
2005-04-16 15:20:36 -07: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-03 22:12:38 -08:00
int vcc_ioctl ( struct socket * sock , unsigned int cmd , unsigned long arg )
{
return do_vcc_ioctl ( sock , cmd , arg , 0 ) ;
}
# ifdef CONFIG_COMPAT
int vcc_compat_ioctl ( struct socket * sock , unsigned int cmd , unsigned long arg )
{
return do_vcc_ioctl ( sock , cmd , arg , 1 ) ;
}
# endif