History

tcp: allow MPTCP to update the announced window

The MPTCP RFC requires that the MPTCP-level receive window's right edge never moves backward. Currently the MPTCP code enforces such constraint while tracking the right edge, but it does not reflects it on the wire, as MPTCP lacks a suitable hook to update accordingly the TCP header. This change modifies the existing mptcp_write_options() hook, providing the current packet's TCP header to the MPTCP protocol, so that the next patch could implement the above mentioned constraint. No functional changes intended.

Paolo Abeni committed 4 years ago

Commit ea667581 parent 92be2f53 files · +10 −8Browse files

Unified · Split

3 files
  1. include/net/mptcp.h +1 −1
  2. net/ipv4/tcp_output.c +8 −6
  3. net/mptcp/options.c +1 −1
include/net/mptcp.h+1−1
@@ -125,7 +125,7 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, · 124 unmodified lines
125 struct mptcp_out_options *opts);125 struct mptcp_out_options *opts);
126bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb);126bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb);
127 127
128void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,128void mptcp_write_options(struct tcphdr *th, __be32 *ptr, struct tcp_sock *tp,
129 struct mptcp_out_options *opts);129 struct mptcp_out_options *opts);
130 130
131void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info);131void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info);
net/ipv4/tcp_output.c+8−6
@@ -445,12 +445,13 @@ struct tcp_out_options { · 444 unmodified lines
445 struct mptcp_out_options mptcp;445 struct mptcp_out_options mptcp;
446};446};
447 447
448static void mptcp_options_write(__be32 *ptr, const struct tcp_sock *tp,448static void mptcp_options_write(struct tcphdr *th, __be32 *ptr,
449 struct tcp_sock *tp,
449 struct tcp_out_options *opts)450 struct tcp_out_options *opts)
450{451{
451#if IS_ENABLED(CONFIG_MPTCP)452#if IS_ENABLED(CONFIG_MPTCP)
452 if (unlikely(OPTION_MPTCP & opts->options))453 if (unlikely(OPTION_MPTCP & opts->options))
453 mptcp_write_options(ptr, tp, &opts->mptcp);454 mptcp_write_options(th, ptr, tp, &opts->mptcp);
454#endif455#endif
455}456}
456 457
@@ -606,9 +607,10 @@ static void bpf_skops_write_hdr_opt(struct sock *sk, struct sk_buff *skb, · 149 unmodified lines
606 * At least SACK_PERM as the first option is known to lead to a disaster607 * At least SACK_PERM as the first option is known to lead to a disaster
607 * (but it may well be that other scenarios fail similarly).608 * (but it may well be that other scenarios fail similarly).
608 */609 */
609static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,610static void tcp_options_write(struct tcphdr *th, struct tcp_sock *tp,
610 struct tcp_out_options *opts)611 struct tcp_out_options *opts)
611{612{
613 __be32 *ptr = (__be32 *)(th + 1);
612 u16 options = opts->options; /* mungable copy */614 u16 options = opts->options; /* mungable copy */
613 615
614 if (unlikely(OPTION_MD5 & options)) {616 if (unlikely(OPTION_MD5 & options)) {
@@ -702,7 +704,7 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, · 87 unmodified lines
702 704
703 smc_options_write(ptr, &options);705 smc_options_write(ptr, &options);
704 706
705 mptcp_options_write(ptr, tp, opts);707 mptcp_options_write(th, ptr, tp, opts);
706}708}
707 709
708static void smc_set_option(const struct tcp_sock *tp,710static void smc_set_option(const struct tcp_sock *tp,
@@ -1355,7 +1357,7 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, · 646 unmodified lines
1355 th->window = htons(min(tp->rcv_wnd, 65535U));1357 th->window = htons(min(tp->rcv_wnd, 65535U));
1356 }1358 }
1357 1359
1358 tcp_options_write((__be32 *)(th + 1), tp, &opts);1360 tcp_options_write(th, tp, &opts);
1359 1361
1360#ifdef CONFIG_TCP_MD5SIG1362#ifdef CONFIG_TCP_MD5SIG
1361 /* Calculate the MD5 hash, as we have all we need now */1363 /* Calculate the MD5 hash, as we have all we need now */
@@ -3591,7 +3593,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, · 2229 unmodified lines
3591 3593
3592 /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */3594 /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
3593 th->window = htons(min(req->rsk_rcv_wnd, 65535U));3595 th->window = htons(min(req->rsk_rcv_wnd, 65535U));
3594 tcp_options_write((__be32 *)(th + 1), NULL, &opts);3596 tcp_options_write(th, NULL, &opts);
3595 th->doff = (tcp_header_size >> 2);3597 th->doff = (tcp_header_size >> 2);
3596 __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);3598 __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
3597 3599
net/mptcp/options.c+1−1
@@ -1265,7 +1265,7 @@ static u16 mptcp_make_csum(const struct mptcp_ext *mpext) · 1264 unmodified lines
1265 ~csum_unfold(mpext->csum));1265 ~csum_unfold(mpext->csum));
1266}1266}
1267 1267
1268void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,1268void mptcp_write_options(struct tcphdr *th, __be32 *ptr, struct tcp_sock *tp,
1269 struct mptcp_out_options *opts)1269 struct mptcp_out_options *opts)
1270{1270{
1271 const struct sock *ssk = (const struct sock *)tp;1271 const struct sock *ssk = (const struct sock *)tp;