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
Unified · Split
| @@ -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); |
| 73 | bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, | 73 | bool 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); |
| 75 | void mptcp_rcv_synsent(struct sock *sk); | ||
| 76 | bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, | 75 | bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, |
| 77 | struct mptcp_out_options *opts); | 76 | struct mptcp_out_options *opts); |
| 78 | bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, | 77 | bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, |
| @@ -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_seq | 5994 | * Change state from SYN-SENT only after copied_seq |
| 5998 | * is initialized. */ | 5995 | * is initialized. */ |
| @@ -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 | ||
| 347 | void 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 retransmissions | 349 | * MPTCP uses the delack timer to do 3rd ack retransmissions |
| @@ -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 { |
| 270 | do_reset: | 291 | do_reset: |