aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2009-11-07 02:10:54 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-07 02:10:54 -0500
commit6b96018b28bd93274b4b2a4c633a5d373fda0441 (patch)
treedd6402a6671f1e4d3ac0b930f410e2f2a59930da /net
parent206602217747382488fcae68351673cc9103debc (diff)
compat: move sockios handling to net/socket.c
This removes the original socket compat_ioctl code from fs/compat_ioctl.c and converts the code from the copy in net/socket.c into a single function. We add a few cycles of runtime to compat_sock_ioctl() with the long switch() statement, but gain some cycles in return by simplifying the call chain to get there. Due to better inlining, save 1.5kb of object size in the process, and enable further savings: before: text data bss dec hex filename 13540 18008 2080 33628 835c obj/fs/compat_ioctl.o 14565 636 40 15241 3b89 obj/net/socket.o after: text data bss dec hex filename 8916 15176 2080 26172 663c obj/fs/compat_ioctl.o 20725 636 40 21401 5399 obj/net/socket.o Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/socket.c468
1 files changed, 240 insertions, 228 deletions
diff --git a/net/socket.c b/net/socket.c
index 344bd230b831..901d709a7be0 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -97,6 +97,20 @@
97#include <net/sock.h> 97#include <net/sock.h>
98#include <linux/netfilter.h> 98#include <linux/netfilter.h>
99 99
100#include <linux/if_tun.h>
101#include <linux/ipv6_route.h>
102#include <linux/route.h>
103#include <linux/atmdev.h>
104#include <linux/atmarp.h>
105#include <linux/atmsvc.h>
106#include <linux/atmlec.h>
107#include <linux/atmclip.h>
108#include <linux/atmmpc.h>
109#include <linux/atm_tcp.h>
110#include <linux/sonet.h>
111#include <linux/sockios.h>
112#include <linux/atalk.h>
113
100static int sock_no_open(struct inode *irrelevant, struct file *dontcare); 114static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
101static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, 115static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
102 unsigned long nr_segs, loff_t pos); 116 unsigned long nr_segs, loff_t pos);
@@ -919,6 +933,24 @@ void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
919 933
920EXPORT_SYMBOL(dlci_ioctl_set); 934EXPORT_SYMBOL(dlci_ioctl_set);
921 935
936static long sock_do_ioctl(struct net *net, struct socket *sock,
937 unsigned int cmd, unsigned long arg)
938{
939 int err;
940 void __user *argp = (void __user *)arg;
941
942 err = sock->ops->ioctl(sock, cmd, arg);
943
944 /*
945 * If this ioctl is unknown try to hand it down
946 * to the NIC driver.
947 */
948 if (err == -ENOIOCTLCMD)
949 err = dev_ioctl(net, cmd, argp);
950
951 return err;
952}
953
922/* 954/*
923 * With an ioctl, arg may well be a user mode pointer, but we don't know 955 * With an ioctl, arg may well be a user mode pointer, but we don't know
924 * what to do with it - that's up to the protocol still. 956 * what to do with it - that's up to the protocol still.
@@ -992,14 +1024,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
992 mutex_unlock(&dlci_ioctl_mutex); 1024 mutex_unlock(&dlci_ioctl_mutex);
993 break; 1025 break;
994 default: 1026 default:
995 err = sock->ops->ioctl(sock, cmd, arg); 1027 err = sock_do_ioctl(net, sock, cmd, arg);
996
997 /*
998 * If this ioctl is unknown try to hand it down
999 * to the NIC driver.
1000 */
1001 if (err == -ENOIOCTLCMD)
1002 err = dev_ioctl(net, cmd, argp);
1003 break; 1028 break;
1004 } 1029 }
1005 return err; 1030 return err;
@@ -2459,16 +2484,15 @@ void socket_seq_show(struct seq_file *seq)
2459#endif /* CONFIG_PROC_FS */ 2484#endif /* CONFIG_PROC_FS */
2460 2485
2461#ifdef CONFIG_COMPAT 2486#ifdef CONFIG_COMPAT
2462#if 0 2487static int do_siocgstamp(struct net *net, struct socket *sock,
2463static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg) 2488 unsigned int cmd, struct compat_timeval __user *up)
2464{ 2489{
2465 struct compat_timeval __user *up = compat_ptr(arg);
2466 mm_segment_t old_fs = get_fs(); 2490 mm_segment_t old_fs = get_fs();
2467 struct timeval ktv; 2491 struct timeval ktv;
2468 int err; 2492 int err;
2469 2493
2470 set_fs(KERNEL_DS); 2494 set_fs(KERNEL_DS);
2471 err = sys_ioctl(fd, cmd, (unsigned long)&ktv); 2495 err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
2472 set_fs(old_fs); 2496 set_fs(old_fs);
2473 if (!err) { 2497 if (!err) {
2474 err = put_user(ktv.tv_sec, &up->tv_sec); 2498 err = put_user(ktv.tv_sec, &up->tv_sec);
@@ -2477,15 +2501,15 @@ static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
2477 return err; 2501 return err;
2478} 2502}
2479 2503
2480static int do_siocgstampns(unsigned int fd, unsigned int cmd, unsigned long arg) 2504static int do_siocgstampns(struct net *net, struct socket *sock,
2505 unsigned int cmd, struct compat_timespec __user *up)
2481{ 2506{
2482 struct compat_timespec __user *up = compat_ptr(arg);
2483 mm_segment_t old_fs = get_fs(); 2507 mm_segment_t old_fs = get_fs();
2484 struct timespec kts; 2508 struct timespec kts;
2485 int err; 2509 int err;
2486 2510
2487 set_fs(KERNEL_DS); 2511 set_fs(KERNEL_DS);
2488 err = sys_ioctl(fd, cmd, (unsigned long)&kts); 2512 err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
2489 set_fs(old_fs); 2513 set_fs(old_fs);
2490 if (!err) { 2514 if (!err) {
2491 err = put_user(kts.tv_sec, &up->tv_sec); 2515 err = put_user(kts.tv_sec, &up->tv_sec);
@@ -2494,73 +2518,36 @@ static int do_siocgstampns(unsigned int fd, unsigned int cmd, unsigned long arg)
2494 return err; 2518 return err;
2495} 2519}
2496 2520
2497struct ifmap32 { 2521static int dev_ifname32(struct net *net, struct compat_ifreq __user *uifr32)
2498 compat_ulong_t mem_start;
2499 compat_ulong_t mem_end;
2500 unsigned short base_addr;
2501 unsigned char irq;
2502 unsigned char dma;
2503 unsigned char port;
2504};
2505
2506struct ifreq32 {
2507#define IFHWADDRLEN 6
2508#define IFNAMSIZ 16
2509 union {
2510 char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
2511 } ifr_ifrn;
2512 union {
2513 struct sockaddr ifru_addr;
2514 struct sockaddr ifru_dstaddr;
2515 struct sockaddr ifru_broadaddr;
2516 struct sockaddr ifru_netmask;
2517 struct sockaddr ifru_hwaddr;
2518 short ifru_flags;
2519 compat_int_t ifru_ivalue;
2520 compat_int_t ifru_mtu;
2521 struct ifmap32 ifru_map;
2522 char ifru_slave[IFNAMSIZ]; /* Just fits the size */
2523 char ifru_newname[IFNAMSIZ];
2524 compat_caddr_t ifru_data;
2525 /* XXXX? ifru_settings should be here */
2526 } ifr_ifru;
2527};
2528
2529struct ifconf32 {
2530 compat_int_t ifc_len; /* size of buffer */
2531 compat_caddr_t ifcbuf;
2532};
2533
2534static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
2535{ 2522{
2536 struct ifreq __user *uifr; 2523 struct ifreq __user *uifr;
2537 int err; 2524 int err;
2538 2525
2539 uifr = compat_alloc_user_space(sizeof(struct ifreq)); 2526 uifr = compat_alloc_user_space(sizeof(struct ifreq));
2540 if (copy_in_user(uifr, compat_ptr(arg), sizeof(struct ifreq32))) 2527 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
2541 return -EFAULT; 2528 return -EFAULT;
2542 2529
2543 err = sys_ioctl(fd, SIOCGIFNAME, (unsigned long)uifr); 2530 err = dev_ioctl(net, SIOCGIFNAME, uifr);
2544 if (err) 2531 if (err)
2545 return err; 2532 return err;
2546 2533
2547 if (copy_in_user(compat_ptr(arg), uifr, sizeof(struct ifreq32))) 2534 if (copy_in_user(uifr32, uifr, sizeof(struct compat_ifreq)))
2548 return -EFAULT; 2535 return -EFAULT;
2549 2536
2550 return 0; 2537 return 0;
2551} 2538}
2552 2539
2553static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg) 2540static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
2554{ 2541{
2555 struct ifconf32 ifc32; 2542 struct compat_ifconf ifc32;
2556 struct ifconf ifc; 2543 struct ifconf ifc;
2557 struct ifconf __user *uifc; 2544 struct ifconf __user *uifc;
2558 struct ifreq32 __user *ifr32; 2545 struct compat_ifreq __user *ifr32;
2559 struct ifreq __user *ifr; 2546 struct ifreq __user *ifr;
2560 unsigned int i, j; 2547 unsigned int i, j;
2561 int err; 2548 int err;
2562 2549
2563 if (copy_from_user(&ifc32, compat_ptr(arg), sizeof(struct ifconf32))) 2550 if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
2564 return -EFAULT; 2551 return -EFAULT;
2565 2552
2566 if (ifc32.ifcbuf == 0) { 2553 if (ifc32.ifcbuf == 0) {
@@ -2569,14 +2556,14 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
2569 ifc.ifc_req = NULL; 2556 ifc.ifc_req = NULL;
2570 uifc = compat_alloc_user_space(sizeof(struct ifconf)); 2557 uifc = compat_alloc_user_space(sizeof(struct ifconf));
2571 } else { 2558 } else {
2572 size_t len =((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) * 2559 size_t len =((ifc32.ifc_len / sizeof (struct compat_ifreq)) + 1) *
2573 sizeof (struct ifreq); 2560 sizeof (struct ifreq);
2574 uifc = compat_alloc_user_space(sizeof(struct ifconf) + len); 2561 uifc = compat_alloc_user_space(sizeof(struct ifconf) + len);
2575 ifc.ifc_len = len; 2562 ifc.ifc_len = len;
2576 ifr = ifc.ifc_req = (void __user *)(uifc + 1); 2563 ifr = ifc.ifc_req = (void __user *)(uifc + 1);
2577 ifr32 = compat_ptr(ifc32.ifcbuf); 2564 ifr32 = compat_ptr(ifc32.ifcbuf);
2578 for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) { 2565 for (i = 0; i < ifc32.ifc_len; i += sizeof (struct compat_ifreq)) {
2579 if (copy_in_user(ifr, ifr32, sizeof(struct ifreq32))) 2566 if (copy_in_user(ifr, ifr32, sizeof(struct compat_ifreq)))
2580 return -EFAULT; 2567 return -EFAULT;
2581 ifr++; 2568 ifr++;
2582 ifr32++; 2569 ifr32++;
@@ -2585,7 +2572,7 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
2585 if (copy_to_user(uifc, &ifc, sizeof(struct ifconf))) 2572 if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
2586 return -EFAULT; 2573 return -EFAULT;
2587 2574
2588 err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)uifc); 2575 err = dev_ioctl(net, SIOCGIFCONF, uifc);
2589 if (err) 2576 if (err)
2590 return err; 2577 return err;
2591 2578
@@ -2595,9 +2582,9 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
2595 ifr = ifc.ifc_req; 2582 ifr = ifc.ifc_req;
2596 ifr32 = compat_ptr(ifc32.ifcbuf); 2583 ifr32 = compat_ptr(ifc32.ifcbuf);
2597 for (i = 0, j = 0; 2584 for (i = 0, j = 0;
2598 i + sizeof (struct ifreq32) <= ifc32.ifc_len && j < ifc.ifc_len; 2585 i + sizeof (struct compat_ifreq) <= ifc32.ifc_len && j < ifc.ifc_len;
2599 i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) { 2586 i += sizeof (struct compat_ifreq), j += sizeof (struct ifreq)) {
2600 if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32))) 2587 if (copy_in_user(ifr32, ifr, sizeof (struct compat_ifreq)))
2601 return -EFAULT; 2588 return -EFAULT;
2602 ifr32++; 2589 ifr32++;
2603 ifr++; 2590 ifr++;
@@ -2608,26 +2595,24 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
2608 * a 32-bit one. 2595 * a 32-bit one.
2609 */ 2596 */
2610 i = ifc.ifc_len; 2597 i = ifc.ifc_len;
2611 i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32)); 2598 i = ((i / sizeof(struct ifreq)) * sizeof(struct compat_ifreq));
2612 ifc32.ifc_len = i; 2599 ifc32.ifc_len = i;
2613 } else { 2600 } else {
2614 ifc32.ifc_len = i; 2601 ifc32.ifc_len = i;
2615 } 2602 }
2616 if (copy_to_user(compat_ptr(arg), &ifc32, sizeof(struct ifconf32))) 2603 if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
2617 return -EFAULT; 2604 return -EFAULT;
2618 2605
2619 return 0; 2606 return 0;
2620} 2607}
2621 2608
2622static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 2609static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
2623{ 2610{
2624 struct ifreq __user *ifr; 2611 struct ifreq __user *ifr;
2625 struct ifreq32 __user *ifr32;
2626 u32 data; 2612 u32 data;
2627 void __user *datap; 2613 void __user *datap;
2628 2614
2629 ifr = compat_alloc_user_space(sizeof(*ifr)); 2615 ifr = compat_alloc_user_space(sizeof(*ifr));
2630 ifr32 = compat_ptr(arg);
2631 2616
2632 if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ)) 2617 if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
2633 return -EFAULT; 2618 return -EFAULT;
@@ -2639,14 +2624,14 @@ static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
2639 if (put_user(datap, &ifr->ifr_ifru.ifru_data)) 2624 if (put_user(datap, &ifr->ifr_ifru.ifru_data))
2640 return -EFAULT; 2625 return -EFAULT;
2641 2626
2642 return sys_ioctl(fd, cmd, (unsigned long) ifr); 2627 return dev_ioctl(net, SIOCETHTOOL, ifr);
2643} 2628}
2644 2629
2645static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 2630static int bond_ioctl(struct net *net, unsigned int cmd,
2631 struct compat_ifreq __user *ifr32)
2646{ 2632{
2647 struct ifreq kifr; 2633 struct ifreq kifr;
2648 struct ifreq __user *uifr; 2634 struct ifreq __user *uifr;
2649 struct ifreq32 __user *ifr32 = compat_ptr(arg);
2650 mm_segment_t old_fs; 2635 mm_segment_t old_fs;
2651 int err; 2636 int err;
2652 u32 data; 2637 u32 data;
@@ -2657,12 +2642,12 @@ static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
2657 case SIOCBONDRELEASE: 2642 case SIOCBONDRELEASE:
2658 case SIOCBONDSETHWADDR: 2643 case SIOCBONDSETHWADDR:
2659 case SIOCBONDCHANGEACTIVE: 2644 case SIOCBONDCHANGEACTIVE:
2660 if (copy_from_user(&kifr, ifr32, sizeof(struct ifreq32))) 2645 if (copy_from_user(&kifr, ifr32, sizeof(struct compat_ifreq)))
2661 return -EFAULT; 2646 return -EFAULT;
2662 2647
2663 old_fs = get_fs(); 2648 old_fs = get_fs();
2664 set_fs (KERNEL_DS); 2649 set_fs (KERNEL_DS);
2665 err = sys_ioctl (fd, cmd, (unsigned long)&kifr); 2650 err = dev_ioctl(net, cmd, &kifr);
2666 set_fs (old_fs); 2651 set_fs (old_fs);
2667 2652
2668 return err; 2653 return err;
@@ -2679,16 +2664,16 @@ static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
2679 if (put_user(datap, &uifr->ifr_ifru.ifru_data)) 2664 if (put_user(datap, &uifr->ifr_ifru.ifru_data))
2680 return -EFAULT; 2665 return -EFAULT;
2681 2666
2682 return sys_ioctl (fd, cmd, (unsigned long)uifr); 2667 return dev_ioctl(net, cmd, uifr);
2683 default: 2668 default:
2684 return -EINVAL; 2669 return -EINVAL;
2685 }; 2670 };
2686} 2671}
2687 2672
2688static int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 2673static int siocdevprivate_ioctl(struct net *net, unsigned int cmd,
2674 struct compat_ifreq __user *u_ifreq32)
2689{ 2675{
2690 struct ifreq __user *u_ifreq64; 2676 struct ifreq __user *u_ifreq64;
2691 struct ifreq32 __user *u_ifreq32 = compat_ptr(arg);
2692 char tmp_buf[IFNAMSIZ]; 2677 char tmp_buf[IFNAMSIZ];
2693 void __user *data64; 2678 void __user *data64;
2694 u32 data32; 2679 u32 data32;
@@ -2711,18 +2696,17 @@ static int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long
2711 if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data)) 2696 if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
2712 return -EFAULT; 2697 return -EFAULT;
2713 2698
2714 return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64); 2699 return dev_ioctl(net, cmd, u_ifreq64);
2715} 2700}
2716 2701
2717static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg) 2702static int dev_ifsioc(struct net *net, struct socket *sock,
2703 unsigned int cmd, struct compat_ifreq __user *uifr32)
2718{ 2704{
2719 struct ifreq ifr; 2705 struct ifreq ifr;
2720 struct ifreq32 __user *uifr32; 2706 struct compat_ifmap __user *uifmap32;
2721 struct ifmap32 __user *uifmap32;
2722 mm_segment_t old_fs; 2707 mm_segment_t old_fs;
2723 int err; 2708 int err;
2724 2709
2725 uifr32 = compat_ptr(arg);
2726 uifmap32 = &uifr32->ifr_ifru.ifru_map; 2710 uifmap32 = &uifr32->ifr_ifru.ifru_map;
2727 switch (cmd) { 2711 switch (cmd) {
2728 case SIOCSIFMAP: 2712 case SIOCSIFMAP:
@@ -2748,7 +2732,7 @@ static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
2748 } 2732 }
2749 old_fs = get_fs(); 2733 old_fs = get_fs();
2750 set_fs (KERNEL_DS); 2734 set_fs (KERNEL_DS);
2751 err = sys_ioctl (fd, cmd, (unsigned long)&ifr); 2735 err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ifr);
2752 set_fs (old_fs); 2736 set_fs (old_fs);
2753 if (!err) { 2737 if (!err) {
2754 switch (cmd) { 2738 switch (cmd) {
@@ -2813,7 +2797,8 @@ struct in6_rtmsg32 {
2813 s32 rtmsg_ifindex; 2797 s32 rtmsg_ifindex;
2814}; 2798};
2815 2799
2816static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 2800static int routing_ioctl(struct net *net, struct socket *sock,
2801 unsigned int cmd, void __user *argp)
2817{ 2802{
2818 int ret; 2803 int ret;
2819 void *r = NULL; 2804 void *r = NULL;
@@ -2823,10 +2808,8 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
2823 u32 rtdev; 2808 u32 rtdev;
2824 mm_segment_t old_fs = get_fs(); 2809 mm_segment_t old_fs = get_fs();
2825 2810
2826 struct socket *mysock = sockfd_lookup(fd, &ret); 2811 if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */
2827 2812 struct in6_rtmsg32 __user *ur6 = argp;
2828 if (mysock && mysock->sk && mysock->sk->sk_family == AF_INET6) { /* ipv6 */
2829 struct in6_rtmsg32 __user *ur6 = compat_ptr(arg);
2830 ret = copy_from_user (&r6.rtmsg_dst, &(ur6->rtmsg_dst), 2813 ret = copy_from_user (&r6.rtmsg_dst, &(ur6->rtmsg_dst),
2831 3 * sizeof(struct in6_addr)); 2814 3 * sizeof(struct in6_addr));
2832 ret |= __get_user (r6.rtmsg_type, &(ur6->rtmsg_type)); 2815 ret |= __get_user (r6.rtmsg_type, &(ur6->rtmsg_type));
@@ -2839,7 +2822,7 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
2839 2822
2840 r = (void *) &r6; 2823 r = (void *) &r6;
2841 } else { /* ipv4 */ 2824 } else { /* ipv4 */
2842 struct rtentry32 __user *ur4 = compat_ptr(arg); 2825 struct rtentry32 __user *ur4 = argp;
2843 ret = copy_from_user (&r4.rt_dst, &(ur4->rt_dst), 2826 ret = copy_from_user (&r4.rt_dst, &(ur4->rt_dst),
2844 3 * sizeof(struct sockaddr)); 2827 3 * sizeof(struct sockaddr));
2845 ret |= __get_user (r4.rt_flags, &(ur4->rt_flags)); 2828 ret |= __get_user (r4.rt_flags, &(ur4->rt_flags));
@@ -2863,13 +2846,10 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
2863 } 2846 }
2864 2847
2865 set_fs (KERNEL_DS); 2848 set_fs (KERNEL_DS);
2866 ret = sys_ioctl (fd, cmd, (unsigned long) r); 2849 ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r);
2867 set_fs (old_fs); 2850 set_fs (old_fs);
2868 2851
2869out: 2852out:
2870 if (mysock)
2871 sockfd_put(mysock);
2872
2873 return ret; 2853 return ret;
2874} 2854}
2875 2855
@@ -2877,11 +2857,11 @@ out:
2877 * for some operations; this forces use of the newer bridge-utils that 2857 * for some operations; this forces use of the newer bridge-utils that
2878 * use compatiable ioctls 2858 * use compatiable ioctls
2879 */ 2859 */
2880static int old_bridge_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 2860static int old_bridge_ioctl(compat_ulong_t __user *argp)
2881{ 2861{
2882 u32 tmp; 2862 compat_ulong_t tmp;
2883 2863
2884 if (get_user(tmp, (u32 __user *) arg)) 2864 if (get_user(tmp, argp))
2885 return -EFAULT; 2865 return -EFAULT;
2886 if (tmp == BRCTL_GET_VERSION) 2866 if (tmp == BRCTL_GET_VERSION)
2887 return BRCTL_VERSION + 1; 2867 return BRCTL_VERSION + 1;
@@ -2942,7 +2922,8 @@ static struct {
2942 2922
2943#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map) 2923#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)
2944 2924
2945static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg) 2925static int do_atm_iobuf(struct net *net, struct socket *sock,
2926 unsigned int cmd, unsigned long arg)
2946{ 2927{
2947 struct atm_iobuf __user *iobuf; 2928 struct atm_iobuf __user *iobuf;
2948 struct atm_iobuf32 __user *iobuf32; 2929 struct atm_iobuf32 __user *iobuf32;
@@ -2961,7 +2942,7 @@ static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
2961 put_user(datap, &iobuf->buffer)) 2942 put_user(datap, &iobuf->buffer))
2962 return -EFAULT; 2943 return -EFAULT;
2963 2944
2964 err = sys_ioctl(fd, cmd, (unsigned long)iobuf); 2945 err = sock_do_ioctl(net, sock, cmd, (unsigned long)iobuf);
2965 2946
2966 if (!err) { 2947 if (!err) {
2967 if (copy_in_user(&iobuf32->length, &iobuf->length, 2948 if (copy_in_user(&iobuf32->length, &iobuf->length,
@@ -2972,7 +2953,8 @@ static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
2972 return err; 2953 return err;
2973} 2954}
2974 2955
2975static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg) 2956static int do_atmif_sioc(struct net *net, struct socket *sock,
2957 unsigned int cmd, unsigned long arg)
2976{ 2958{
2977 struct atmif_sioc __user *sioc; 2959 struct atmif_sioc __user *sioc;
2978 struct atmif_sioc32 __user *sioc32; 2960 struct atmif_sioc32 __user *sioc32;
@@ -2990,7 +2972,7 @@ static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
2990 if (put_user(datap, &sioc->arg)) 2972 if (put_user(datap, &sioc->arg))
2991 return -EFAULT; 2973 return -EFAULT;
2992 2974
2993 err = sys_ioctl(fd, cmd, (unsigned long) sioc); 2975 err = sock_do_ioctl(net, sock, cmd, (unsigned long) sioc);
2994 2976
2995 if (!err) { 2977 if (!err) {
2996 if (copy_in_user(&sioc32->length, &sioc->length, 2978 if (copy_in_user(&sioc32->length, &sioc->length,
@@ -3000,7 +2982,8 @@ static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
3000 return err; 2982 return err;
3001} 2983}
3002 2984
3003static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg) 2985static int do_atm_ioctl(struct net *net, struct socket *sock,
2986 unsigned int cmd32, unsigned long arg)
3004{ 2987{
3005 int i; 2988 int i;
3006 unsigned int cmd = 0; 2989 unsigned int cmd = 0;
@@ -3014,7 +2997,7 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
3014 case SONET_SETFRAMING: 2997 case SONET_SETFRAMING:
3015 case SONET_GETFRAMING: 2998 case SONET_GETFRAMING:
3016 case SONET_GETFRSENSE: 2999 case SONET_GETFRSENSE:
3017 return do_atmif_sioc(fd, cmd32, arg); 3000 return do_atmif_sioc(net, sock, cmd32, arg);
3018 } 3001 }
3019 3002
3020 for (i = 0; i < NR_ATM_IOCTL; i++) { 3003 for (i = 0; i < NR_ATM_IOCTL; i++) {
@@ -3028,7 +3011,7 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
3028 3011
3029 switch (cmd) { 3012 switch (cmd) {
3030 case ATM_GETNAMES: 3013 case ATM_GETNAMES:
3031 return do_atm_iobuf(fd, cmd, arg); 3014 return do_atm_iobuf(net, sock, cmd, arg);
3032 3015
3033 case ATM_GETLINKRATE: 3016 case ATM_GETLINKRATE:
3034 case ATM_GETTYPE: 3017 case ATM_GETTYPE:
@@ -3046,134 +3029,160 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
3046 case ATM_GETLOOP: 3029 case ATM_GETLOOP:
3047 case ATM_SETLOOP: 3030 case ATM_SETLOOP:
3048 case ATM_QUERYLOOP: 3031 case ATM_QUERYLOOP:
3049 return do_atmif_sioc(fd, cmd, arg); 3032 return do_atmif_sioc(net, sock, cmd, arg);
3050 } 3033 }
3051 3034
3052 return -EINVAL; 3035 return -EINVAL;
3053} 3036}
3054 3037
3038static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3039 unsigned int cmd, unsigned long arg)
3040{
3041 void __user *argp = compat_ptr(arg);
3042 struct sock *sk = sock->sk;
3043 struct net *net = sock_net(sk);
3055 3044
3056/* bridge */ 3045 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
3057HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) 3046 return siocdevprivate_ioctl(net, cmd, argp);
3058HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl) 3047
3059#ifdef CONFIG_NET 3048 switch (cmd) {
3060HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32) 3049 case SIOCSIFBR:
3061HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf) 3050 case SIOCGIFBR:
3062HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc) 3051 return old_bridge_ioctl(argp);
3063HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc) 3052 case SIOCGIFNAME:
3064HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc) 3053 return dev_ifname32(net, argp);
3065HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc) 3054 case SIOCGIFCONF:
3066HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc) 3055 return dev_ifconf(net, argp);
3067HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc) 3056 case SIOCETHTOOL:
3068HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc) 3057 return ethtool_ioctl(net, argp);
3069HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc) 3058 case SIOCBONDENSLAVE:
3070HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc) 3059 case SIOCBONDRELEASE:
3071HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc) 3060 case SIOCBONDSETHWADDR:
3072HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc) 3061 case SIOCBONDSLAVEINFOQUERY:
3073HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc) 3062 case SIOCBONDINFOQUERY:
3074HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc) 3063 case SIOCBONDCHANGEACTIVE:
3075HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc) 3064 return bond_ioctl(net, cmd, argp);
3076HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc) 3065 case SIOCADDRT:
3077HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc) 3066 case SIOCDELRT:
3078HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc) 3067 return routing_ioctl(net, sock, cmd, argp);
3079HANDLE_IOCTL(SIOCSIFHWBROADCAST, dev_ifsioc) 3068 case SIOCGSTAMP:
3080HANDLE_IOCTL(SIOCSHWTSTAMP, dev_ifsioc) 3069 return do_siocgstamp(net, sock, cmd, argp);
3081 3070 case SIOCGSTAMPNS:
3082HANDLE_IOCTL(SIOCDIFADDR, dev_ifsioc) 3071 return do_siocgstampns(net, sock, cmd, argp);
3083HANDLE_IOCTL(SIOCSARP, dev_ifsioc) 3072/* Note SIOCRTMSG is no longer, so this is safe and
3084HANDLE_IOCTL(SIOCDARP, dev_ifsioc) 3073 * the user would have seen just an -EINVAL anyways. */
3085 3074 case SIOCRTMSG:
3086HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc) 3075 case SIOCGIFCOUNT:
3087HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc) 3076 return -EINVAL;
3088HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc) 3077
3089HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc) 3078 case FIOSETOWN:
3090HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc) 3079 case SIOCSPGRP:
3091HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc) 3080 case FIOGETOWN:
3092HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc) 3081 case SIOCGPGRP:
3093HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc) 3082 case SIOCBRADDBR:
3094HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc) 3083 case SIOCBRDELBR:
3095HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc) 3084 case SIOCGIFVLAN:
3096HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl) 3085 case SIOCSIFVLAN:
3097HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl) 3086 case SIOCADDDLCI:
3098HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl) 3087 case SIOCDELDLCI:
3099HANDLE_IOCTL(SIOCBONDSETHWADDR, bond_ioctl) 3088 return sock_ioctl(file, cmd, arg);
3100HANDLE_IOCTL(SIOCBONDSLAVEINFOQUERY, bond_ioctl) 3089
3101HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl) 3090 case SIOCGIFFLAGS:
3102HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl) 3091 case SIOCSIFFLAGS:
3103HANDLE_IOCTL(SIOCADDRT, routing_ioctl) 3092 case SIOCGIFMETRIC:
3104HANDLE_IOCTL(SIOCDELRT, routing_ioctl) 3093 case SIOCSIFMETRIC:
3105HANDLE_IOCTL(SIOCBRADDIF, dev_ifsioc) 3094 case SIOCGIFMTU:
3106HANDLE_IOCTL(SIOCBRDELIF, dev_ifsioc) 3095 case SIOCSIFMTU:
3107/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */ 3096 case SIOCGIFMEM:
3108HANDLE_IOCTL(SIOCRTMSG, ret_einval) 3097 case SIOCSIFMEM:
3109HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp) 3098 case SIOCGIFHWADDR:
3110HANDLE_IOCTL(SIOCGSTAMPNS, do_siocgstampns) 3099 case SIOCSIFHWADDR:
3111#endif 3100 case SIOCADDMULTI:
3112IGNORE_IOCTL(SIOCGIFCOUNT) 3101 case SIOCDELMULTI:
3113/* Little a */ 3102 case SIOCGIFINDEX:
3114COMPATIBLE_IOCTL(ATMSIGD_CTRL) 3103 case SIOCGIFMAP:
3115COMPATIBLE_IOCTL(ATMARPD_CTRL) 3104 case SIOCSIFMAP:
3116COMPATIBLE_IOCTL(ATMLEC_CTRL) 3105 case SIOCGIFADDR:
3117COMPATIBLE_IOCTL(ATMLEC_MCAST) 3106 case SIOCSIFADDR:
3118COMPATIBLE_IOCTL(ATMLEC_DATA) 3107 case SIOCSIFHWBROADCAST:
3119COMPATIBLE_IOCTL(ATM_SETSC) 3108 case SIOCSHWTSTAMP:
3120COMPATIBLE_IOCTL(SIOCSIFATMTCP) 3109 case SIOCDIFADDR:
3121COMPATIBLE_IOCTL(SIOCMKCLIP) 3110/* case SIOCSARP: duplicate */
3122COMPATIBLE_IOCTL(ATMARP_MKIP) 3111/* case SIOCDARP: duplicate */
3123COMPATIBLE_IOCTL(ATMARP_SETENTRY) 3112 case SIOCGIFBRDADDR:
3124COMPATIBLE_IOCTL(ATMARP_ENCAP) 3113 case SIOCSIFBRDADDR:
3125COMPATIBLE_IOCTL(ATMTCP_CREATE) 3114 case SIOCGIFDSTADDR:
3126COMPATIBLE_IOCTL(ATMTCP_REMOVE) 3115 case SIOCSIFDSTADDR:
3127COMPATIBLE_IOCTL(ATMMPC_CTRL) 3116 case SIOCGIFNETMASK:
3128COMPATIBLE_IOCTL(ATMMPC_DATA) 3117 case SIOCSIFNETMASK:
3129HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl) 3118 case SIOCSIFPFLAGS:
3130HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl) 3119 case SIOCGIFPFLAGS:
3131HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl) 3120 case SIOCGIFTXQLEN:
3132HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl) 3121 case SIOCSIFTXQLEN:
3133HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl) 3122 case SIOCBRADDIF:
3134HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl) 3123 case SIOCBRDELIF:
3135HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl) 3124 return dev_ifsioc(net, sock, cmd, argp);
3136HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl) 3125 case ATM_GETLINKRATE32:
3137HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl) 3126 case ATM_GETNAMES32:
3138HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl) 3127 case ATM_GETTYPE32:
3139HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl) 3128 case ATM_GETESI32:
3140HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl) 3129 case ATM_GETADDR32:
3141HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl) 3130 case ATM_RSTADDR32:
3142HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl) 3131 case ATM_ADDADDR32:
3143HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl) 3132 case ATM_DELADDR32:
3144HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl) 3133 case ATM_GETCIRANGE32:
3145HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl) 3134 case ATM_SETCIRANGE32:
3146HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl) 3135 case ATM_SETESI32:
3147HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl) 3136 case ATM_SETESIF32:
3148HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl) 3137 case ATM_GETSTAT32:
3149HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl) 3138 case ATM_GETSTATZ32:
3150HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl) 3139 case ATM_GETLOOP32:
3151HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl) 3140 case ATM_SETLOOP32:
3152HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl) 3141 case ATM_QUERYLOOP32:
3153HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl) 3142 case SONET_GETSTAT:
3154COMPATIBLE_IOCTL(FIOSETOWN) 3143 case SONET_GETSTATZ:
3155COMPATIBLE_IOCTL(SIOCSPGRP) 3144 case SONET_GETDIAG:
3156COMPATIBLE_IOCTL(FIOGETOWN) 3145 case SONET_SETDIAG:
3157COMPATIBLE_IOCTL(SIOCGPGRP) 3146 case SONET_CLRDIAG:
3158COMPATIBLE_IOCTL(SIOCATMARK) 3147 case SONET_SETFRAMING:
3159COMPATIBLE_IOCTL(SIOCSIFLINK) 3148 case SONET_GETFRAMING:
3160COMPATIBLE_IOCTL(SIOCSIFNAME) 3149 case SONET_GETFRSENSE:
3161COMPATIBLE_IOCTL(SIOCSARP) 3150 return do_atm_ioctl(net, sock, cmd, arg);
3162COMPATIBLE_IOCTL(SIOCGARP) 3151
3163COMPATIBLE_IOCTL(SIOCDARP) 3152 case ATMSIGD_CTRL:
3164COMPATIBLE_IOCTL(SIOCSRARP) 3153 case ATMARPD_CTRL:
3165COMPATIBLE_IOCTL(SIOCGRARP) 3154 case ATMLEC_CTRL:
3166COMPATIBLE_IOCTL(SIOCDRARP) 3155 case ATMLEC_MCAST:
3167COMPATIBLE_IOCTL(SIOCADDDLCI) 3156 case ATMLEC_DATA:
3168COMPATIBLE_IOCTL(SIOCDELDLCI) 3157 case ATM_SETSC:
3169COMPATIBLE_IOCTL(SIOCGMIIPHY) 3158 case SIOCSIFATMTCP:
3170COMPATIBLE_IOCTL(SIOCGMIIREG) 3159 case SIOCMKCLIP:
3171COMPATIBLE_IOCTL(SIOCSMIIREG) 3160 case ATMARP_MKIP:
3172COMPATIBLE_IOCTL(SIOCGIFVLAN) 3161 case ATMARP_SETENTRY:
3173COMPATIBLE_IOCTL(SIOCSIFVLAN) 3162 case ATMARP_ENCAP:
3174COMPATIBLE_IOCTL(SIOCBRADDBR) 3163 case ATMTCP_CREATE:
3175COMPATIBLE_IOCTL(SIOCBRDELBR) 3164 case ATMTCP_REMOVE:
3176#endif 3165 case ATMMPC_CTRL:
3166 case ATMMPC_DATA:
3167
3168 case SIOCSARP:
3169 case SIOCGARP:
3170 case SIOCDARP:
3171
3172 case SIOCATMARK:
3173 case SIOCSIFLINK:
3174 case SIOCSIFNAME:
3175 case SIOCSRARP:
3176 case SIOCGRARP:
3177 case SIOCDRARP:
3178 case SIOCGMIIPHY:
3179 case SIOCGMIIREG:
3180 case SIOCSMIIREG:
3181 return sock_do_ioctl(net, sock, cmd, arg);
3182 }
3183
3184 return -ENOIOCTLCMD;
3185}
3177 3186
3178static long compat_sock_ioctl(struct file *file, unsigned cmd, 3187static long compat_sock_ioctl(struct file *file, unsigned cmd,
3179 unsigned long arg) 3188 unsigned long arg)
@@ -3193,6 +3202,9 @@ static long compat_sock_ioctl(struct file *file, unsigned cmd,
3193 (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)) 3202 (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
3194 ret = compat_wext_handle_ioctl(net, cmd, arg); 3203 ret = compat_wext_handle_ioctl(net, cmd, arg);
3195 3204
3205 if (ret == -ENOIOCTLCMD)
3206 ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
3207
3196 return ret; 3208 return ret;
3197} 3209}
3198#endif 3210#endif