Commit 7ba42910 authored by Changli Gao's avatar Changli Gao Committed by David S. Miller

inet, inet6: make tcp_sendmsg() and tcp_sendpage() through inet_sendmsg() and inet_sendpage()

a new boolean flag no_autobind is added to structure proto to avoid the autobind
calls when the protocol is TCP. Then sock_rps_record_flow() is called int the
TCP's sendmsg() and sendpage() pathes.
Signed-off-by: default avatarChangli Gao <xiaosuo@gmail.com>
----
 include/net/inet_common.h |    4 ++++
 include/net/sock.h        |    1 +
 include/net/tcp.h         |    8 ++++----
 net/ipv4/af_inet.c        |   15 +++++++++------
 net/ipv4/tcp.c            |   11 +++++------
 net/ipv4/tcp_ipv4.c       |    3 +++
 net/ipv6/af_inet6.c       |    8 ++++----
 net/ipv6/tcp_ipv6.c       |    3 +++
 8 files changed, 33 insertions(+), 20 deletions(-)
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 53d3176b
...@@ -21,6 +21,10 @@ extern int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr, ...@@ -21,6 +21,10 @@ extern int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
extern int inet_accept(struct socket *sock, struct socket *newsock, int flags); extern int inet_accept(struct socket *sock, struct socket *newsock, int flags);
extern int inet_sendmsg(struct kiocb *iocb, struct socket *sock, extern int inet_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size); struct msghdr *msg, size_t size);
extern ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,
size_t size, int flags);
extern int inet_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags);
extern int inet_shutdown(struct socket *sock, int how); extern int inet_shutdown(struct socket *sock, int how);
extern int inet_listen(struct socket *sock, int backlog); extern int inet_listen(struct socket *sock, int backlog);
extern void inet_sock_destruct(struct sock *sk); extern void inet_sock_destruct(struct sock *sk);
......
...@@ -772,6 +772,7 @@ struct proto { ...@@ -772,6 +772,7 @@ struct proto {
int *sysctl_wmem; int *sysctl_wmem;
int *sysctl_rmem; int *sysctl_rmem;
int max_header; int max_header;
bool no_autobind;
struct kmem_cache *slab; struct kmem_cache *slab;
unsigned int obj_size; unsigned int obj_size;
......
...@@ -304,10 +304,10 @@ extern int tcp_v4_rcv(struct sk_buff *skb); ...@@ -304,10 +304,10 @@ extern int tcp_v4_rcv(struct sk_buff *skb);
extern int tcp_v4_remember_stamp(struct sock *sk); extern int tcp_v4_remember_stamp(struct sock *sk);
extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw); extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw);
extern int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
struct msghdr *msg, size_t size); size_t size);
extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, extern int tcp_sendpage(struct sock *sk, struct page *page, int offset,
size_t size, int flags); size_t size, int flags);
extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg);
extern int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, extern int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
struct tcphdr *th, unsigned len); struct tcphdr *th, unsigned len);
......
...@@ -727,28 +727,31 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, ...@@ -727,28 +727,31 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
sock_rps_record_flow(sk); sock_rps_record_flow(sk);
/* We may need to bind the socket. */ /* We may need to bind the socket. */
if (!inet_sk(sk)->inet_num && inet_autobind(sk)) if (!inet_sk(sk)->inet_num && !sk->sk_prot->no_autobind &&
inet_autobind(sk))
return -EAGAIN; return -EAGAIN;
return sk->sk_prot->sendmsg(iocb, sk, msg, size); return sk->sk_prot->sendmsg(iocb, sk, msg, size);
} }
EXPORT_SYMBOL(inet_sendmsg); EXPORT_SYMBOL(inet_sendmsg);
static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,
size_t size, int flags) size_t size, int flags)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
sock_rps_record_flow(sk); sock_rps_record_flow(sk);
/* We may need to bind the socket. */ /* We may need to bind the socket. */
if (!inet_sk(sk)->inet_num && inet_autobind(sk)) if (!inet_sk(sk)->inet_num && !sk->sk_prot->no_autobind &&
inet_autobind(sk))
return -EAGAIN; return -EAGAIN;
if (sk->sk_prot->sendpage) if (sk->sk_prot->sendpage)
return sk->sk_prot->sendpage(sk, page, offset, size, flags); return sk->sk_prot->sendpage(sk, page, offset, size, flags);
return sock_no_sendpage(sock, page, offset, size, flags); return sock_no_sendpage(sock, page, offset, size, flags);
} }
EXPORT_SYMBOL(inet_sendpage);
int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
size_t size, int flags) size_t size, int flags)
...@@ -894,10 +897,10 @@ const struct proto_ops inet_stream_ops = { ...@@ -894,10 +897,10 @@ const struct proto_ops inet_stream_ops = {
.shutdown = inet_shutdown, .shutdown = inet_shutdown,
.setsockopt = sock_common_setsockopt, .setsockopt = sock_common_setsockopt,
.getsockopt = sock_common_getsockopt, .getsockopt = sock_common_getsockopt,
.sendmsg = tcp_sendmsg, .sendmsg = inet_sendmsg,
.recvmsg = inet_recvmsg, .recvmsg = inet_recvmsg,
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
.sendpage = tcp_sendpage, .sendpage = inet_sendpage,
.splice_read = tcp_splice_read, .splice_read = tcp_splice_read,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_setsockopt = compat_sock_common_setsockopt, .compat_setsockopt = compat_sock_common_setsockopt,
......
...@@ -857,15 +857,15 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse ...@@ -857,15 +857,15 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse
return sk_stream_error(sk, flags, err); return sk_stream_error(sk, flags, err);
} }
ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, int tcp_sendpage(struct sock *sk, struct page *page, int offset,
size_t size, int flags) size_t size, int flags)
{ {
ssize_t res; ssize_t res;
struct sock *sk = sock->sk;
if (!(sk->sk_route_caps & NETIF_F_SG) || if (!(sk->sk_route_caps & NETIF_F_SG) ||
!(sk->sk_route_caps & NETIF_F_ALL_CSUM)) !(sk->sk_route_caps & NETIF_F_ALL_CSUM))
return sock_no_sendpage(sock, page, offset, size, flags); return sock_no_sendpage(sk->sk_socket, page, offset, size,
flags);
lock_sock(sk); lock_sock(sk);
TCP_CHECK_TIMER(sk); TCP_CHECK_TIMER(sk);
...@@ -899,10 +899,9 @@ static inline int select_size(struct sock *sk, int sg) ...@@ -899,10 +899,9 @@ static inline int select_size(struct sock *sk, int sg)
return tmp; return tmp;
} }
int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t size) size_t size)
{ {
struct sock *sk = sock->sk;
struct iovec *iov; struct iovec *iov;
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb; struct sk_buff *skb;
......
...@@ -2600,6 +2600,8 @@ struct proto tcp_prot = { ...@@ -2600,6 +2600,8 @@ struct proto tcp_prot = {
.setsockopt = tcp_setsockopt, .setsockopt = tcp_setsockopt,
.getsockopt = tcp_getsockopt, .getsockopt = tcp_getsockopt,
.recvmsg = tcp_recvmsg, .recvmsg = tcp_recvmsg,
.sendmsg = tcp_sendmsg,
.sendpage = tcp_sendpage,
.backlog_rcv = tcp_v4_do_rcv, .backlog_rcv = tcp_v4_do_rcv,
.hash = inet_hash, .hash = inet_hash,
.unhash = inet_unhash, .unhash = inet_unhash,
...@@ -2618,6 +2620,7 @@ struct proto tcp_prot = { ...@@ -2618,6 +2620,7 @@ struct proto tcp_prot = {
.twsk_prot = &tcp_timewait_sock_ops, .twsk_prot = &tcp_timewait_sock_ops,
.rsk_prot = &tcp_request_sock_ops, .rsk_prot = &tcp_request_sock_ops,
.h.hashinfo = &tcp_hashinfo, .h.hashinfo = &tcp_hashinfo,
.no_autobind = true,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_setsockopt = compat_tcp_setsockopt, .compat_setsockopt = compat_tcp_setsockopt,
.compat_getsockopt = compat_tcp_getsockopt, .compat_getsockopt = compat_tcp_getsockopt,
......
...@@ -522,10 +522,10 @@ const struct proto_ops inet6_stream_ops = { ...@@ -522,10 +522,10 @@ const struct proto_ops inet6_stream_ops = {
.shutdown = inet_shutdown, /* ok */ .shutdown = inet_shutdown, /* ok */
.setsockopt = sock_common_setsockopt, /* ok */ .setsockopt = sock_common_setsockopt, /* ok */
.getsockopt = sock_common_getsockopt, /* ok */ .getsockopt = sock_common_getsockopt, /* ok */
.sendmsg = tcp_sendmsg, /* ok */ .sendmsg = inet_sendmsg, /* ok */
.recvmsg = sock_common_recvmsg, /* ok */ .recvmsg = inet_recvmsg, /* ok */
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
.sendpage = tcp_sendpage, .sendpage = inet_sendpage,
.splice_read = tcp_splice_read, .splice_read = tcp_splice_read,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_setsockopt = compat_sock_common_setsockopt, .compat_setsockopt = compat_sock_common_setsockopt,
...@@ -549,7 +549,7 @@ const struct proto_ops inet6_dgram_ops = { ...@@ -549,7 +549,7 @@ const struct proto_ops inet6_dgram_ops = {
.setsockopt = sock_common_setsockopt, /* ok */ .setsockopt = sock_common_setsockopt, /* ok */
.getsockopt = sock_common_getsockopt, /* ok */ .getsockopt = sock_common_getsockopt, /* ok */
.sendmsg = inet_sendmsg, /* ok */ .sendmsg = inet_sendmsg, /* ok */
.recvmsg = sock_common_recvmsg, /* ok */ .recvmsg = inet_recvmsg, /* ok */
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
.sendpage = sock_no_sendpage, .sendpage = sock_no_sendpage,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
......
...@@ -2142,6 +2142,8 @@ struct proto tcpv6_prot = { ...@@ -2142,6 +2142,8 @@ struct proto tcpv6_prot = {
.setsockopt = tcp_setsockopt, .setsockopt = tcp_setsockopt,
.getsockopt = tcp_getsockopt, .getsockopt = tcp_getsockopt,
.recvmsg = tcp_recvmsg, .recvmsg = tcp_recvmsg,
.sendmsg = tcp_sendmsg,
.sendpage = tcp_sendpage,
.backlog_rcv = tcp_v6_do_rcv, .backlog_rcv = tcp_v6_do_rcv,
.hash = tcp_v6_hash, .hash = tcp_v6_hash,
.unhash = inet_unhash, .unhash = inet_unhash,
...@@ -2160,6 +2162,7 @@ struct proto tcpv6_prot = { ...@@ -2160,6 +2162,7 @@ struct proto tcpv6_prot = {
.twsk_prot = &tcp6_timewait_sock_ops, .twsk_prot = &tcp6_timewait_sock_ops,
.rsk_prot = &tcp6_request_sock_ops, .rsk_prot = &tcp6_request_sock_ops,
.h.hashinfo = &tcp_hashinfo, .h.hashinfo = &tcp_hashinfo,
.no_autobind = true,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_setsockopt = compat_tcp_setsockopt, .compat_setsockopt = compat_tcp_setsockopt,
.compat_getsockopt = compat_tcp_getsockopt, .compat_getsockopt = compat_tcp_getsockopt,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment