diff options
Diffstat (limited to 'net/socket.c')
| -rw-r--r-- | net/socket.c | 314 |
1 files changed, 145 insertions, 169 deletions
diff --git a/net/socket.c b/net/socket.c index 769c386bd428..2270b941bcc7 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -87,12 +87,14 @@ | |||
| 87 | #include <linux/wireless.h> | 87 | #include <linux/wireless.h> |
| 88 | #include <linux/nsproxy.h> | 88 | #include <linux/nsproxy.h> |
| 89 | #include <linux/magic.h> | 89 | #include <linux/magic.h> |
| 90 | #include <linux/slab.h> | ||
| 90 | 91 | ||
| 91 | #include <asm/uaccess.h> | 92 | #include <asm/uaccess.h> |
| 92 | #include <asm/unistd.h> | 93 | #include <asm/unistd.h> |
| 93 | 94 | ||
| 94 | #include <net/compat.h> | 95 | #include <net/compat.h> |
| 95 | #include <net/wext.h> | 96 | #include <net/wext.h> |
| 97 | #include <net/cls_cgroup.h> | ||
| 96 | 98 | ||
| 97 | #include <net/sock.h> | 99 | #include <net/sock.h> |
| 98 | #include <linux/netfilter.h> | 100 | #include <linux/netfilter.h> |
| @@ -122,7 +124,7 @@ static int sock_fasync(int fd, struct file *filp, int on); | |||
| 122 | static ssize_t sock_sendpage(struct file *file, struct page *page, | 124 | static ssize_t sock_sendpage(struct file *file, struct page *page, |
| 123 | int offset, size_t size, loff_t *ppos, int more); | 125 | int offset, size_t size, loff_t *ppos, int more); |
| 124 | static ssize_t sock_splice_read(struct file *file, loff_t *ppos, | 126 | static ssize_t sock_splice_read(struct file *file, loff_t *ppos, |
| 125 | struct pipe_inode_info *pipe, size_t len, | 127 | struct pipe_inode_info *pipe, size_t len, |
| 126 | unsigned int flags); | 128 | unsigned int flags); |
| 127 | 129 | ||
| 128 | /* | 130 | /* |
| @@ -160,7 +162,7 @@ static const struct net_proto_family *net_families[NPROTO] __read_mostly; | |||
| 160 | * Statistics counters of the socket lists | 162 | * Statistics counters of the socket lists |
| 161 | */ | 163 | */ |
| 162 | 164 | ||
| 163 | static DEFINE_PER_CPU(int, sockets_in_use) = 0; | 165 | static DEFINE_PER_CPU(int, sockets_in_use); |
| 164 | 166 | ||
| 165 | /* | 167 | /* |
| 166 | * Support routines. | 168 | * Support routines. |
| @@ -168,15 +170,6 @@ static DEFINE_PER_CPU(int, sockets_in_use) = 0; | |||
| 168 | * divide and look after the messy bits. | 170 | * divide and look after the messy bits. |
| 169 | */ | 171 | */ |
| 170 | 172 | ||
| 171 | #define MAX_SOCK_ADDR 128 /* 108 for Unix domain - | ||
| 172 | 16 for IP, 16 for IPX, | ||
| 173 | 24 for IPv6, | ||
| 174 | about 80 for AX.25 | ||
| 175 | must be at least one bigger than | ||
| 176 | the AF_UNIX size (see net/unix/af_unix.c | ||
| 177 | :unix_mkname()). | ||
| 178 | */ | ||
| 179 | |||
| 180 | /** | 173 | /** |
| 181 | * move_addr_to_kernel - copy a socket address into kernel space | 174 | * move_addr_to_kernel - copy a socket address into kernel space |
| 182 | * @uaddr: Address in user space | 175 | * @uaddr: Address in user space |
| @@ -251,9 +244,14 @@ static struct inode *sock_alloc_inode(struct super_block *sb) | |||
| 251 | ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL); | 244 | ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL); |
| 252 | if (!ei) | 245 | if (!ei) |
| 253 | return NULL; | 246 | return NULL; |
| 254 | init_waitqueue_head(&ei->socket.wait); | 247 | ei->socket.wq = kmalloc(sizeof(struct socket_wq), GFP_KERNEL); |
| 248 | if (!ei->socket.wq) { | ||
| 249 | kmem_cache_free(sock_inode_cachep, ei); | ||
| 250 | return NULL; | ||
| 251 | } | ||
| 252 | init_waitqueue_head(&ei->socket.wq->wait); | ||
| 253 | ei->socket.wq->fasync_list = NULL; | ||
| 255 | 254 | ||
| 256 | ei->socket.fasync_list = NULL; | ||
| 257 | ei->socket.state = SS_UNCONNECTED; | 255 | ei->socket.state = SS_UNCONNECTED; |
| 258 | ei->socket.flags = 0; | 256 | ei->socket.flags = 0; |
| 259 | ei->socket.ops = NULL; | 257 | ei->socket.ops = NULL; |
| @@ -263,10 +261,21 @@ static struct inode *sock_alloc_inode(struct super_block *sb) | |||
| 263 | return &ei->vfs_inode; | 261 | return &ei->vfs_inode; |
| 264 | } | 262 | } |
| 265 | 263 | ||
| 264 | |||
| 265 | static void wq_free_rcu(struct rcu_head *head) | ||
| 266 | { | ||
| 267 | struct socket_wq *wq = container_of(head, struct socket_wq, rcu); | ||
| 268 | |||
| 269 | kfree(wq); | ||
| 270 | } | ||
| 271 | |||
| 266 | static void sock_destroy_inode(struct inode *inode) | 272 | static void sock_destroy_inode(struct inode *inode) |
| 267 | { | 273 | { |
| 268 | kmem_cache_free(sock_inode_cachep, | 274 | struct socket_alloc *ei; |
| 269 | container_of(inode, struct socket_alloc, vfs_inode)); | 275 | |
| 276 | ei = container_of(inode, struct socket_alloc, vfs_inode); | ||
| 277 | call_rcu(&ei->socket.wq->rcu, wq_free_rcu); | ||
| 278 | kmem_cache_free(sock_inode_cachep, ei); | ||
| 270 | } | 279 | } |
| 271 | 280 | ||
| 272 | static void init_once(void *foo) | 281 | static void init_once(void *foo) |
| @@ -291,9 +300,9 @@ static int init_inodecache(void) | |||
| 291 | } | 300 | } |
| 292 | 301 | ||
| 293 | static const struct super_operations sockfs_ops = { | 302 | static const struct super_operations sockfs_ops = { |
| 294 | .alloc_inode = sock_alloc_inode, | 303 | .alloc_inode = sock_alloc_inode, |
| 295 | .destroy_inode =sock_destroy_inode, | 304 | .destroy_inode = sock_destroy_inode, |
| 296 | .statfs = simple_statfs, | 305 | .statfs = simple_statfs, |
| 297 | }; | 306 | }; |
| 298 | 307 | ||
| 299 | static int sockfs_get_sb(struct file_system_type *fs_type, | 308 | static int sockfs_get_sb(struct file_system_type *fs_type, |
| @@ -393,6 +402,7 @@ int sock_map_fd(struct socket *sock, int flags) | |||
| 393 | 402 | ||
| 394 | return fd; | 403 | return fd; |
| 395 | } | 404 | } |
| 405 | EXPORT_SYMBOL(sock_map_fd); | ||
| 396 | 406 | ||
| 397 | static struct socket *sock_from_file(struct file *file, int *err) | 407 | static struct socket *sock_from_file(struct file *file, int *err) |
| 398 | { | 408 | { |
| @@ -404,7 +414,7 @@ static struct socket *sock_from_file(struct file *file, int *err) | |||
| 404 | } | 414 | } |
| 405 | 415 | ||
| 406 | /** | 416 | /** |
| 407 | * sockfd_lookup - Go from a file number to its socket slot | 417 | * sockfd_lookup - Go from a file number to its socket slot |
| 408 | * @fd: file handle | 418 | * @fd: file handle |
| 409 | * @err: pointer to an error code return | 419 | * @err: pointer to an error code return |
| 410 | * | 420 | * |
| @@ -432,6 +442,7 @@ struct socket *sockfd_lookup(int fd, int *err) | |||
| 432 | fput(file); | 442 | fput(file); |
| 433 | return sock; | 443 | return sock; |
| 434 | } | 444 | } |
| 445 | EXPORT_SYMBOL(sockfd_lookup); | ||
| 435 | 446 | ||
| 436 | static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) | 447 | static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) |
| 437 | { | 448 | { |
| @@ -512,7 +523,7 @@ void sock_release(struct socket *sock) | |||
| 512 | module_put(owner); | 523 | module_put(owner); |
| 513 | } | 524 | } |
| 514 | 525 | ||
| 515 | if (sock->fasync_list) | 526 | if (sock->wq->fasync_list) |
| 516 | printk(KERN_ERR "sock_release: fasync list not empty!\n"); | 527 | printk(KERN_ERR "sock_release: fasync list not empty!\n"); |
| 517 | 528 | ||
| 518 | percpu_sub(sockets_in_use, 1); | 529 | percpu_sub(sockets_in_use, 1); |
| @@ -522,6 +533,7 @@ void sock_release(struct socket *sock) | |||
| 522 | } | 533 | } |
| 523 | sock->file = NULL; | 534 | sock->file = NULL; |
| 524 | } | 535 | } |
| 536 | EXPORT_SYMBOL(sock_release); | ||
| 525 | 537 | ||
| 526 | int sock_tx_timestamp(struct msghdr *msg, struct sock *sk, | 538 | int sock_tx_timestamp(struct msghdr *msg, struct sock *sk, |
| 527 | union skb_shared_tx *shtx) | 539 | union skb_shared_tx *shtx) |
| @@ -541,6 +553,8 @@ static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 541 | struct sock_iocb *si = kiocb_to_siocb(iocb); | 553 | struct sock_iocb *si = kiocb_to_siocb(iocb); |
| 542 | int err; | 554 | int err; |
| 543 | 555 | ||
| 556 | sock_update_classid(sock->sk); | ||
| 557 | |||
| 544 | si->sock = sock; | 558 | si->sock = sock; |
| 545 | si->scm = NULL; | 559 | si->scm = NULL; |
| 546 | si->msg = msg; | 560 | si->msg = msg; |
| @@ -566,6 +580,7 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) | |||
| 566 | ret = wait_on_sync_kiocb(&iocb); | 580 | ret = wait_on_sync_kiocb(&iocb); |
| 567 | return ret; | 581 | return ret; |
| 568 | } | 582 | } |
| 583 | EXPORT_SYMBOL(sock_sendmsg); | ||
| 569 | 584 | ||
| 570 | int kernel_sendmsg(struct socket *sock, struct msghdr *msg, | 585 | int kernel_sendmsg(struct socket *sock, struct msghdr *msg, |
| 571 | struct kvec *vec, size_t num, size_t size) | 586 | struct kvec *vec, size_t num, size_t size) |
| @@ -584,6 +599,7 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg, | |||
| 584 | set_fs(oldfs); | 599 | set_fs(oldfs); |
| 585 | return result; | 600 | return result; |
| 586 | } | 601 | } |
| 602 | EXPORT_SYMBOL(kernel_sendmsg); | ||
| 587 | 603 | ||
| 588 | static int ktime2ts(ktime_t kt, struct timespec *ts) | 604 | static int ktime2ts(ktime_t kt, struct timespec *ts) |
| 589 | { | 605 | { |
| @@ -619,10 +635,9 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, | |||
| 619 | put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP, | 635 | put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP, |
| 620 | sizeof(tv), &tv); | 636 | sizeof(tv), &tv); |
| 621 | } else { | 637 | } else { |
| 622 | struct timespec ts; | 638 | skb_get_timestampns(skb, &ts[0]); |
| 623 | skb_get_timestampns(skb, &ts); | ||
| 624 | put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS, | 639 | put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS, |
| 625 | sizeof(ts), &ts); | 640 | sizeof(ts[0]), &ts[0]); |
| 626 | } | 641 | } |
| 627 | } | 642 | } |
| 628 | 643 | ||
| @@ -645,7 +660,6 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, | |||
| 645 | put_cmsg(msg, SOL_SOCKET, | 660 | put_cmsg(msg, SOL_SOCKET, |
| 646 | SCM_TIMESTAMPING, sizeof(ts), &ts); | 661 | SCM_TIMESTAMPING, sizeof(ts), &ts); |
| 647 | } | 662 | } |
| 648 | |||
| 649 | EXPORT_SYMBOL_GPL(__sock_recv_timestamp); | 663 | EXPORT_SYMBOL_GPL(__sock_recv_timestamp); |
| 650 | 664 | ||
| 651 | inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) | 665 | inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) |
| @@ -655,19 +669,21 @@ inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff | |||
| 655 | sizeof(__u32), &skb->dropcount); | 669 | sizeof(__u32), &skb->dropcount); |
| 656 | } | 670 | } |
| 657 | 671 | ||
| 658 | void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, | 672 | void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, |
| 659 | struct sk_buff *skb) | 673 | struct sk_buff *skb) |
| 660 | { | 674 | { |
| 661 | sock_recv_timestamp(msg, sk, skb); | 675 | sock_recv_timestamp(msg, sk, skb); |
| 662 | sock_recv_drops(msg, sk, skb); | 676 | sock_recv_drops(msg, sk, skb); |
| 663 | } | 677 | } |
| 664 | EXPORT_SYMBOL_GPL(sock_recv_ts_and_drops); | 678 | EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops); |
| 665 | 679 | ||
| 666 | static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, | 680 | static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, |
| 667 | struct msghdr *msg, size_t size, int flags) | 681 | struct msghdr *msg, size_t size, int flags) |
| 668 | { | 682 | { |
| 669 | struct sock_iocb *si = kiocb_to_siocb(iocb); | 683 | struct sock_iocb *si = kiocb_to_siocb(iocb); |
| 670 | 684 | ||
| 685 | sock_update_classid(sock->sk); | ||
| 686 | |||
| 671 | si->sock = sock; | 687 | si->sock = sock; |
| 672 | si->scm = NULL; | 688 | si->scm = NULL; |
| 673 | si->msg = msg; | 689 | si->msg = msg; |
| @@ -699,6 +715,7 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg, | |||
| 699 | ret = wait_on_sync_kiocb(&iocb); | 715 | ret = wait_on_sync_kiocb(&iocb); |
| 700 | return ret; | 716 | return ret; |
| 701 | } | 717 | } |
| 718 | EXPORT_SYMBOL(sock_recvmsg); | ||
| 702 | 719 | ||
| 703 | static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, | 720 | static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, |
| 704 | size_t size, int flags) | 721 | size_t size, int flags) |
| @@ -731,6 +748,7 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg, | |||
| 731 | set_fs(oldfs); | 748 | set_fs(oldfs); |
| 732 | return result; | 749 | return result; |
| 733 | } | 750 | } |
| 751 | EXPORT_SYMBOL(kernel_recvmsg); | ||
| 734 | 752 | ||
| 735 | static void sock_aio_dtor(struct kiocb *iocb) | 753 | static void sock_aio_dtor(struct kiocb *iocb) |
| 736 | { | 754 | { |
| @@ -753,7 +771,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page, | |||
| 753 | } | 771 | } |
| 754 | 772 | ||
| 755 | static ssize_t sock_splice_read(struct file *file, loff_t *ppos, | 773 | static ssize_t sock_splice_read(struct file *file, loff_t *ppos, |
| 756 | struct pipe_inode_info *pipe, size_t len, | 774 | struct pipe_inode_info *pipe, size_t len, |
| 757 | unsigned int flags) | 775 | unsigned int flags) |
| 758 | { | 776 | { |
| 759 | struct socket *sock = file->private_data; | 777 | struct socket *sock = file->private_data; |
| @@ -761,6 +779,8 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, | |||
| 761 | if (unlikely(!sock->ops->splice_read)) | 779 | if (unlikely(!sock->ops->splice_read)) |
| 762 | return -EINVAL; | 780 | return -EINVAL; |
| 763 | 781 | ||
| 782 | sock_update_classid(sock->sk); | ||
| 783 | |||
| 764 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); | 784 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); |
| 765 | } | 785 | } |
| 766 | 786 | ||
| @@ -864,7 +884,7 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 864 | */ | 884 | */ |
| 865 | 885 | ||
| 866 | static DEFINE_MUTEX(br_ioctl_mutex); | 886 | static DEFINE_MUTEX(br_ioctl_mutex); |
| 867 | static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg) = NULL; | 887 | static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg); |
| 868 | 888 | ||
| 869 | void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *)) | 889 | void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *)) |
| 870 | { | 890 | { |
| @@ -872,7 +892,6 @@ void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *)) | |||
| 872 | br_ioctl_hook = hook; | 892 | br_ioctl_hook = hook; |
| 873 | mutex_unlock(&br_ioctl_mutex); | 893 | mutex_unlock(&br_ioctl_mutex); |
| 874 | } | 894 | } |
| 875 | |||
| 876 | EXPORT_SYMBOL(brioctl_set); | 895 | EXPORT_SYMBOL(brioctl_set); |
| 877 | 896 | ||
| 878 | static DEFINE_MUTEX(vlan_ioctl_mutex); | 897 | static DEFINE_MUTEX(vlan_ioctl_mutex); |
| @@ -884,7 +903,6 @@ void vlan_ioctl_set(int (*hook) (struct net *, void __user *)) | |||
| 884 | vlan_ioctl_hook = hook; | 903 | vlan_ioctl_hook = hook; |
| 885 | mutex_unlock(&vlan_ioctl_mutex); | 904 | mutex_unlock(&vlan_ioctl_mutex); |
| 886 | } | 905 | } |
| 887 | |||
| 888 | EXPORT_SYMBOL(vlan_ioctl_set); | 906 | EXPORT_SYMBOL(vlan_ioctl_set); |
| 889 | 907 | ||
| 890 | static DEFINE_MUTEX(dlci_ioctl_mutex); | 908 | static DEFINE_MUTEX(dlci_ioctl_mutex); |
| @@ -896,7 +914,6 @@ void dlci_ioctl_set(int (*hook) (unsigned int, void __user *)) | |||
| 896 | dlci_ioctl_hook = hook; | 914 | dlci_ioctl_hook = hook; |
| 897 | mutex_unlock(&dlci_ioctl_mutex); | 915 | mutex_unlock(&dlci_ioctl_mutex); |
| 898 | } | 916 | } |
| 899 | |||
| 900 | EXPORT_SYMBOL(dlci_ioctl_set); | 917 | EXPORT_SYMBOL(dlci_ioctl_set); |
| 901 | 918 | ||
| 902 | static long sock_do_ioctl(struct net *net, struct socket *sock, | 919 | static long sock_do_ioctl(struct net *net, struct socket *sock, |
| @@ -1024,6 +1041,7 @@ out_release: | |||
| 1024 | sock = NULL; | 1041 | sock = NULL; |
| 1025 | goto out; | 1042 | goto out; |
| 1026 | } | 1043 | } |
| 1044 | EXPORT_SYMBOL(sock_create_lite); | ||
| 1027 | 1045 | ||
| 1028 | /* No kernel lock held - perfect */ | 1046 | /* No kernel lock held - perfect */ |
| 1029 | static unsigned int sock_poll(struct file *file, poll_table *wait) | 1047 | static unsigned int sock_poll(struct file *file, poll_table *wait) |
| @@ -1067,87 +1085,44 @@ static int sock_close(struct inode *inode, struct file *filp) | |||
| 1067 | * 1. fasync_list is modified only under process context socket lock | 1085 | * 1. fasync_list is modified only under process context socket lock |
| 1068 | * i.e. under semaphore. | 1086 | * i.e. under semaphore. |
| 1069 | * 2. fasync_list is used under read_lock(&sk->sk_callback_lock) | 1087 | * 2. fasync_list is used under read_lock(&sk->sk_callback_lock) |
| 1070 | * or under socket lock. | 1088 | * or under socket lock |
| 1071 | * 3. fasync_list can be used from softirq context, so that | ||
| 1072 | * modification under socket lock have to be enhanced with | ||
| 1073 | * write_lock_bh(&sk->sk_callback_lock). | ||
| 1074 | * --ANK (990710) | ||
| 1075 | */ | 1089 | */ |
| 1076 | 1090 | ||
| 1077 | static int sock_fasync(int fd, struct file *filp, int on) | 1091 | static int sock_fasync(int fd, struct file *filp, int on) |
| 1078 | { | 1092 | { |
| 1079 | struct fasync_struct *fa, *fna = NULL, **prev; | 1093 | struct socket *sock = filp->private_data; |
| 1080 | struct socket *sock; | 1094 | struct sock *sk = sock->sk; |
| 1081 | struct sock *sk; | ||
| 1082 | |||
| 1083 | if (on) { | ||
| 1084 | fna = kmalloc(sizeof(struct fasync_struct), GFP_KERNEL); | ||
| 1085 | if (fna == NULL) | ||
| 1086 | return -ENOMEM; | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | sock = filp->private_data; | ||
| 1090 | 1095 | ||
| 1091 | sk = sock->sk; | 1096 | if (sk == NULL) |
| 1092 | if (sk == NULL) { | ||
| 1093 | kfree(fna); | ||
| 1094 | return -EINVAL; | 1097 | return -EINVAL; |
| 1095 | } | ||
| 1096 | 1098 | ||
| 1097 | lock_sock(sk); | 1099 | lock_sock(sk); |
| 1098 | 1100 | ||
| 1099 | spin_lock(&filp->f_lock); | 1101 | fasync_helper(fd, filp, on, &sock->wq->fasync_list); |
| 1100 | if (on) | ||
| 1101 | filp->f_flags |= FASYNC; | ||
| 1102 | else | ||
| 1103 | filp->f_flags &= ~FASYNC; | ||
| 1104 | spin_unlock(&filp->f_lock); | ||
| 1105 | |||
| 1106 | prev = &(sock->fasync_list); | ||
| 1107 | |||
| 1108 | for (fa = *prev; fa != NULL; prev = &fa->fa_next, fa = *prev) | ||
| 1109 | if (fa->fa_file == filp) | ||
| 1110 | break; | ||
| 1111 | |||
| 1112 | if (on) { | ||
| 1113 | if (fa != NULL) { | ||
| 1114 | write_lock_bh(&sk->sk_callback_lock); | ||
| 1115 | fa->fa_fd = fd; | ||
| 1116 | write_unlock_bh(&sk->sk_callback_lock); | ||
| 1117 | 1102 | ||
| 1118 | kfree(fna); | 1103 | if (!sock->wq->fasync_list) |
| 1119 | goto out; | 1104 | sock_reset_flag(sk, SOCK_FASYNC); |
| 1120 | } | 1105 | else |
| 1121 | fna->fa_file = filp; | ||
| 1122 | fna->fa_fd = fd; | ||
| 1123 | fna->magic = FASYNC_MAGIC; | ||
| 1124 | fna->fa_next = sock->fasync_list; | ||
| 1125 | write_lock_bh(&sk->sk_callback_lock); | ||
| 1126 | sock->fasync_list = fna; | ||
| 1127 | sock_set_flag(sk, SOCK_FASYNC); | 1106 | sock_set_flag(sk, SOCK_FASYNC); |
| 1128 | write_unlock_bh(&sk->sk_callback_lock); | ||
| 1129 | } else { | ||
| 1130 | if (fa != NULL) { | ||
| 1131 | write_lock_bh(&sk->sk_callback_lock); | ||
| 1132 | *prev = fa->fa_next; | ||
| 1133 | if (!sock->fasync_list) | ||
| 1134 | sock_reset_flag(sk, SOCK_FASYNC); | ||
| 1135 | write_unlock_bh(&sk->sk_callback_lock); | ||
| 1136 | kfree(fa); | ||
| 1137 | } | ||
| 1138 | } | ||
| 1139 | 1107 | ||
| 1140 | out: | 1108 | release_sock(sk); |
| 1141 | release_sock(sock->sk); | ||
| 1142 | return 0; | 1109 | return 0; |
| 1143 | } | 1110 | } |
| 1144 | 1111 | ||
| 1145 | /* This function may be called only under socket lock or callback_lock */ | 1112 | /* This function may be called only under socket lock or callback_lock or rcu_lock */ |
| 1146 | 1113 | ||
| 1147 | int sock_wake_async(struct socket *sock, int how, int band) | 1114 | int sock_wake_async(struct socket *sock, int how, int band) |
| 1148 | { | 1115 | { |
| 1149 | if (!sock || !sock->fasync_list) | 1116 | struct socket_wq *wq; |
| 1117 | |||
| 1118 | if (!sock) | ||
| 1119 | return -1; | ||
| 1120 | rcu_read_lock(); | ||
| 1121 | wq = rcu_dereference(sock->wq); | ||
| 1122 | if (!wq || !wq->fasync_list) { | ||
| 1123 | rcu_read_unlock(); | ||
| 1150 | return -1; | 1124 | return -1; |
| 1125 | } | ||
| 1151 | switch (how) { | 1126 | switch (how) { |
| 1152 | case SOCK_WAKE_WAITD: | 1127 | case SOCK_WAKE_WAITD: |
| 1153 | if (test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) | 1128 | if (test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) |
| @@ -1159,13 +1134,15 @@ int sock_wake_async(struct socket *sock, int how, int band) | |||
| 1159 | /* fall through */ | 1134 | /* fall through */ |
| 1160 | case SOCK_WAKE_IO: | 1135 | case SOCK_WAKE_IO: |
| 1161 | call_kill: | 1136 | call_kill: |
| 1162 | __kill_fasync(sock->fasync_list, SIGIO, band); | 1137 | kill_fasync(&wq->fasync_list, SIGIO, band); |
| 1163 | break; | 1138 | break; |
| 1164 | case SOCK_WAKE_URG: | 1139 | case SOCK_WAKE_URG: |
| 1165 | __kill_fasync(sock->fasync_list, SIGURG, band); | 1140 | kill_fasync(&wq->fasync_list, SIGURG, band); |
| 1166 | } | 1141 | } |
| 1142 | rcu_read_unlock(); | ||
| 1167 | return 0; | 1143 | return 0; |
| 1168 | } | 1144 | } |
| 1145 | EXPORT_SYMBOL(sock_wake_async); | ||
| 1169 | 1146 | ||
| 1170 | static int __sock_create(struct net *net, int family, int type, int protocol, | 1147 | static int __sock_create(struct net *net, int family, int type, int protocol, |
| 1171 | struct socket **res, int kern) | 1148 | struct socket **res, int kern) |
| @@ -1284,11 +1261,13 @@ int sock_create(int family, int type, int protocol, struct socket **res) | |||
| 1284 | { | 1261 | { |
| 1285 | return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0); | 1262 | return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0); |
| 1286 | } | 1263 | } |
| 1264 | EXPORT_SYMBOL(sock_create); | ||
| 1287 | 1265 | ||
| 1288 | int sock_create_kern(int family, int type, int protocol, struct socket **res) | 1266 | int sock_create_kern(int family, int type, int protocol, struct socket **res) |
| 1289 | { | 1267 | { |
| 1290 | return __sock_create(&init_net, family, type, protocol, res, 1); | 1268 | return __sock_create(&init_net, family, type, protocol, res, 1); |
| 1291 | } | 1269 | } |
| 1270 | EXPORT_SYMBOL(sock_create_kern); | ||
| 1292 | 1271 | ||
| 1293 | SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) | 1272 | SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) |
| 1294 | { | 1273 | { |
| @@ -1493,7 +1472,8 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, | |||
| 1493 | goto out; | 1472 | goto out; |
| 1494 | 1473 | ||
| 1495 | err = -ENFILE; | 1474 | err = -ENFILE; |
| 1496 | if (!(newsock = sock_alloc())) | 1475 | newsock = sock_alloc(); |
| 1476 | if (!newsock) | ||
| 1497 | goto out_put; | 1477 | goto out_put; |
| 1498 | 1478 | ||
| 1499 | newsock->type = sock->type; | 1479 | newsock->type = sock->type; |
| @@ -1880,8 +1860,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) | |||
| 1880 | if (MSG_CMSG_COMPAT & flags) { | 1860 | if (MSG_CMSG_COMPAT & flags) { |
| 1881 | if (get_compat_msghdr(&msg_sys, msg_compat)) | 1861 | if (get_compat_msghdr(&msg_sys, msg_compat)) |
| 1882 | return -EFAULT; | 1862 | return -EFAULT; |
| 1883 | } | 1863 | } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr))) |
| 1884 | else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr))) | ||
| 1885 | return -EFAULT; | 1864 | return -EFAULT; |
| 1886 | 1865 | ||
| 1887 | sock = sockfd_lookup_light(fd, &err, &fput_needed); | 1866 | sock = sockfd_lookup_light(fd, &err, &fput_needed); |
| @@ -1983,8 +1962,7 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg, | |||
| 1983 | if (MSG_CMSG_COMPAT & flags) { | 1962 | if (MSG_CMSG_COMPAT & flags) { |
| 1984 | if (get_compat_msghdr(msg_sys, msg_compat)) | 1963 | if (get_compat_msghdr(msg_sys, msg_compat)) |
| 1985 | return -EFAULT; | 1964 | return -EFAULT; |
| 1986 | } | 1965 | } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr))) |
| 1987 | else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr))) | ||
| 1988 | return -EFAULT; | 1966 | return -EFAULT; |
| 1989 | 1967 | ||
| 1990 | err = -EMSGSIZE; | 1968 | err = -EMSGSIZE; |
| @@ -2135,6 +2113,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
| 2135 | break; | 2113 | break; |
| 2136 | ++datagrams; | 2114 | ++datagrams; |
| 2137 | 2115 | ||
| 2116 | /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */ | ||
| 2117 | if (flags & MSG_WAITFORONE) | ||
| 2118 | flags |= MSG_DONTWAIT; | ||
| 2119 | |||
| 2138 | if (timeout) { | 2120 | if (timeout) { |
| 2139 | ktime_get_ts(timeout); | 2121 | ktime_get_ts(timeout); |
| 2140 | *timeout = timespec_sub(end_time, *timeout); | 2122 | *timeout = timespec_sub(end_time, *timeout); |
| @@ -2206,10 +2188,10 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, | |||
| 2206 | /* Argument list sizes for sys_socketcall */ | 2188 | /* Argument list sizes for sys_socketcall */ |
| 2207 | #define AL(x) ((x) * sizeof(unsigned long)) | 2189 | #define AL(x) ((x) * sizeof(unsigned long)) |
| 2208 | static const unsigned char nargs[20] = { | 2190 | static const unsigned char nargs[20] = { |
| 2209 | AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), | 2191 | AL(0), AL(3), AL(3), AL(3), AL(2), AL(3), |
| 2210 | AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), | 2192 | AL(3), AL(3), AL(4), AL(4), AL(4), AL(6), |
| 2211 | AL(6),AL(2),AL(5),AL(5),AL(3),AL(3), | 2193 | AL(6), AL(2), AL(5), AL(5), AL(3), AL(3), |
| 2212 | AL(4),AL(5) | 2194 | AL(4), AL(5) |
| 2213 | }; | 2195 | }; |
| 2214 | 2196 | ||
| 2215 | #undef AL | 2197 | #undef AL |
| @@ -2355,6 +2337,7 @@ int sock_register(const struct net_proto_family *ops) | |||
| 2355 | printk(KERN_INFO "NET: Registered protocol family %d\n", ops->family); | 2337 | printk(KERN_INFO "NET: Registered protocol family %d\n", ops->family); |
| 2356 | return err; | 2338 | return err; |
| 2357 | } | 2339 | } |
| 2340 | EXPORT_SYMBOL(sock_register); | ||
| 2358 | 2341 | ||
| 2359 | /** | 2342 | /** |
| 2360 | * sock_unregister - remove a protocol handler | 2343 | * sock_unregister - remove a protocol handler |
| @@ -2381,6 +2364,7 @@ void sock_unregister(int family) | |||
| 2381 | 2364 | ||
| 2382 | printk(KERN_INFO "NET: Unregistered protocol family %d\n", family); | 2365 | printk(KERN_INFO "NET: Unregistered protocol family %d\n", family); |
| 2383 | } | 2366 | } |
| 2367 | EXPORT_SYMBOL(sock_unregister); | ||
| 2384 | 2368 | ||
| 2385 | static int __init sock_init(void) | 2369 | static int __init sock_init(void) |
| 2386 | { | 2370 | { |
| @@ -2410,6 +2394,10 @@ static int __init sock_init(void) | |||
| 2410 | netfilter_init(); | 2394 | netfilter_init(); |
| 2411 | #endif | 2395 | #endif |
| 2412 | 2396 | ||
| 2397 | #ifdef CONFIG_NETWORK_PHY_TIMESTAMPING | ||
| 2398 | skb_timestamping_init(); | ||
| 2399 | #endif | ||
| 2400 | |||
| 2413 | return 0; | 2401 | return 0; |
| 2414 | } | 2402 | } |
| 2415 | 2403 | ||
| @@ -2505,13 +2493,13 @@ static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32) | |||
| 2505 | ifc.ifc_req = NULL; | 2493 | ifc.ifc_req = NULL; |
| 2506 | uifc = compat_alloc_user_space(sizeof(struct ifconf)); | 2494 | uifc = compat_alloc_user_space(sizeof(struct ifconf)); |
| 2507 | } else { | 2495 | } else { |
| 2508 | size_t len =((ifc32.ifc_len / sizeof (struct compat_ifreq)) + 1) * | 2496 | size_t len = ((ifc32.ifc_len / sizeof(struct compat_ifreq)) + 1) * |
| 2509 | sizeof (struct ifreq); | 2497 | sizeof(struct ifreq); |
| 2510 | uifc = compat_alloc_user_space(sizeof(struct ifconf) + len); | 2498 | uifc = compat_alloc_user_space(sizeof(struct ifconf) + len); |
| 2511 | ifc.ifc_len = len; | 2499 | ifc.ifc_len = len; |
| 2512 | ifr = ifc.ifc_req = (void __user *)(uifc + 1); | 2500 | ifr = ifc.ifc_req = (void __user *)(uifc + 1); |
| 2513 | ifr32 = compat_ptr(ifc32.ifcbuf); | 2501 | ifr32 = compat_ptr(ifc32.ifcbuf); |
| 2514 | for (i = 0; i < ifc32.ifc_len; i += sizeof (struct compat_ifreq)) { | 2502 | for (i = 0; i < ifc32.ifc_len; i += sizeof(struct compat_ifreq)) { |
| 2515 | if (copy_in_user(ifr, ifr32, sizeof(struct compat_ifreq))) | 2503 | if (copy_in_user(ifr, ifr32, sizeof(struct compat_ifreq))) |
| 2516 | return -EFAULT; | 2504 | return -EFAULT; |
| 2517 | ifr++; | 2505 | ifr++; |
| @@ -2531,9 +2519,9 @@ static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32) | |||
| 2531 | ifr = ifc.ifc_req; | 2519 | ifr = ifc.ifc_req; |
| 2532 | ifr32 = compat_ptr(ifc32.ifcbuf); | 2520 | ifr32 = compat_ptr(ifc32.ifcbuf); |
| 2533 | for (i = 0, j = 0; | 2521 | for (i = 0, j = 0; |
| 2534 | i + sizeof (struct compat_ifreq) <= ifc32.ifc_len && j < ifc.ifc_len; | 2522 | i + sizeof(struct compat_ifreq) <= ifc32.ifc_len && j < ifc.ifc_len; |
| 2535 | i += sizeof (struct compat_ifreq), j += sizeof (struct ifreq)) { | 2523 | i += sizeof(struct compat_ifreq), j += sizeof(struct ifreq)) { |
| 2536 | if (copy_in_user(ifr32, ifr, sizeof (struct compat_ifreq))) | 2524 | if (copy_in_user(ifr32, ifr, sizeof(struct compat_ifreq))) |
| 2537 | return -EFAULT; | 2525 | return -EFAULT; |
| 2538 | ifr32++; | 2526 | ifr32++; |
| 2539 | ifr++; | 2527 | ifr++; |
| @@ -2582,7 +2570,7 @@ static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32 | |||
| 2582 | compat_uptr_t uptr32; | 2570 | compat_uptr_t uptr32; |
| 2583 | struct ifreq __user *uifr; | 2571 | struct ifreq __user *uifr; |
| 2584 | 2572 | ||
| 2585 | uifr = compat_alloc_user_space(sizeof (*uifr)); | 2573 | uifr = compat_alloc_user_space(sizeof(*uifr)); |
| 2586 | if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq))) | 2574 | if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq))) |
| 2587 | return -EFAULT; | 2575 | return -EFAULT; |
| 2588 | 2576 | ||
| @@ -2616,9 +2604,9 @@ static int bond_ioctl(struct net *net, unsigned int cmd, | |||
| 2616 | return -EFAULT; | 2604 | return -EFAULT; |
| 2617 | 2605 | ||
| 2618 | old_fs = get_fs(); | 2606 | old_fs = get_fs(); |
| 2619 | set_fs (KERNEL_DS); | 2607 | set_fs(KERNEL_DS); |
| 2620 | err = dev_ioctl(net, cmd, &kifr); | 2608 | err = dev_ioctl(net, cmd, &kifr); |
| 2621 | set_fs (old_fs); | 2609 | set_fs(old_fs); |
| 2622 | 2610 | ||
| 2623 | return err; | 2611 | return err; |
| 2624 | case SIOCBONDSLAVEINFOQUERY: | 2612 | case SIOCBONDSLAVEINFOQUERY: |
| @@ -2637,7 +2625,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd, | |||
| 2637 | return dev_ioctl(net, cmd, uifr); | 2625 | return dev_ioctl(net, cmd, uifr); |
| 2638 | default: | 2626 | default: |
| 2639 | return -EINVAL; | 2627 | return -EINVAL; |
| 2640 | }; | 2628 | } |
| 2641 | } | 2629 | } |
| 2642 | 2630 | ||
| 2643 | static int siocdevprivate_ioctl(struct net *net, unsigned int cmd, | 2631 | static int siocdevprivate_ioctl(struct net *net, unsigned int cmd, |
| @@ -2725,9 +2713,9 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd, | |||
| 2725 | return -EFAULT; | 2713 | return -EFAULT; |
| 2726 | 2714 | ||
| 2727 | old_fs = get_fs(); | 2715 | old_fs = get_fs(); |
| 2728 | set_fs (KERNEL_DS); | 2716 | set_fs(KERNEL_DS); |
| 2729 | err = dev_ioctl(net, cmd, (void __user *)&ifr); | 2717 | err = dev_ioctl(net, cmd, (void __user *)&ifr); |
| 2730 | set_fs (old_fs); | 2718 | set_fs(old_fs); |
| 2731 | 2719 | ||
| 2732 | if (cmd == SIOCGIFMAP && !err) { | 2720 | if (cmd == SIOCGIFMAP && !err) { |
| 2733 | err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name)); | 2721 | err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name)); |
| @@ -2749,7 +2737,7 @@ static int compat_siocshwtstamp(struct net *net, struct compat_ifreq __user *uif | |||
| 2749 | compat_uptr_t uptr32; | 2737 | compat_uptr_t uptr32; |
| 2750 | struct ifreq __user *uifr; | 2738 | struct ifreq __user *uifr; |
| 2751 | 2739 | ||
| 2752 | uifr = compat_alloc_user_space(sizeof (*uifr)); | 2740 | uifr = compat_alloc_user_space(sizeof(*uifr)); |
| 2753 | if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq))) | 2741 | if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq))) |
| 2754 | return -EFAULT; | 2742 | return -EFAULT; |
| 2755 | 2743 | ||
| @@ -2765,20 +2753,20 @@ static int compat_siocshwtstamp(struct net *net, struct compat_ifreq __user *uif | |||
| 2765 | } | 2753 | } |
| 2766 | 2754 | ||
| 2767 | struct rtentry32 { | 2755 | struct rtentry32 { |
| 2768 | u32 rt_pad1; | 2756 | u32 rt_pad1; |
| 2769 | struct sockaddr rt_dst; /* target address */ | 2757 | struct sockaddr rt_dst; /* target address */ |
| 2770 | struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */ | 2758 | struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */ |
| 2771 | struct sockaddr rt_genmask; /* target network mask (IP) */ | 2759 | struct sockaddr rt_genmask; /* target network mask (IP) */ |
| 2772 | unsigned short rt_flags; | 2760 | unsigned short rt_flags; |
| 2773 | short rt_pad2; | 2761 | short rt_pad2; |
| 2774 | u32 rt_pad3; | 2762 | u32 rt_pad3; |
| 2775 | unsigned char rt_tos; | 2763 | unsigned char rt_tos; |
| 2776 | unsigned char rt_class; | 2764 | unsigned char rt_class; |
| 2777 | short rt_pad4; | 2765 | short rt_pad4; |
| 2778 | short rt_metric; /* +1 for binary compatibility! */ | 2766 | short rt_metric; /* +1 for binary compatibility! */ |
| 2779 | /* char * */ u32 rt_dev; /* forcing the device at add */ | 2767 | /* char * */ u32 rt_dev; /* forcing the device at add */ |
| 2780 | u32 rt_mtu; /* per route MTU/Window */ | 2768 | u32 rt_mtu; /* per route MTU/Window */ |
| 2781 | u32 rt_window; /* Window clamping */ | 2769 | u32 rt_window; /* Window clamping */ |
| 2782 | unsigned short rt_irtt; /* Initial RTT */ | 2770 | unsigned short rt_irtt; /* Initial RTT */ |
| 2783 | }; | 2771 | }; |
| 2784 | 2772 | ||
| @@ -2808,29 +2796,29 @@ static int routing_ioctl(struct net *net, struct socket *sock, | |||
| 2808 | 2796 | ||
| 2809 | if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */ | 2797 | if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */ |
| 2810 | struct in6_rtmsg32 __user *ur6 = argp; | 2798 | struct in6_rtmsg32 __user *ur6 = argp; |
| 2811 | ret = copy_from_user (&r6.rtmsg_dst, &(ur6->rtmsg_dst), | 2799 | ret = copy_from_user(&r6.rtmsg_dst, &(ur6->rtmsg_dst), |
| 2812 | 3 * sizeof(struct in6_addr)); | 2800 | 3 * sizeof(struct in6_addr)); |
| 2813 | ret |= __get_user (r6.rtmsg_type, &(ur6->rtmsg_type)); | 2801 | ret |= __get_user(r6.rtmsg_type, &(ur6->rtmsg_type)); |
| 2814 | ret |= __get_user (r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len)); | 2802 | ret |= __get_user(r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len)); |
| 2815 | ret |= __get_user (r6.rtmsg_src_len, &(ur6->rtmsg_src_len)); | 2803 | ret |= __get_user(r6.rtmsg_src_len, &(ur6->rtmsg_src_len)); |
| 2816 | ret |= __get_user (r6.rtmsg_metric, &(ur6->rtmsg_metric)); | 2804 | ret |= __get_user(r6.rtmsg_metric, &(ur6->rtmsg_metric)); |
| 2817 | ret |= __get_user (r6.rtmsg_info, &(ur6->rtmsg_info)); | 2805 | ret |= __get_user(r6.rtmsg_info, &(ur6->rtmsg_info)); |
| 2818 | ret |= __get_user (r6.rtmsg_flags, &(ur6->rtmsg_flags)); | 2806 | ret |= __get_user(r6.rtmsg_flags, &(ur6->rtmsg_flags)); |
| 2819 | ret |= __get_user (r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex)); | 2807 | ret |= __get_user(r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex)); |
| 2820 | 2808 | ||
| 2821 | r = (void *) &r6; | 2809 | r = (void *) &r6; |
| 2822 | } else { /* ipv4 */ | 2810 | } else { /* ipv4 */ |
| 2823 | struct rtentry32 __user *ur4 = argp; | 2811 | struct rtentry32 __user *ur4 = argp; |
| 2824 | ret = copy_from_user (&r4.rt_dst, &(ur4->rt_dst), | 2812 | ret = copy_from_user(&r4.rt_dst, &(ur4->rt_dst), |
| 2825 | 3 * sizeof(struct sockaddr)); | 2813 | 3 * sizeof(struct sockaddr)); |
| 2826 | ret |= __get_user (r4.rt_flags, &(ur4->rt_flags)); | 2814 | ret |= __get_user(r4.rt_flags, &(ur4->rt_flags)); |
| 2827 | ret |= __get_user (r4.rt_metric, &(ur4->rt_metric)); | 2815 | ret |= __get_user(r4.rt_metric, &(ur4->rt_metric)); |
| 2828 | ret |= __get_user (r4.rt_mtu, &(ur4->rt_mtu)); | 2816 | ret |= __get_user(r4.rt_mtu, &(ur4->rt_mtu)); |
| 2829 | ret |= __get_user (r4.rt_window, &(ur4->rt_window)); | 2817 | ret |= __get_user(r4.rt_window, &(ur4->rt_window)); |
| 2830 | ret |= __get_user (r4.rt_irtt, &(ur4->rt_irtt)); | 2818 | ret |= __get_user(r4.rt_irtt, &(ur4->rt_irtt)); |
| 2831 | ret |= __get_user (rtdev, &(ur4->rt_dev)); | 2819 | ret |= __get_user(rtdev, &(ur4->rt_dev)); |
| 2832 | if (rtdev) { | 2820 | if (rtdev) { |
| 2833 | ret |= copy_from_user (devname, compat_ptr(rtdev), 15); | 2821 | ret |= copy_from_user(devname, compat_ptr(rtdev), 15); |
| 2834 | r4.rt_dev = devname; devname[15] = 0; | 2822 | r4.rt_dev = devname; devname[15] = 0; |
| 2835 | } else | 2823 | } else |
| 2836 | r4.rt_dev = NULL; | 2824 | r4.rt_dev = NULL; |
| @@ -2843,9 +2831,9 @@ static int routing_ioctl(struct net *net, struct socket *sock, | |||
| 2843 | goto out; | 2831 | goto out; |
| 2844 | } | 2832 | } |
| 2845 | 2833 | ||
| 2846 | set_fs (KERNEL_DS); | 2834 | set_fs(KERNEL_DS); |
| 2847 | ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r); | 2835 | ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r); |
| 2848 | set_fs (old_fs); | 2836 | set_fs(old_fs); |
| 2849 | 2837 | ||
| 2850 | out: | 2838 | out: |
| 2851 | return ret; | 2839 | return ret; |
| @@ -3008,11 +2996,13 @@ int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen) | |||
| 3008 | { | 2996 | { |
| 3009 | return sock->ops->bind(sock, addr, addrlen); | 2997 | return sock->ops->bind(sock, addr, addrlen); |
| 3010 | } | 2998 | } |
| 2999 | EXPORT_SYMBOL(kernel_bind); | ||
| 3011 | 3000 | ||
| 3012 | int kernel_listen(struct socket *sock, int backlog) | 3001 | int kernel_listen(struct socket *sock, int backlog) |
| 3013 | { | 3002 | { |
| 3014 | return sock->ops->listen(sock, backlog); | 3003 | return sock->ops->listen(sock, backlog); |
| 3015 | } | 3004 | } |
| 3005 | EXPORT_SYMBOL(kernel_listen); | ||
| 3016 | 3006 | ||
| 3017 | int kernel_accept(struct socket *sock, struct socket **newsock, int flags) | 3007 | int kernel_accept(struct socket *sock, struct socket **newsock, int flags) |
| 3018 | { | 3008 | { |
| @@ -3037,24 +3027,28 @@ int kernel_accept(struct socket *sock, struct socket **newsock, int flags) | |||
| 3037 | done: | 3027 | done: |
| 3038 | return err; | 3028 | return err; |
| 3039 | } | 3029 | } |
| 3030 | EXPORT_SYMBOL(kernel_accept); | ||
| 3040 | 3031 | ||
| 3041 | int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen, | 3032 | int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen, |
| 3042 | int flags) | 3033 | int flags) |
| 3043 | { | 3034 | { |
| 3044 | return sock->ops->connect(sock, addr, addrlen, flags); | 3035 | return sock->ops->connect(sock, addr, addrlen, flags); |
| 3045 | } | 3036 | } |
| 3037 | EXPORT_SYMBOL(kernel_connect); | ||
| 3046 | 3038 | ||
| 3047 | int kernel_getsockname(struct socket *sock, struct sockaddr *addr, | 3039 | int kernel_getsockname(struct socket *sock, struct sockaddr *addr, |
| 3048 | int *addrlen) | 3040 | int *addrlen) |
| 3049 | { | 3041 | { |
| 3050 | return sock->ops->getname(sock, addr, addrlen, 0); | 3042 | return sock->ops->getname(sock, addr, addrlen, 0); |
| 3051 | } | 3043 | } |
| 3044 | EXPORT_SYMBOL(kernel_getsockname); | ||
| 3052 | 3045 | ||
| 3053 | int kernel_getpeername(struct socket *sock, struct sockaddr *addr, | 3046 | int kernel_getpeername(struct socket *sock, struct sockaddr *addr, |
| 3054 | int *addrlen) | 3047 | int *addrlen) |
| 3055 | { | 3048 | { |
| 3056 | return sock->ops->getname(sock, addr, addrlen, 1); | 3049 | return sock->ops->getname(sock, addr, addrlen, 1); |
| 3057 | } | 3050 | } |
| 3051 | EXPORT_SYMBOL(kernel_getpeername); | ||
| 3058 | 3052 | ||
| 3059 | int kernel_getsockopt(struct socket *sock, int level, int optname, | 3053 | int kernel_getsockopt(struct socket *sock, int level, int optname, |
| 3060 | char *optval, int *optlen) | 3054 | char *optval, int *optlen) |
| @@ -3071,6 +3065,7 @@ int kernel_getsockopt(struct socket *sock, int level, int optname, | |||
| 3071 | set_fs(oldfs); | 3065 | set_fs(oldfs); |
| 3072 | return err; | 3066 | return err; |
| 3073 | } | 3067 | } |
| 3068 | EXPORT_SYMBOL(kernel_getsockopt); | ||
| 3074 | 3069 | ||
| 3075 | int kernel_setsockopt(struct socket *sock, int level, int optname, | 3070 | int kernel_setsockopt(struct socket *sock, int level, int optname, |
| 3076 | char *optval, unsigned int optlen) | 3071 | char *optval, unsigned int optlen) |
| @@ -3087,15 +3082,19 @@ int kernel_setsockopt(struct socket *sock, int level, int optname, | |||
| 3087 | set_fs(oldfs); | 3082 | set_fs(oldfs); |
| 3088 | return err; | 3083 | return err; |
| 3089 | } | 3084 | } |
| 3085 | EXPORT_SYMBOL(kernel_setsockopt); | ||
| 3090 | 3086 | ||
| 3091 | int kernel_sendpage(struct socket *sock, struct page *page, int offset, | 3087 | int kernel_sendpage(struct socket *sock, struct page *page, int offset, |
| 3092 | size_t size, int flags) | 3088 | size_t size, int flags) |
| 3093 | { | 3089 | { |
| 3090 | sock_update_classid(sock->sk); | ||
| 3091 | |||
| 3094 | if (sock->ops->sendpage) | 3092 | if (sock->ops->sendpage) |
| 3095 | return sock->ops->sendpage(sock, page, offset, size, flags); | 3093 | return sock->ops->sendpage(sock, page, offset, size, flags); |
| 3096 | 3094 | ||
| 3097 | return sock_no_sendpage(sock, page, offset, size, flags); | 3095 | return sock_no_sendpage(sock, page, offset, size, flags); |
| 3098 | } | 3096 | } |
| 3097 | EXPORT_SYMBOL(kernel_sendpage); | ||
| 3099 | 3098 | ||
| 3100 | int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg) | 3099 | int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg) |
| 3101 | { | 3100 | { |
| @@ -3108,33 +3107,10 @@ int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg) | |||
| 3108 | 3107 | ||
| 3109 | return err; | 3108 | return err; |
| 3110 | } | 3109 | } |
| 3110 | EXPORT_SYMBOL(kernel_sock_ioctl); | ||
| 3111 | 3111 | ||
| 3112 | int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how) | 3112 | int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how) |
| 3113 | { | 3113 | { |
| 3114 | return sock->ops->shutdown(sock, how); | 3114 | return sock->ops->shutdown(sock, how); |
| 3115 | } | 3115 | } |
| 3116 | |||
| 3117 | EXPORT_SYMBOL(sock_create); | ||
| 3118 | EXPORT_SYMBOL(sock_create_kern); | ||
| 3119 | EXPORT_SYMBOL(sock_create_lite); | ||
| 3120 | EXPORT_SYMBOL(sock_map_fd); | ||
| 3121 | EXPORT_SYMBOL(sock_recvmsg); | ||
| 3122 | EXPORT_SYMBOL(sock_register); | ||
| 3123 | EXPORT_SYMBOL(sock_release); | ||
| 3124 | EXPORT_SYMBOL(sock_sendmsg); | ||
| 3125 | EXPORT_SYMBOL(sock_unregister); | ||
| 3126 | EXPORT_SYMBOL(sock_wake_async); | ||
| 3127 | EXPORT_SYMBOL(sockfd_lookup); | ||
| 3128 | EXPORT_SYMBOL(kernel_sendmsg); | ||
| 3129 | EXPORT_SYMBOL(kernel_recvmsg); | ||
| 3130 | EXPORT_SYMBOL(kernel_bind); | ||
| 3131 | EXPORT_SYMBOL(kernel_listen); | ||
| 3132 | EXPORT_SYMBOL(kernel_accept); | ||
| 3133 | EXPORT_SYMBOL(kernel_connect); | ||
| 3134 | EXPORT_SYMBOL(kernel_getsockname); | ||
| 3135 | EXPORT_SYMBOL(kernel_getpeername); | ||
| 3136 | EXPORT_SYMBOL(kernel_getsockopt); | ||
| 3137 | EXPORT_SYMBOL(kernel_setsockopt); | ||
| 3138 | EXPORT_SYMBOL(kernel_sendpage); | ||
| 3139 | EXPORT_SYMBOL(kernel_sock_ioctl); | ||
| 3140 | EXPORT_SYMBOL(kernel_sock_shutdown); | 3116 | EXPORT_SYMBOL(kernel_sock_shutdown); |
