History

mptcp: consolidate synack processing.

Currently the MPTCP code uses 2 hooks to process syn-ack packets, mptcp_rcv_synsent() and the sk_rx_dst_set() callback. We can drop the first, moving the relevant code into the latter, reducing the hooking into the TCP code. This is also needed by the next patch. v1 -> v2: - use local tcp sock ptr instead of casting the sk variable several times - DaveM

Paolo Abeni committed 6 years ago

Commit 263e1201 parent 30724cc4 files · +24 −29Browse files

Unified · Split

4 files
  1. include/net/mptcp.h +0 −1
  2. net/ipv4/tcp_input.c +0 −3
  3. net/mptcp/options.c +0 −22
  4. net/mptcp/subflow.c +24 −3
include/net/mptcp.h+0−1
@@ -72,7 +72,6 @@ void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr, · 71 unmodified lines
72 int opsize, struct tcp_options_received *opt_rx);72 int opsize, struct tcp_options_received *opt_rx);
73bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,73bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
74 unsigned int *size, struct mptcp_out_options *opts);74 unsigned int *size, struct mptcp_out_options *opts);
75void mptcp_rcv_synsent(struct sock *sk);
76bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,75bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
77 struct mptcp_out_options *opts);76 struct mptcp_out_options *opts);
78bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,77bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
net/ipv4/tcp_input.c+0−3
@@ -5990,9 +5990,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, · 5989 unmodified lines
5990 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);5990 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
5991 tcp_initialize_rcv_mss(sk);5991 tcp_initialize_rcv_mss(sk);
5992 5992
5993 if (sk_is_mptcp(sk))
5994 mptcp_rcv_synsent(sk);
5995
5996 /* Remember, tcp_poll() does not lock socket!5993 /* Remember, tcp_poll() does not lock socket!
5997 * Change state from SYN-SENT only after copied_seq5994 * Change state from SYN-SENT only after copied_seq
5998 * is initialized. */5995 * is initialized. */
net/mptcp/options.c+0−22
@@ -344,28 +344,6 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, · 343 unmodified lines
344 return false;344 return false;
345}345}
346 346
347void mptcp_rcv_synsent(struct sock *sk)
348{
349 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
350 struct tcp_sock *tp = tcp_sk(sk);
351
352 if (subflow->request_mptcp && tp->rx_opt.mptcp.mp_capable) {
353 subflow->mp_capable = 1;
354 subflow->can_ack = 1;
355 subflow->remote_key = tp->rx_opt.mptcp.sndr_key;
356 pr_debug("subflow=%p, remote_key=%llu", subflow,
357 subflow->remote_key);
358 } else if (subflow->request_join && tp->rx_opt.mptcp.mp_join) {
359 subflow->mp_join = 1;
360 subflow->thmac = tp->rx_opt.mptcp.thmac;
361 subflow->remote_nonce = tp->rx_opt.mptcp.nonce;
362 pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", subflow,
363 subflow->thmac, subflow->remote_nonce);
364 } else if (subflow->request_mptcp) {
365 tcp_sk(sk)->is_mptcp = 0;
366 }
367}
368
369/* MP_JOIN client subflow must wait for 4th ack before sending any data:347/* MP_JOIN client subflow must wait for 4th ack before sending any data:
370 * TCP can't schedule delack timer before the subflow is fully established.348 * TCP can't schedule delack timer before the subflow is fully established.
371 * MPTCP uses the delack timer to do 3rd ack retransmissions349 * MPTCP uses the delack timer to do 3rd ack retransmissions
net/mptcp/subflow.c+24−3
@@ -222,6 +222,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) · 221 unmodified lines
222{222{
223 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);223 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
224 struct sock *parent = subflow->conn;224 struct sock *parent = subflow->conn;
225 struct tcp_sock *tp = tcp_sk(sk);
225 226
226 subflow->icsk_af_ops->sk_rx_dst_set(sk, skb);227 subflow->icsk_af_ops->sk_rx_dst_set(sk, skb);
227 228
@@ -230,14 +231,35 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) · 2 unmodified lines
230 parent->sk_state_change(parent);231 parent->sk_state_change(parent);
231 }232 }
232 233
233 if (subflow->conn_finished || !tcp_sk(sk)->is_mptcp)234 /* be sure no special action on any packet other than syn-ack */
235 if (subflow->conn_finished)
236 return;
237
238 subflow->conn_finished = 1;
239
240 if (subflow->request_mptcp && tp->rx_opt.mptcp.mp_capable) {
241 subflow->mp_capable = 1;
242 subflow->can_ack = 1;
243 subflow->remote_key = tp->rx_opt.mptcp.sndr_key;
244 pr_debug("subflow=%p, remote_key=%llu", subflow,
245 subflow->remote_key);
246 } else if (subflow->request_join && tp->rx_opt.mptcp.mp_join) {
247 subflow->mp_join = 1;
248 subflow->thmac = tp->rx_opt.mptcp.thmac;
249 subflow->remote_nonce = tp->rx_opt.mptcp.nonce;
250 pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", subflow,
251 subflow->thmac, subflow->remote_nonce);
252 } else if (subflow->request_mptcp) {
253 tp->is_mptcp = 0;
254 }
255
256 if (!tp->is_mptcp)
234 return;257 return;
235 258
236 if (subflow->mp_capable) {259 if (subflow->mp_capable) {
237 pr_debug("subflow=%p, remote_key=%llu", mptcp_subflow_ctx(sk),260 pr_debug("subflow=%p, remote_key=%llu", mptcp_subflow_ctx(sk),
238 subflow->remote_key);261 subflow->remote_key);
239 mptcp_finish_connect(sk);262 mptcp_finish_connect(sk);
240 subflow->conn_finished = 1;
241 263
242 if (skb) {264 if (skb) {
243 pr_debug("synack seq=%u", TCP_SKB_CB(skb)->seq);265 pr_debug("synack seq=%u", TCP_SKB_CB(skb)->seq);
@@ -264,7 +286,6 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) · 20 unmodified lines
264 if (!mptcp_finish_join(sk))286 if (!mptcp_finish_join(sk))
265 goto do_reset;287 goto do_reset;
266 288
267 subflow->conn_finished = 1;
268 MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX);289 MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX);
269 } else {290 } else {
270do_reset:291do_reset: