aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/inet_common.h4
-rw-r--r--include/net/sock.h1
-rw-r--r--include/net/tcp.h8
-rw-r--r--net/ipv4/af_inet.c15
-rw-r--r--net/ipv4/tcp.c11
-rw-r--r--net/ipv4/tcp_ipv4.c3
-rw-r--r--net/ipv6/af_inet6.c8
-rw-r--r--net/ipv6/tcp_ipv6.c3
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,
21extern int inet_accept(struct socket *sock, struct socket *newsock, int flags); 21extern int inet_accept(struct socket *sock, struct socket *newsock, int flags);
22extern int inet_sendmsg(struct kiocb *iocb, struct socket *sock, 22extern int inet_sendmsg(struct kiocb *iocb, struct socket *sock,
23 struct msghdr *msg, size_t size); 23 struct msghdr *msg, size_t size);
24extern ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,
25 size_t size, int flags);
26extern int inet_recvmsg(struct kiocb *iocb, struct socket *sock,
27 struct msghdr *msg, size_t size, int flags);
24extern int inet_shutdown(struct socket *sock, int how); 28extern int inet_shutdown(struct socket *sock, int how);
25extern int inet_listen(struct socket *sock, int backlog); 29extern int inet_listen(struct socket *sock, int backlog);
26extern void inet_sock_destruct(struct sock *sk); 30extern 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
305extern int tcp_v4_remember_stamp(struct sock *sk); 305extern int tcp_v4_remember_stamp(struct sock *sk);
306extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw); 306extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw);
307extern int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, 307extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
308 struct msghdr *msg, size_t size); 308 size_t size);
309extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, 309extern int tcp_sendpage(struct sock *sk, struct page *page, int offset,
310 size_t size, int flags); 310 size_t size, int flags);
311extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); 311extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg);
312extern int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, 312extern 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}
735EXPORT_SYMBOL(inet_sendmsg); 736EXPORT_SYMBOL(inet_sendmsg);
736 737
737static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, 738ssize_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}
754EXPORT_SYMBOL(inet_sendpage);
752 755
753int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, 756int 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
860ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, 860int 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
902int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, 902int 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,