summaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-01-31 17:31:10 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-01-31 17:31:10 -0500
commitb2fe5fa68642860e7de76167c3111623aa0d5de1 (patch)
treeb7f9b89b7039ecefbc35fe3c8e73a6ff972641dd /net/socket.c
parenta103950e0dd2058df5e8a8d4a915707bdcf205f0 (diff)
parenta54667f6728c2714a400f3c884727da74b6d1717 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) Significantly shrink the core networking routing structures. Result of http://vger.kernel.org/~davem/seoul2017_netdev_keynote.pdf 2) Add netdevsim driver for testing various offloads, from Jakub Kicinski. 3) Support cross-chip FDB operations in DSA, from Vivien Didelot. 4) Add a 2nd listener hash table for TCP, similar to what was done for UDP. From Martin KaFai Lau. 5) Add eBPF based queue selection to tun, from Jason Wang. 6) Lockless qdisc support, from John Fastabend. 7) SCTP stream interleave support, from Xin Long. 8) Smoother TCP receive autotuning, from Eric Dumazet. 9) Lots of erspan tunneling enhancements, from William Tu. 10) Add true function call support to BPF, from Alexei Starovoitov. 11) Add explicit support for GRO HW offloading, from Michael Chan. 12) Support extack generation in more netlink subsystems. From Alexander Aring, Quentin Monnet, and Jakub Kicinski. 13) Add 1000BaseX, flow control, and EEE support to mvneta driver. From Russell King. 14) Add flow table abstraction to netfilter, from Pablo Neira Ayuso. 15) Many improvements and simplifications to the NFP driver bpf JIT, from Jakub Kicinski. 16) Support for ipv6 non-equal cost multipath routing, from Ido Schimmel. 17) Add resource abstration to devlink, from Arkadi Sharshevsky. 18) Packet scheduler classifier shared filter block support, from Jiri Pirko. 19) Avoid locking in act_csum, from Davide Caratti. 20) devinet_ioctl() simplifications from Al viro. 21) More TCP bpf improvements from Lawrence Brakmo. 22) Add support for onlink ipv6 route flag, similar to ipv4, from David Ahern. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1925 commits) tls: Add support for encryption using async offload accelerator ip6mr: fix stale iterator net/sched: kconfig: Remove blank help texts openvswitch: meter: Use 64-bit arithmetic instead of 32-bit tcp_nv: fix potential integer overflow in tcpnv_acked r8169: fix RTL8168EP take too long to complete driver initialization. qmi_wwan: Add support for Quectel EP06 rtnetlink: enable IFLA_IF_NETNSID for RTM_NEWLINK ipmr: Fix ptrdiff_t print formatting ibmvnic: Wait for device response when changing MAC qlcnic: fix deadlock bug tcp: release sk_frag.page in tcp_disconnect ipv4: Get the address of interface correctly. net_sched: gen_estimator: fix lockdep splat net: macb: Handle HRESP error net/mlx5e: IPoIB, Fix copy-paste bug in flow steering refactoring ipv6: addrconf: break critical section in addrconf_verify_rtnl() ipv6: change route cache aging logic i40e/i40evf: Update DESC_NEEDED value to reflect larger value bnxt_en: cleanup DIM work on device shutdown ...
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c301
1 files changed, 71 insertions, 230 deletions
diff --git a/net/socket.c b/net/socket.c
index 2f378449bc1b..a93c99b518ca 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -163,12 +163,6 @@ static DEFINE_SPINLOCK(net_family_lock);
163static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly; 163static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
164 164
165/* 165/*
166 * Statistics counters of the socket lists
167 */
168
169static DEFINE_PER_CPU(int, sockets_in_use);
170
171/*
172 * Support routines. 166 * Support routines.
173 * Move socket addresses back and forth across the kernel/user 167 * Move socket addresses back and forth across the kernel/user
174 * divide and look after the messy bits. 168 * divide and look after the messy bits.
@@ -580,7 +574,6 @@ struct socket *sock_alloc(void)
580 inode->i_gid = current_fsgid(); 574 inode->i_gid = current_fsgid();
581 inode->i_op = &sockfs_inode_ops; 575 inode->i_op = &sockfs_inode_ops;
582 576
583 this_cpu_add(sockets_in_use, 1);
584 return sock; 577 return sock;
585} 578}
586EXPORT_SYMBOL(sock_alloc); 579EXPORT_SYMBOL(sock_alloc);
@@ -607,7 +600,6 @@ void sock_release(struct socket *sock)
607 if (rcu_dereference_protected(sock->wq, 1)->fasync_list) 600 if (rcu_dereference_protected(sock->wq, 1)->fasync_list)
608 pr_err("%s: fasync list not empty!\n", __func__); 601 pr_err("%s: fasync list not empty!\n", __func__);
609 602
610 this_cpu_sub(sockets_in_use, 1);
611 if (!sock->file) { 603 if (!sock->file) {
612 iput(SOCK_INODE(sock)); 604 iput(SOCK_INODE(sock));
613 return; 605 return;
@@ -969,9 +961,28 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,
969 * If this ioctl is unknown try to hand it down 961 * If this ioctl is unknown try to hand it down
970 * to the NIC driver. 962 * to the NIC driver.
971 */ 963 */
972 if (err == -ENOIOCTLCMD) 964 if (err != -ENOIOCTLCMD)
973 err = dev_ioctl(net, cmd, argp); 965 return err;
974 966
967 if (cmd == SIOCGIFCONF) {
968 struct ifconf ifc;
969 if (copy_from_user(&ifc, argp, sizeof(struct ifconf)))
970 return -EFAULT;
971 rtnl_lock();
972 err = dev_ifconf(net, &ifc, sizeof(struct ifreq));
973 rtnl_unlock();
974 if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf)))
975 err = -EFAULT;
976 } else {
977 struct ifreq ifr;
978 bool need_copyout;
979 if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
980 return -EFAULT;
981 err = dev_ioctl(net, cmd, &ifr, &need_copyout);
982 if (!err && need_copyout)
983 if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
984 return -EFAULT;
985 }
975 return err; 986 return err;
976} 987}
977 988
@@ -996,12 +1007,19 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
996 sock = file->private_data; 1007 sock = file->private_data;
997 sk = sock->sk; 1008 sk = sock->sk;
998 net = sock_net(sk); 1009 net = sock_net(sk);
999 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { 1010 if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) {
1000 err = dev_ioctl(net, cmd, argp); 1011 struct ifreq ifr;
1012 bool need_copyout;
1013 if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
1014 return -EFAULT;
1015 err = dev_ioctl(net, cmd, &ifr, &need_copyout);
1016 if (!err && need_copyout)
1017 if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
1018 return -EFAULT;
1001 } else 1019 } else
1002#ifdef CONFIG_WEXT_CORE 1020#ifdef CONFIG_WEXT_CORE
1003 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { 1021 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
1004 err = dev_ioctl(net, cmd, argp); 1022 err = wext_handle_ioctl(net, cmd, argp);
1005 } else 1023 } else
1006#endif 1024#endif
1007 switch (cmd) { 1025 switch (cmd) {
@@ -2621,29 +2639,11 @@ out_fs:
2621 2639
2622core_initcall(sock_init); /* early initcall */ 2640core_initcall(sock_init); /* early initcall */
2623 2641
2624static int __init jit_init(void)
2625{
2626#ifdef CONFIG_BPF_JIT_ALWAYS_ON
2627 bpf_jit_enable = 1;
2628#endif
2629 return 0;
2630}
2631pure_initcall(jit_init);
2632
2633#ifdef CONFIG_PROC_FS 2642#ifdef CONFIG_PROC_FS
2634void socket_seq_show(struct seq_file *seq) 2643void socket_seq_show(struct seq_file *seq)
2635{ 2644{
2636 int cpu; 2645 seq_printf(seq, "sockets: used %d\n",
2637 int counter = 0; 2646 sock_inuse_get(seq->private));
2638
2639 for_each_possible_cpu(cpu)
2640 counter += per_cpu(sockets_in_use, cpu);
2641
2642 /* It can be negative, by the way. 8) */
2643 if (counter < 0)
2644 counter = 0;
2645
2646 seq_printf(seq, "sockets: used %d\n", counter);
2647} 2647}
2648#endif /* CONFIG_PROC_FS */ 2648#endif /* CONFIG_PROC_FS */
2649 2649
@@ -2680,89 +2680,25 @@ static int do_siocgstampns(struct net *net, struct socket *sock,
2680 return err; 2680 return err;
2681} 2681}
2682 2682
2683static int dev_ifname32(struct net *net, struct compat_ifreq __user *uifr32) 2683static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
2684{
2685 struct ifreq __user *uifr;
2686 int err;
2687
2688 uifr = compat_alloc_user_space(sizeof(struct ifreq));
2689 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
2690 return -EFAULT;
2691
2692 err = dev_ioctl(net, SIOCGIFNAME, uifr);
2693 if (err)
2694 return err;
2695
2696 if (copy_in_user(uifr32, uifr, sizeof(struct compat_ifreq)))
2697 return -EFAULT;
2698
2699 return 0;
2700}
2701
2702static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
2703{ 2684{
2704 struct compat_ifconf ifc32; 2685 struct compat_ifconf ifc32;
2705 struct ifconf ifc; 2686 struct ifconf ifc;
2706 struct ifconf __user *uifc;
2707 struct compat_ifreq __user *ifr32;
2708 struct ifreq __user *ifr;
2709 unsigned int i, j;
2710 int err; 2687 int err;
2711 2688
2712 if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf))) 2689 if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
2713 return -EFAULT; 2690 return -EFAULT;
2714 2691
2715 memset(&ifc, 0, sizeof(ifc)); 2692 ifc.ifc_len = ifc32.ifc_len;
2716 if (ifc32.ifcbuf == 0) { 2693 ifc.ifc_req = compat_ptr(ifc32.ifcbuf);
2717 ifc32.ifc_len = 0;
2718 ifc.ifc_len = 0;
2719 ifc.ifc_req = NULL;
2720 uifc = compat_alloc_user_space(sizeof(struct ifconf));
2721 } else {
2722 size_t len = ((ifc32.ifc_len / sizeof(struct compat_ifreq)) + 1) *
2723 sizeof(struct ifreq);
2724 uifc = compat_alloc_user_space(sizeof(struct ifconf) + len);
2725 ifc.ifc_len = len;
2726 ifr = ifc.ifc_req = (void __user *)(uifc + 1);
2727 ifr32 = compat_ptr(ifc32.ifcbuf);
2728 for (i = 0; i < ifc32.ifc_len; i += sizeof(struct compat_ifreq)) {
2729 if (copy_in_user(ifr, ifr32, sizeof(struct compat_ifreq)))
2730 return -EFAULT;
2731 ifr++;
2732 ifr32++;
2733 }
2734 }
2735 if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
2736 return -EFAULT;
2737 2694
2738 err = dev_ioctl(net, SIOCGIFCONF, uifc); 2695 rtnl_lock();
2696 err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq));
2697 rtnl_unlock();
2739 if (err) 2698 if (err)
2740 return err; 2699 return err;
2741 2700
2742 if (copy_from_user(&ifc, uifc, sizeof(struct ifconf))) 2701 ifc32.ifc_len = ifc.ifc_len;
2743 return -EFAULT;
2744
2745 ifr = ifc.ifc_req;
2746 ifr32 = compat_ptr(ifc32.ifcbuf);
2747 for (i = 0, j = 0;
2748 i + sizeof(struct compat_ifreq) <= ifc32.ifc_len && j < ifc.ifc_len;
2749 i += sizeof(struct compat_ifreq), j += sizeof(struct ifreq)) {
2750 if (copy_in_user(ifr32, ifr, sizeof(struct compat_ifreq)))
2751 return -EFAULT;
2752 ifr32++;
2753 ifr++;
2754 }
2755
2756 if (ifc32.ifcbuf == 0) {
2757 /* Translate from 64-bit structure multiple to
2758 * a 32-bit one.
2759 */
2760 i = ifc.ifc_len;
2761 i = ((i / sizeof(struct ifreq)) * sizeof(struct compat_ifreq));
2762 ifc32.ifc_len = i;
2763 } else {
2764 ifc32.ifc_len = i;
2765 }
2766 if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf))) 2702 if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
2767 return -EFAULT; 2703 return -EFAULT;
2768 2704
@@ -2773,9 +2709,9 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
2773{ 2709{
2774 struct compat_ethtool_rxnfc __user *compat_rxnfc; 2710 struct compat_ethtool_rxnfc __user *compat_rxnfc;
2775 bool convert_in = false, convert_out = false; 2711 bool convert_in = false, convert_out = false;
2776 size_t buf_size = ALIGN(sizeof(struct ifreq), 8); 2712 size_t buf_size = 0;
2777 struct ethtool_rxnfc __user *rxnfc; 2713 struct ethtool_rxnfc __user *rxnfc = NULL;
2778 struct ifreq __user *ifr; 2714 struct ifreq ifr;
2779 u32 rule_cnt = 0, actual_rule_cnt; 2715 u32 rule_cnt = 0, actual_rule_cnt;
2780 u32 ethcmd; 2716 u32 ethcmd;
2781 u32 data; 2717 u32 data;
@@ -2812,18 +2748,14 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
2812 case ETHTOOL_SRXCLSRLDEL: 2748 case ETHTOOL_SRXCLSRLDEL:
2813 buf_size += sizeof(struct ethtool_rxnfc); 2749 buf_size += sizeof(struct ethtool_rxnfc);
2814 convert_in = true; 2750 convert_in = true;
2751 rxnfc = compat_alloc_user_space(buf_size);
2815 break; 2752 break;
2816 } 2753 }
2817 2754
2818 ifr = compat_alloc_user_space(buf_size); 2755 if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ))
2819 rxnfc = (void __user *)ifr + ALIGN(sizeof(struct ifreq), 8);
2820
2821 if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
2822 return -EFAULT; 2756 return -EFAULT;
2823 2757
2824 if (put_user(convert_in ? rxnfc : compat_ptr(data), 2758 ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc;
2825 &ifr->ifr_ifru.ifru_data))
2826 return -EFAULT;
2827 2759
2828 if (convert_in) { 2760 if (convert_in) {
2829 /* We expect there to be holes between fs.m_ext and 2761 /* We expect there to be holes between fs.m_ext and
@@ -2851,7 +2783,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
2851 return -EFAULT; 2783 return -EFAULT;
2852 } 2784 }
2853 2785
2854 ret = dev_ioctl(net, SIOCETHTOOL, ifr); 2786 ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL);
2855 if (ret) 2787 if (ret)
2856 return ret; 2788 return ret;
2857 2789
@@ -2892,113 +2824,43 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
2892 2824
2893static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32) 2825static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
2894{ 2826{
2895 void __user *uptr;
2896 compat_uptr_t uptr32; 2827 compat_uptr_t uptr32;
2897 struct ifreq __user *uifr; 2828 struct ifreq ifr;
2829 void __user *saved;
2830 int err;
2898 2831
2899 uifr = compat_alloc_user_space(sizeof(*uifr)); 2832 if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq)))
2900 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
2901 return -EFAULT; 2833 return -EFAULT;
2902 2834
2903 if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu)) 2835 if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
2904 return -EFAULT; 2836 return -EFAULT;
2905 2837
2906 uptr = compat_ptr(uptr32); 2838 saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;
2907 2839 ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32);
2908 if (put_user(uptr, &uifr->ifr_settings.ifs_ifsu.raw_hdlc))
2909 return -EFAULT;
2910
2911 return dev_ioctl(net, SIOCWANDEV, uifr);
2912}
2913
2914static int bond_ioctl(struct net *net, unsigned int cmd,
2915 struct compat_ifreq __user *ifr32)
2916{
2917 struct ifreq kifr;
2918 mm_segment_t old_fs;
2919 int err;
2920 2840
2921 switch (cmd) { 2841 err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL);
2922 case SIOCBONDENSLAVE: 2842 if (!err) {
2923 case SIOCBONDRELEASE: 2843 ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved;
2924 case SIOCBONDSETHWADDR: 2844 if (copy_to_user(uifr32, &ifr, sizeof(struct compat_ifreq)))
2925 case SIOCBONDCHANGEACTIVE: 2845 err = -EFAULT;
2926 if (copy_from_user(&kifr, ifr32, sizeof(struct compat_ifreq)))
2927 return -EFAULT;
2928
2929 old_fs = get_fs();
2930 set_fs(KERNEL_DS);
2931 err = dev_ioctl(net, cmd,
2932 (struct ifreq __user __force *) &kifr);
2933 set_fs(old_fs);
2934
2935 return err;
2936 default:
2937 return -ENOIOCTLCMD;
2938 } 2846 }
2847 return err;
2939} 2848}
2940 2849
2941/* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */ 2850/* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
2942static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd, 2851static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
2943 struct compat_ifreq __user *u_ifreq32) 2852 struct compat_ifreq __user *u_ifreq32)
2944{ 2853{
2945 struct ifreq __user *u_ifreq64; 2854 struct ifreq ifreq;
2946 char tmp_buf[IFNAMSIZ];
2947 void __user *data64;
2948 u32 data32; 2855 u32 data32;
2949 2856
2950 if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]), 2857 if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ))
2951 IFNAMSIZ))
2952 return -EFAULT; 2858 return -EFAULT;
2953 if (get_user(data32, &u_ifreq32->ifr_ifru.ifru_data)) 2859 if (get_user(data32, &u_ifreq32->ifr_data))
2954 return -EFAULT; 2860 return -EFAULT;
2955 data64 = compat_ptr(data32); 2861 ifreq.ifr_data = compat_ptr(data32);
2956 2862
2957 u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64)); 2863 return dev_ioctl(net, cmd, &ifreq, NULL);
2958
2959 if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
2960 IFNAMSIZ))
2961 return -EFAULT;
2962 if (put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
2963 return -EFAULT;
2964
2965 return dev_ioctl(net, cmd, u_ifreq64);
2966}
2967
2968static int dev_ifsioc(struct net *net, struct socket *sock,
2969 unsigned int cmd, struct compat_ifreq __user *uifr32)
2970{
2971 struct ifreq __user *uifr;
2972 int err;
2973
2974 uifr = compat_alloc_user_space(sizeof(*uifr));
2975 if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
2976 return -EFAULT;
2977
2978 err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
2979
2980 if (!err) {
2981 switch (cmd) {
2982 case SIOCGIFFLAGS:
2983 case SIOCGIFMETRIC:
2984 case SIOCGIFMTU:
2985 case SIOCGIFMEM:
2986 case SIOCGIFHWADDR:
2987 case SIOCGIFINDEX:
2988 case SIOCGIFADDR:
2989 case SIOCGIFBRDADDR:
2990 case SIOCGIFDSTADDR:
2991 case SIOCGIFNETMASK:
2992 case SIOCGIFPFLAGS:
2993 case SIOCGIFTXQLEN:
2994 case SIOCGMIIPHY:
2995 case SIOCGMIIREG:
2996 if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
2997 err = -EFAULT;
2998 break;
2999 }
3000 }
3001 return err;
3002} 2864}
3003 2865
3004static int compat_sioc_ifmap(struct net *net, unsigned int cmd, 2866static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
@@ -3006,7 +2868,6 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
3006{ 2868{
3007 struct ifreq ifr; 2869 struct ifreq ifr;
3008 struct compat_ifmap __user *uifmap32; 2870 struct compat_ifmap __user *uifmap32;
3009 mm_segment_t old_fs;
3010 int err; 2871 int err;
3011 2872
3012 uifmap32 = &uifr32->ifr_ifru.ifru_map; 2873 uifmap32 = &uifr32->ifr_ifru.ifru_map;
@@ -3020,10 +2881,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
3020 if (err) 2881 if (err)
3021 return -EFAULT; 2882 return -EFAULT;
3022 2883
3023 old_fs = get_fs(); 2884 err = dev_ioctl(net, cmd, &ifr, NULL);
3024 set_fs(KERNEL_DS);
3025 err = dev_ioctl(net, cmd, (void __user __force *)&ifr);
3026 set_fs(old_fs);
3027 2885
3028 if (cmd == SIOCGIFMAP && !err) { 2886 if (cmd == SIOCGIFMAP && !err) {
3029 err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name)); 2887 err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
@@ -3156,10 +3014,8 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3156 case SIOCSIFBR: 3014 case SIOCSIFBR:
3157 case SIOCGIFBR: 3015 case SIOCGIFBR:
3158 return old_bridge_ioctl(argp); 3016 return old_bridge_ioctl(argp);
3159 case SIOCGIFNAME:
3160 return dev_ifname32(net, argp);
3161 case SIOCGIFCONF: 3017 case SIOCGIFCONF:
3162 return dev_ifconf(net, argp); 3018 return compat_dev_ifconf(net, argp);
3163 case SIOCETHTOOL: 3019 case SIOCETHTOOL:
3164 return ethtool_ioctl(net, argp); 3020 return ethtool_ioctl(net, argp);
3165 case SIOCWANDEV: 3021 case SIOCWANDEV:
@@ -3167,11 +3023,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3167 case SIOCGIFMAP: 3023 case SIOCGIFMAP:
3168 case SIOCSIFMAP: 3024 case SIOCSIFMAP:
3169 return compat_sioc_ifmap(net, cmd, argp); 3025 return compat_sioc_ifmap(net, cmd, argp);
3170 case SIOCBONDENSLAVE:
3171 case SIOCBONDRELEASE:
3172 case SIOCBONDSETHWADDR:
3173 case SIOCBONDCHANGEACTIVE:
3174 return bond_ioctl(net, cmd, argp);
3175 case SIOCADDRT: 3026 case SIOCADDRT:
3176 case SIOCDELRT: 3027 case SIOCDELRT:
3177 return routing_ioctl(net, sock, cmd, argp); 3028 return routing_ioctl(net, sock, cmd, argp);
@@ -3231,12 +3082,15 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3231 case SIOCGMIIPHY: 3082 case SIOCGMIIPHY:
3232 case SIOCGMIIREG: 3083 case SIOCGMIIREG:
3233 case SIOCSMIIREG: 3084 case SIOCSMIIREG:
3234 return dev_ifsioc(net, sock, cmd, argp);
3235
3236 case SIOCSARP: 3085 case SIOCSARP:
3237 case SIOCGARP: 3086 case SIOCGARP:
3238 case SIOCDARP: 3087 case SIOCDARP:
3239 case SIOCATMARK: 3088 case SIOCATMARK:
3089 case SIOCBONDENSLAVE:
3090 case SIOCBONDRELEASE:
3091 case SIOCBONDSETHWADDR:
3092 case SIOCBONDCHANGEACTIVE:
3093 case SIOCGIFNAME:
3240 return sock_do_ioctl(net, sock, cmd, arg); 3094 return sock_do_ioctl(net, sock, cmd, arg);
3241 } 3095 }
3242 3096
@@ -3391,19 +3245,6 @@ int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset,
3391} 3245}
3392EXPORT_SYMBOL(kernel_sendpage_locked); 3246EXPORT_SYMBOL(kernel_sendpage_locked);
3393 3247
3394int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg)
3395{
3396 mm_segment_t oldfs = get_fs();
3397 int err;
3398
3399 set_fs(KERNEL_DS);
3400 err = sock->ops->ioctl(sock, cmd, arg);
3401 set_fs(oldfs);
3402
3403 return err;
3404}
3405EXPORT_SYMBOL(kernel_sock_ioctl);
3406
3407int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how) 3248int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how)
3408{ 3249{
3409 return sock->ops->shutdown(sock, how); 3250 return sock->ops->shutdown(sock, how);