diff options
| -rw-r--r-- | include/net/inet_common.h | 4 | ||||
| -rw-r--r-- | include/net/sock.h | 1 | ||||
| -rw-r--r-- | include/net/tcp.h | 8 | ||||
| -rw-r--r-- | net/ipv4/af_inet.c | 15 | ||||
| -rw-r--r-- | net/ipv4/tcp.c | 11 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 3 | ||||
| -rw-r--r-- | net/ipv6/af_inet6.c | 8 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 3 |
8 files changed, 33 insertions, 20 deletions
diff --git a/include/net/inet_common.h b/include/net/inet_common.h index 140c1ec9f8a2..22fac9892b16 100644 --- a/include/net/inet_common.h +++ b/include/net/inet_common.h | |||
| @@ -21,6 +21,10 @@ extern int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr, | |||
| 21 | extern int inet_accept(struct socket *sock, struct socket *newsock, int flags); | 21 | extern int inet_accept(struct socket *sock, struct socket *newsock, int flags); |
| 22 | extern int inet_sendmsg(struct kiocb *iocb, struct socket *sock, | 22 | extern int inet_sendmsg(struct kiocb *iocb, struct socket *sock, |
| 23 | struct msghdr *msg, size_t size); | 23 | struct msghdr *msg, size_t size); |
| 24 | extern ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, | ||
| 25 | size_t size, int flags); | ||
| 26 | extern int inet_recvmsg(struct kiocb *iocb, struct socket *sock, | ||
| 27 | struct msghdr *msg, size_t size, int flags); | ||
| 24 | extern int inet_shutdown(struct socket *sock, int how); | 28 | extern int inet_shutdown(struct socket *sock, int how); |
| 25 | extern int inet_listen(struct socket *sock, int backlog); | 29 | extern int inet_listen(struct socket *sock, int backlog); |
| 26 | extern void inet_sock_destruct(struct sock *sk); | 30 | extern void inet_sock_destruct(struct sock *sk); |
diff --git a/include/net/sock.h b/include/net/sock.h index 4f26f2f83be9..3100e71f0c3d 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
| @@ -772,6 +772,7 @@ struct proto { | |||
| 772 | int *sysctl_wmem; | 772 | int *sysctl_wmem; |
| 773 | int *sysctl_rmem; | 773 | int *sysctl_rmem; |
| 774 | int max_header; | 774 | int max_header; |
| 775 | bool no_autobind; | ||
| 775 | 776 | ||
| 776 | struct kmem_cache *slab; | 777 | struct kmem_cache *slab; |
| 777 | unsigned int obj_size; | 778 | unsigned int obj_size; |
diff --git a/include/net/tcp.h b/include/net/tcp.h index 33ce5242a17a..468b01f01c13 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
| @@ -304,10 +304,10 @@ extern int tcp_v4_rcv(struct sk_buff *skb); | |||
| 304 | 304 | ||
| 305 | extern int tcp_v4_remember_stamp(struct sock *sk); | 305 | extern int tcp_v4_remember_stamp(struct sock *sk); |
| 306 | extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw); | 306 | extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw); |
| 307 | extern int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, | 307 | extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
| 308 | struct msghdr *msg, size_t size); | 308 | size_t size); |
| 309 | extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, | 309 | extern int tcp_sendpage(struct sock *sk, struct page *page, int offset, |
| 310 | size_t size, int flags); | 310 | size_t size, int flags); |
| 311 | extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); | 311 | extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); |
| 312 | extern int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | 312 | extern int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, |
| 313 | struct tcphdr *th, unsigned len); | 313 | struct tcphdr *th, unsigned len); |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 3ceb025b16f2..6a1100c25a9f 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -727,28 +727,31 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
| 727 | sock_rps_record_flow(sk); | 727 | sock_rps_record_flow(sk); |
| 728 | 728 | ||
| 729 | /* We may need to bind the socket. */ | 729 | /* We may need to bind the socket. */ |
| 730 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) | 730 | if (!inet_sk(sk)->inet_num && !sk->sk_prot->no_autobind && |
| 731 | inet_autobind(sk)) | ||
| 731 | return -EAGAIN; | 732 | return -EAGAIN; |
| 732 | 733 | ||
| 733 | return sk->sk_prot->sendmsg(iocb, sk, msg, size); | 734 | return sk->sk_prot->sendmsg(iocb, sk, msg, size); |
| 734 | } | 735 | } |
| 735 | EXPORT_SYMBOL(inet_sendmsg); | 736 | EXPORT_SYMBOL(inet_sendmsg); |
| 736 | 737 | ||
| 737 | static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, | 738 | ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, |
| 738 | size_t size, int flags) | 739 | size_t size, int flags) |
| 739 | { | 740 | { |
| 740 | struct sock *sk = sock->sk; | 741 | struct sock *sk = sock->sk; |
| 741 | 742 | ||
| 742 | sock_rps_record_flow(sk); | 743 | sock_rps_record_flow(sk); |
| 743 | 744 | ||
| 744 | /* We may need to bind the socket. */ | 745 | /* We may need to bind the socket. */ |
| 745 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) | 746 | if (!inet_sk(sk)->inet_num && !sk->sk_prot->no_autobind && |
| 747 | inet_autobind(sk)) | ||
| 746 | return -EAGAIN; | 748 | return -EAGAIN; |
| 747 | 749 | ||
| 748 | if (sk->sk_prot->sendpage) | 750 | if (sk->sk_prot->sendpage) |
| 749 | return sk->sk_prot->sendpage(sk, page, offset, size, flags); | 751 | return sk->sk_prot->sendpage(sk, page, offset, size, flags); |
| 750 | return sock_no_sendpage(sock, page, offset, size, flags); | 752 | return sock_no_sendpage(sock, page, offset, size, flags); |
| 751 | } | 753 | } |
| 754 | EXPORT_SYMBOL(inet_sendpage); | ||
| 752 | 755 | ||
| 753 | int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | 756 | int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, |
| 754 | size_t size, int flags) | 757 | size_t size, int flags) |
| @@ -894,10 +897,10 @@ const struct proto_ops inet_stream_ops = { | |||
| 894 | .shutdown = inet_shutdown, | 897 | .shutdown = inet_shutdown, |
| 895 | .setsockopt = sock_common_setsockopt, | 898 | .setsockopt = sock_common_setsockopt, |
| 896 | .getsockopt = sock_common_getsockopt, | 899 | .getsockopt = sock_common_getsockopt, |
| 897 | .sendmsg = tcp_sendmsg, | 900 | .sendmsg = inet_sendmsg, |
| 898 | .recvmsg = inet_recvmsg, | 901 | .recvmsg = inet_recvmsg, |
| 899 | .mmap = sock_no_mmap, | 902 | .mmap = sock_no_mmap, |
| 900 | .sendpage = tcp_sendpage, | 903 | .sendpage = inet_sendpage, |
| 901 | .splice_read = tcp_splice_read, | 904 | .splice_read = tcp_splice_read, |
| 902 | #ifdef CONFIG_COMPAT | 905 | #ifdef CONFIG_COMPAT |
| 903 | .compat_setsockopt = compat_sock_common_setsockopt, | 906 | .compat_setsockopt = compat_sock_common_setsockopt, |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index b8601b7683a6..9fce8a8a13aa 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -857,15 +857,15 @@ out_err: | |||
| 857 | return sk_stream_error(sk, flags, err); | 857 | return sk_stream_error(sk, flags, err); |
| 858 | } | 858 | } |
| 859 | 859 | ||
| 860 | ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, | 860 | int tcp_sendpage(struct sock *sk, struct page *page, int offset, |
| 861 | size_t size, int flags) | 861 | size_t size, int flags) |
| 862 | { | 862 | { |
| 863 | ssize_t res; | 863 | ssize_t res; |
| 864 | struct sock *sk = sock->sk; | ||
| 865 | 864 | ||
| 866 | if (!(sk->sk_route_caps & NETIF_F_SG) || | 865 | if (!(sk->sk_route_caps & NETIF_F_SG) || |
| 867 | !(sk->sk_route_caps & NETIF_F_ALL_CSUM)) | 866 | !(sk->sk_route_caps & NETIF_F_ALL_CSUM)) |
| 868 | return sock_no_sendpage(sock, page, offset, size, flags); | 867 | return sock_no_sendpage(sk->sk_socket, page, offset, size, |
| 868 | flags); | ||
| 869 | 869 | ||
| 870 | lock_sock(sk); | 870 | lock_sock(sk); |
| 871 | TCP_CHECK_TIMER(sk); | 871 | TCP_CHECK_TIMER(sk); |
| @@ -899,10 +899,9 @@ static inline int select_size(struct sock *sk, int sg) | |||
| 899 | return tmp; | 899 | return tmp; |
| 900 | } | 900 | } |
| 901 | 901 | ||
| 902 | int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | 902 | int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
| 903 | size_t size) | 903 | size_t size) |
| 904 | { | 904 | { |
| 905 | struct sock *sk = sock->sk; | ||
| 906 | struct iovec *iov; | 905 | struct iovec *iov; |
| 907 | struct tcp_sock *tp = tcp_sk(sk); | 906 | struct tcp_sock *tp = tcp_sk(sk); |
| 908 | struct sk_buff *skb; | 907 | struct sk_buff *skb; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 44545e8e8c92..020766292bb0 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -2600,6 +2600,8 @@ struct proto tcp_prot = { | |||
| 2600 | .setsockopt = tcp_setsockopt, | 2600 | .setsockopt = tcp_setsockopt, |
| 2601 | .getsockopt = tcp_getsockopt, | 2601 | .getsockopt = tcp_getsockopt, |
| 2602 | .recvmsg = tcp_recvmsg, | 2602 | .recvmsg = tcp_recvmsg, |
| 2603 | .sendmsg = tcp_sendmsg, | ||
| 2604 | .sendpage = tcp_sendpage, | ||
| 2603 | .backlog_rcv = tcp_v4_do_rcv, | 2605 | .backlog_rcv = tcp_v4_do_rcv, |
| 2604 | .hash = inet_hash, | 2606 | .hash = inet_hash, |
| 2605 | .unhash = inet_unhash, | 2607 | .unhash = inet_unhash, |
| @@ -2618,6 +2620,7 @@ struct proto tcp_prot = { | |||
| 2618 | .twsk_prot = &tcp_timewait_sock_ops, | 2620 | .twsk_prot = &tcp_timewait_sock_ops, |
| 2619 | .rsk_prot = &tcp_request_sock_ops, | 2621 | .rsk_prot = &tcp_request_sock_ops, |
| 2620 | .h.hashinfo = &tcp_hashinfo, | 2622 | .h.hashinfo = &tcp_hashinfo, |
| 2623 | .no_autobind = true, | ||
| 2621 | #ifdef CONFIG_COMPAT | 2624 | #ifdef CONFIG_COMPAT |
| 2622 | .compat_setsockopt = compat_tcp_setsockopt, | 2625 | .compat_setsockopt = compat_tcp_setsockopt, |
| 2623 | .compat_getsockopt = compat_tcp_getsockopt, | 2626 | .compat_getsockopt = compat_tcp_getsockopt, |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index e830cd4f9d0f..56b9bf2516f4 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
| @@ -522,10 +522,10 @@ const struct proto_ops inet6_stream_ops = { | |||
| 522 | .shutdown = inet_shutdown, /* ok */ | 522 | .shutdown = inet_shutdown, /* ok */ |
| 523 | .setsockopt = sock_common_setsockopt, /* ok */ | 523 | .setsockopt = sock_common_setsockopt, /* ok */ |
| 524 | .getsockopt = sock_common_getsockopt, /* ok */ | 524 | .getsockopt = sock_common_getsockopt, /* ok */ |
| 525 | .sendmsg = tcp_sendmsg, /* ok */ | 525 | .sendmsg = inet_sendmsg, /* ok */ |
| 526 | .recvmsg = sock_common_recvmsg, /* ok */ | 526 | .recvmsg = inet_recvmsg, /* ok */ |
| 527 | .mmap = sock_no_mmap, | 527 | .mmap = sock_no_mmap, |
| 528 | .sendpage = tcp_sendpage, | 528 | .sendpage = inet_sendpage, |
| 529 | .splice_read = tcp_splice_read, | 529 | .splice_read = tcp_splice_read, |
| 530 | #ifdef CONFIG_COMPAT | 530 | #ifdef CONFIG_COMPAT |
| 531 | .compat_setsockopt = compat_sock_common_setsockopt, | 531 | .compat_setsockopt = compat_sock_common_setsockopt, |
| @@ -549,7 +549,7 @@ const struct proto_ops inet6_dgram_ops = { | |||
| 549 | .setsockopt = sock_common_setsockopt, /* ok */ | 549 | .setsockopt = sock_common_setsockopt, /* ok */ |
| 550 | .getsockopt = sock_common_getsockopt, /* ok */ | 550 | .getsockopt = sock_common_getsockopt, /* ok */ |
| 551 | .sendmsg = inet_sendmsg, /* ok */ | 551 | .sendmsg = inet_sendmsg, /* ok */ |
| 552 | .recvmsg = sock_common_recvmsg, /* ok */ | 552 | .recvmsg = inet_recvmsg, /* ok */ |
| 553 | .mmap = sock_no_mmap, | 553 | .mmap = sock_no_mmap, |
| 554 | .sendpage = sock_no_sendpage, | 554 | .sendpage = sock_no_sendpage, |
| 555 | #ifdef CONFIG_COMPAT | 555 | #ifdef CONFIG_COMPAT |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5ebc27ecebdc..fe6d40418c0b 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -2142,6 +2142,8 @@ struct proto tcpv6_prot = { | |||
| 2142 | .setsockopt = tcp_setsockopt, | 2142 | .setsockopt = tcp_setsockopt, |
| 2143 | .getsockopt = tcp_getsockopt, | 2143 | .getsockopt = tcp_getsockopt, |
| 2144 | .recvmsg = tcp_recvmsg, | 2144 | .recvmsg = tcp_recvmsg, |
| 2145 | .sendmsg = tcp_sendmsg, | ||
| 2146 | .sendpage = tcp_sendpage, | ||
| 2145 | .backlog_rcv = tcp_v6_do_rcv, | 2147 | .backlog_rcv = tcp_v6_do_rcv, |
| 2146 | .hash = tcp_v6_hash, | 2148 | .hash = tcp_v6_hash, |
| 2147 | .unhash = inet_unhash, | 2149 | .unhash = inet_unhash, |
| @@ -2160,6 +2162,7 @@ struct proto tcpv6_prot = { | |||
| 2160 | .twsk_prot = &tcp6_timewait_sock_ops, | 2162 | .twsk_prot = &tcp6_timewait_sock_ops, |
| 2161 | .rsk_prot = &tcp6_request_sock_ops, | 2163 | .rsk_prot = &tcp6_request_sock_ops, |
| 2162 | .h.hashinfo = &tcp_hashinfo, | 2164 | .h.hashinfo = &tcp_hashinfo, |
| 2165 | .no_autobind = true, | ||
| 2163 | #ifdef CONFIG_COMPAT | 2166 | #ifdef CONFIG_COMPAT |
| 2164 | .compat_setsockopt = compat_tcp_setsockopt, | 2167 | .compat_setsockopt = compat_tcp_setsockopt, |
| 2165 | .compat_getsockopt = compat_tcp_getsockopt, | 2168 | .compat_getsockopt = compat_tcp_getsockopt, |
