aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_minisocks.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-09-25 13:00:40 -0700
committerDavid S. Miller <davem@davemloft.net>2015-09-25 13:00:40 -0700
commit4d54d86546f62c7c4a0fe3b36a64c5e3b98ce1a9 (patch)
treebd48e072bacebb47bc6cd4ebb3483e9bd9da21b0 /net/ipv4/tcp_minisocks.c
parentnet: remove unused argument of __netdev_find_adj() (diff)
parentinet: constify inet_rtx_syn_ack() sock argument (diff)
downloadlinux-dev-4d54d86546f62c7c4a0fe3b36a64c5e3b98ce1a9.tar.xz
linux-dev-4d54d86546f62c7c4a0fe3b36a64c5e3b98ce1a9.zip
Merge branch 'listener-sock-const'
Eric Dumazet says: ==================== dccp/tcp: constify listener sock Another patch bomb to prepare lockless TCP/DCCP LISTEN handling. SYNACK retransmits are built and sent without listener socket being locked. Soon, initial SYNACK packets will have same property. This series makes sure we did not something wrong with this model, by adding a const qualifier in all the paths taken from synack building and transmit, for IPv4/IPv6 and TCP/dccp. The only potential problem was the rewrite of ecn bits for connections with DCTCP as congestion module, but this was a very minor one. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
-rw-r--r--net/ipv4/tcp_minisocks.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 85830bb92d04..e0a87c238882 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -362,27 +362,35 @@ void tcp_twsk_destructor(struct sock *sk)
}
EXPORT_SYMBOL_GPL(tcp_twsk_destructor);
+/* Warning : This function is called without sk_listener being locked.
+ * Be sure to read socket fields once, as their value could change under us.
+ */
void tcp_openreq_init_rwin(struct request_sock *req,
- struct sock *sk, struct dst_entry *dst)
+ const struct sock *sk_listener,
+ const struct dst_entry *dst)
{
struct inet_request_sock *ireq = inet_rsk(req);
- struct tcp_sock *tp = tcp_sk(sk);
- __u8 rcv_wscale;
+ const struct tcp_sock *tp = tcp_sk(sk_listener);
+ u16 user_mss = READ_ONCE(tp->rx_opt.user_mss);
+ int full_space = tcp_full_space(sk_listener);
int mss = dst_metric_advmss(dst);
+ u32 window_clamp;
+ __u8 rcv_wscale;
- if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)
- mss = tp->rx_opt.user_mss;
+ if (user_mss && user_mss < mss)
+ mss = user_mss;
+ window_clamp = READ_ONCE(tp->window_clamp);
/* Set this up on the first call only */
- req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW);
+ req->window_clamp = window_clamp ? : dst_metric(dst, RTAX_WINDOW);
/* limit the window selection if the user enforce a smaller rx buffer */
- if (sk->sk_userlocks & SOCK_RCVBUF_LOCK &&
- (req->window_clamp > tcp_full_space(sk) || req->window_clamp == 0))
- req->window_clamp = tcp_full_space(sk);
+ if (sk_listener->sk_userlocks & SOCK_RCVBUF_LOCK &&
+ (req->window_clamp > full_space || req->window_clamp == 0))
+ req->window_clamp = full_space;
/* tcp_full_space because it is guaranteed to be the first packet */
- tcp_select_initial_window(tcp_full_space(sk),
+ tcp_select_initial_window(full_space,
mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0),
&req->rcv_wnd,
&req->window_clamp,