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: Changli 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: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
53d3176b28
commit
7ba4291007
8 changed files with 33 additions and 20 deletions
|
@ -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_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||
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_listen(struct socket *sock, int backlog);
|
||||
extern void inet_sock_destruct(struct sock *sk);
|
||||
|
|
|
@ -772,6 +772,7 @@ struct proto {
|
|||
int *sysctl_wmem;
|
||||
int *sysctl_rmem;
|
||||
int max_header;
|
||||
bool no_autobind;
|
||||
|
||||
struct kmem_cache *slab;
|
||||
unsigned int obj_size;
|
||||
|
|
|
@ -304,9 +304,9 @@ extern int tcp_v4_rcv(struct sk_buff *skb);
|
|||
|
||||
extern int tcp_v4_remember_stamp(struct sock *sk);
|
||||
extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw);
|
||||
extern int tcp_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||
struct msghdr *msg, size_t size);
|
||||
extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset,
|
||||
extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
|
||||
size_t size);
|
||||
extern int tcp_sendpage(struct sock *sk, struct page *page, int offset,
|
||||
size_t size, int flags);
|
||||
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,
|
||||
|
|
|
@ -727,14 +727,15 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
|
|||
sock_rps_record_flow(sk);
|
||||
|
||||
/* 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 sk->sk_prot->sendmsg(iocb, sk, msg, size);
|
||||
}
|
||||
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)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
|
@ -742,13 +743,15 @@ static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,
|
|||
sock_rps_record_flow(sk);
|
||||
|
||||
/* 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;
|
||||
|
||||
if (sk->sk_prot->sendpage)
|
||||
return sk->sk_prot->sendpage(sk, 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,
|
||||
size_t size, int flags)
|
||||
|
@ -894,10 +897,10 @@ const struct proto_ops inet_stream_ops = {
|
|||
.shutdown = inet_shutdown,
|
||||
.setsockopt = sock_common_setsockopt,
|
||||
.getsockopt = sock_common_getsockopt,
|
||||
.sendmsg = tcp_sendmsg,
|
||||
.sendmsg = inet_sendmsg,
|
||||
.recvmsg = inet_recvmsg,
|
||||
.mmap = sock_no_mmap,
|
||||
.sendpage = tcp_sendpage,
|
||||
.sendpage = inet_sendpage,
|
||||
.splice_read = tcp_splice_read,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_sock_common_setsockopt,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ssize_t res;
|
||||
struct sock *sk = sock->sk;
|
||||
|
||||
if (!(sk->sk_route_caps & NETIF_F_SG) ||
|
||||
!(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);
|
||||
TCP_CHECK_TIMER(sk);
|
||||
|
@ -899,10 +899,9 @@ static inline int select_size(struct sock *sk, int sg)
|
|||
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)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct iovec *iov;
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
struct sk_buff *skb;
|
||||
|
|
|
@ -2600,6 +2600,8 @@ struct proto tcp_prot = {
|
|||
.setsockopt = tcp_setsockopt,
|
||||
.getsockopt = tcp_getsockopt,
|
||||
.recvmsg = tcp_recvmsg,
|
||||
.sendmsg = tcp_sendmsg,
|
||||
.sendpage = tcp_sendpage,
|
||||
.backlog_rcv = tcp_v4_do_rcv,
|
||||
.hash = inet_hash,
|
||||
.unhash = inet_unhash,
|
||||
|
@ -2618,6 +2620,7 @@ struct proto tcp_prot = {
|
|||
.twsk_prot = &tcp_timewait_sock_ops,
|
||||
.rsk_prot = &tcp_request_sock_ops,
|
||||
.h.hashinfo = &tcp_hashinfo,
|
||||
.no_autobind = true,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_tcp_setsockopt,
|
||||
.compat_getsockopt = compat_tcp_getsockopt,
|
||||
|
|
|
@ -522,10 +522,10 @@ const struct proto_ops inet6_stream_ops = {
|
|||
.shutdown = inet_shutdown, /* ok */
|
||||
.setsockopt = sock_common_setsockopt, /* ok */
|
||||
.getsockopt = sock_common_getsockopt, /* ok */
|
||||
.sendmsg = tcp_sendmsg, /* ok */
|
||||
.recvmsg = sock_common_recvmsg, /* ok */
|
||||
.sendmsg = inet_sendmsg, /* ok */
|
||||
.recvmsg = inet_recvmsg, /* ok */
|
||||
.mmap = sock_no_mmap,
|
||||
.sendpage = tcp_sendpage,
|
||||
.sendpage = inet_sendpage,
|
||||
.splice_read = tcp_splice_read,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_sock_common_setsockopt,
|
||||
|
@ -549,7 +549,7 @@ const struct proto_ops inet6_dgram_ops = {
|
|||
.setsockopt = sock_common_setsockopt, /* ok */
|
||||
.getsockopt = sock_common_getsockopt, /* ok */
|
||||
.sendmsg = inet_sendmsg, /* ok */
|
||||
.recvmsg = sock_common_recvmsg, /* ok */
|
||||
.recvmsg = inet_recvmsg, /* ok */
|
||||
.mmap = sock_no_mmap,
|
||||
.sendpage = sock_no_sendpage,
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
|
|
@ -2142,6 +2142,8 @@ struct proto tcpv6_prot = {
|
|||
.setsockopt = tcp_setsockopt,
|
||||
.getsockopt = tcp_getsockopt,
|
||||
.recvmsg = tcp_recvmsg,
|
||||
.sendmsg = tcp_sendmsg,
|
||||
.sendpage = tcp_sendpage,
|
||||
.backlog_rcv = tcp_v6_do_rcv,
|
||||
.hash = tcp_v6_hash,
|
||||
.unhash = inet_unhash,
|
||||
|
@ -2160,6 +2162,7 @@ struct proto tcpv6_prot = {
|
|||
.twsk_prot = &tcp6_timewait_sock_ops,
|
||||
.rsk_prot = &tcp6_request_sock_ops,
|
||||
.h.hashinfo = &tcp_hashinfo,
|
||||
.no_autobind = true,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_tcp_setsockopt,
|
||||
.compat_getsockopt = compat_tcp_getsockopt,
|
||||
|
|
Loading…
Reference in a new issue