net: Add sock_common_listen for TCP and DCCP
Subsystems (5)
PATCH v2 1/1 net: Add sock_common_listen for TCP and DCCP
Code refactoring:
1. Move the common code of inet_listen() and inet_dccp_listen() to sock_common_listen().
2. Modify and rename inet_listen() to tcp_listen().
3. Modify and rename inet_dccp_listen() to dccp_listen().
4. Add new callback pointer listen in struct proto for tcp_listen() and dccp_listen().
This patch makes codes more modularized and removes redudant codes.
---
v2:
In according to the advices of Eric Dumazet, sock_common_listen() keep using TCP_xxx state instead of introducing new aliases.
Test info:
I test it on my x86 PC.
include/net/sock.h | 3 +++ include/net/tcp.h | 1 + net/core/sock.c | 39 +++++++++++++++++++++++++++++++++ net/dccp/dccp.h | 2 +- net/dccp/ipv4.c | 4 ++-- net/dccp/ipv6.c | 3 ++- net/dccp/proto.c | 62 ++++++++++++++++------------------------------------- net/ipv4/af_inet.c | 58 +------------------------------------------------ net/ipv4/tcp.c | 35 ++++++++++++++++++++++++++++++ net/ipv4/tcp_ipv4.c | 1 + net/ipv6/af_inet6.c | 2 +- net/ipv6/tcp_ipv6.c | 1 + 12 files changed, 106 insertions(+), 105 deletions(-)
include/net/sock.h +3 -0
@@ -934,6 +934,7 @@ struct proto {int (*connect)(struct sock *sk,struct sockaddr *uaddr,int addr_len); +int (*listen)(struct sock *sk,int backlog);int (*disconnect)(struct sock *sk,int flags);struct sock * (*accept)(struct sock *sk,int flags,int *err);
@@ -1587,6 +1588,8 @@ int compat_sock_common_setsockopt(struct socket *sock, int level,void sk_common_release (struct sock *sk); +int sock_common_listen (struct socket *sock,int backlog); +/* * Default socket callbacks and setup code */
include/net/tcp.h +1 -0
@@ -434,6 +434,7 @@ int compat_tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen);void tcp_set_keepalive (struct sock *sk,int val);void tcp_syn_ack_timeout (const struct request_sock *req); +int tcp_listen (struct sock *sk,int backlog);int tcp_recvmsg (struct sock *sk,struct msghdr *msg,size_t len,int nonblock,int flags,int *addr_len); void tcp_parse_options(const struct sk_buff *skb,
net/core/sock.c +39 -0
@@ -2559,6 +2559,45 @@ int sock_common_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,EXPORT_SYMBOL (sock_common_recvmsg);/* +* Move a socket into listening state. +*/ +int sock_common_listen (struct socket *sock,int backlog) +{ +struct sock *sk = sock->sk; +unsigned char old_state; +int err; + +lock_sock (sk); + + err = -EINVAL ; +if (sock->state !=SS_UNCONNECTED ) + goto out; + + old_state = sk->sk_state; +/* Since DCCP used the same state value as TCP, here we +* just check the TCP version state. +*/ +if (!((1 << old_state) & (TCPF_CLOSE |TCPF_LISTEN ))) + goto out; + +/* Really, if the socket is already in listen state +* we can only allow the backlog to be adjusted. +*/ +if (old_state !=TCP_LISTEN ) { + err = sk->sk_prot->listen (sk, backlog); +if (err) + goto out; + } + sk->sk_max_ack_backlog = backlog; + err =0 ; + +out: +release_sock (sk); +return err; +} +EXPORT_SYMBOL (sock_common_listen); + +/* * Set socket options on an inet socket. */ int sock_common_setsockopt(struct socket *sock, int level, int optname,
net/dccp/dccp.h +1 -1
@@ -313,7 +313,7 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);int dccp_recvmsg (struct sock *sk,struct msghdr *msg,size_t len,int nonblock,int flags,int *addr_len);void dccp_shutdown (struct sock *sk,int how); -int inet_dccp_listen (struct socket *sock,int backlog); +int dccp_listen (struct sock *sk,int backlog);unsigned int dccp_poll (struct file *file,struct socket *sock,poll_table *wait);int dccp_v4_connect (struct sock *sk,struct sockaddr *uaddr,int addr_len);
net/dccp/ipv4.c +2 -2
@@ -952,6 +952,7 @@ static struct proto dccp_v4_prot = { .name = "DCCP", .owner = THIS_MODULE, .close = dccp_close, + .listen = dccp_listen, .connect = dccp_v4_connect, .disconnect = dccp_disconnect, .ioctl = dccp_ioctl,
@@ -1000,8 +1001,7 @@ static const struct proto_ops inet_dccp_ops = {/* FIXME: work on tcp_poll to rename it to inet_csk_poll */ .poll = dccp_poll, .ioctl = inet_ioctl, -/* FIXME: work on inet_listen to rename it to sock_common_listen */ - .listen = inet_dccp_listen, + .listen = sock_common_listen, .shutdown = inet_shutdown, .setsockopt = sock_common_setsockopt, .getsockopt = sock_common_getsockopt,
net/dccp/ipv6.c +2 -1
@@ -1011,6 +1011,7 @@ static struct proto dccp_v6_prot = { .name = "DCCPv6", .owner = THIS_MODULE, .close = dccp_close, + .listen = dccp_listen, .connect = dccp_v6_connect, .disconnect = dccp_disconnect, .ioctl = dccp_ioctl,
@@ -1056,7 +1057,7 @@ static const struct proto_ops inet6_dccp_ops = { .getname = inet6_getname, .poll = dccp_poll, .ioctl = inet6_ioctl, - .listen = inet_dccp_listen, + .listen = sock_common_listen, .shutdown = inet_shutdown, .setsockopt = sock_common_setsockopt, .getsockopt = sock_common_getsockopt,
net/dccp/proto.c +19 -43
80 lines not on this page · raw message
net/ipv4/af_inet.c +1 -57
70 lines not on this page · raw message
net/ipv4/tcp.c +35 -0
@@ -1301,6 +1301,41 @@ out_err: }EXPORT_SYMBOL (tcp_sendmsg); +int tcp_listen (struct sock *sk,int backlog) +{ +struct socket *sock = sk->sk_socket; +int err; + + err = -EINVAL ; +if (sock->type !=SOCK_STREAM ) + goto out; +/* Check special setups for testing purpose to enable TFO w/o +* requiring TCP_FASTOPEN sockopt. +* Note that only TCP sockets (SOCK_STREAM) will reach here. +* Also fastopenq may already been allocated because this +* socket was in TCP_LISTEN state previously but was +* shutdown() (rather than close()). +*/ +if ((sysctl_tcp_fastopen &TFO_SERVER_ENABLE ) !=0 && + !inet_csk (sk)->icsk_accept_queue.fastopenq) { +if ((sysctl_tcp_fastopen &TFO_SERVER_WO_SOCKOPT1 ) !=0 ) + err =fastopen_init_queue (sk, backlog); +else if ((sysctl_tcp_fastopen & +TFO_SERVER_WO_SOCKOPT2 ) !=0 ) + err =fastopen_init_queue (sk, + ((uint )sysctl_tcp_fastopen) >>16 ); +else + err =0 ; +if (err) + goto out; + } + err =inet_csk_listen_start (sk, backlog); + +out: +return err; +} +EXPORT_SYMBOL (tcp_listen); +/* * Handle reading urgent data. BSD has very simple semantics for * this, no blocking and very strange errors 8)
net/ipv4/tcp_ipv4.c +1 -0
@@ -2337,6 +2337,7 @@ struct proto tcp_prot = { .name = "TCP", .owner = THIS_MODULE, .close = tcp_close, + .listen = tcp_listen, .connect = tcp_v4_connect, .disconnect = tcp_disconnect, .accept = inet_csk_accept,
net/ipv6/af_inet6.c +1 -1
@@ -516,7 +516,7 @@ const struct proto_ops inet6_stream_ops = { .getname = inet6_getname, .poll = tcp_poll, /* ok */ .ioctl = inet6_ioctl, /* must change */ - .listen = inet_listen, /* ok */ + .listen = sock_common_listen, /* ok */ .shutdown = inet_shutdown, /* ok */ .setsockopt = sock_common_setsockopt, /* ok */ .getsockopt = sock_common_getsockopt, /* ok */
net/ipv6/tcp_ipv6.c +1 -0
@@ -1822,6 +1822,7 @@ struct proto tcpv6_prot = { .name = "TCPv6", .owner = THIS_MODULE, .close = tcp_close, + .listen = tcp_listen, .connect = tcp_v6_connect, .disconnect = tcp_disconnect, .accept = inet_csk_accept,
Signature · 1 line
2.4.3
David Miller
maintainerFrom: Firo Yang <[email protected]>
Date: Fri, 12 Jun 2015 12:57:57 +0800
Quoted 13 lines
Code refactoring:
1. Move the common code ofinet_listen()andinet_dccp_listen()tosock_common_listen().2. Modify and rename
inet_listen()totcp_listen().3. Modify and rename
inet_dccp_listen()todccp_listen().4. Add new callback pointer listen in struct proto for
tcp_listen()anddccp_listen().This patch makes codes more modularized and removes redudant codes.
Quoted 8 lines
Signed-off-by Firo Yang <[email protected]>---
v2:
In according to the advices of Eric Dumazet,sock_common_listen()keep usingTCP_xxxstate instead of introducing new aliases.Test info:
I test it on my x86 PC.
I don't think this is worthwhile, sorry.
Instead of having two straight line copies of a piece of logic, we now have three functions and a new callback. I'd rather have a single duplicate copy of a function than all of that.