forked from mirrors/linux
		
	mptcp: Use 32-bit DATA_ACK when possible
RFC8684 allows to send 32-bit DATA_ACKs as long as the peer is not sending 64-bit data-sequence numbers. The 64-bit DSN is only there for extreme scenarios when a very high throughput subflow is combined with a long-RTT subflow such that the high-throughput subflow wraps around the 32-bit sequence number space within an RTT of the high-RTT subflow. It is thus a rare scenario and we should try to use the 32-bit DATA_ACK instead as long as possible. It allows to reduce the TCP-option overhead by 4 bytes, thus makes space for an additional SACK-block. It also makes tcpdumps much easier to read when the DSN and DATA_ACK are both either 32 or 64-bit. Signed-off-by: Christoph Paasch <cpaasch@apple.com> Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									9efd6a3cec
								
							
						
					
					
						commit
						a0c1d0eafd
					
				
					 4 changed files with 31 additions and 10 deletions
				
			
		|  | @ -16,7 +16,10 @@ struct seq_file; | |||
| 
 | ||||
| /* MPTCP sk_buff extension data */ | ||||
| struct mptcp_ext { | ||||
| 	union { | ||||
| 		u64	data_ack; | ||||
| 		u32	data_ack32; | ||||
| 	}; | ||||
| 	u64		data_seq; | ||||
| 	u32		subflow_seq; | ||||
| 	u16		data_len; | ||||
|  |  | |||
|  | @ -516,7 +516,16 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, | |||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	if (subflow->use_64bit_ack) { | ||||
| 		ack_size = TCPOLEN_MPTCP_DSS_ACK64; | ||||
| 		opts->ext_copy.data_ack = msk->ack_seq; | ||||
| 		opts->ext_copy.ack64 = 1; | ||||
| 	} else { | ||||
| 		ack_size = TCPOLEN_MPTCP_DSS_ACK32; | ||||
| 		opts->ext_copy.data_ack32 = (uint32_t)(msk->ack_seq); | ||||
| 		opts->ext_copy.ack64 = 0; | ||||
| 	} | ||||
| 	opts->ext_copy.use_ack = 1; | ||||
| 
 | ||||
| 	/* Add kind/length/subtype/flag overhead if mapping is not populated */ | ||||
| 	if (dss_size == 0) | ||||
|  | @ -524,10 +533,6 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, | |||
| 
 | ||||
| 	dss_size += ack_size; | ||||
| 
 | ||||
| 	opts->ext_copy.data_ack = msk->ack_seq; | ||||
| 	opts->ext_copy.ack64 = 1; | ||||
| 	opts->ext_copy.use_ack = 1; | ||||
| 
 | ||||
| 	*size = ALIGN(dss_size, 4); | ||||
| 	return true; | ||||
| } | ||||
|  | @ -986,8 +991,13 @@ void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts) | |||
| 		u8 flags = 0; | ||||
| 
 | ||||
| 		if (mpext->use_ack) { | ||||
| 			flags = MPTCP_DSS_HAS_ACK; | ||||
| 			if (mpext->ack64) { | ||||
| 				len += TCPOLEN_MPTCP_DSS_ACK64; | ||||
| 			flags = MPTCP_DSS_HAS_ACK | MPTCP_DSS_ACK64; | ||||
| 				flags |= MPTCP_DSS_ACK64; | ||||
| 			} else { | ||||
| 				len += TCPOLEN_MPTCP_DSS_ACK32; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (mpext->use_map) { | ||||
|  | @ -1004,8 +1014,13 @@ void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts) | |||
| 		*ptr++ = mptcp_option(MPTCPOPT_DSS, len, 0, flags); | ||||
| 
 | ||||
| 		if (mpext->use_ack) { | ||||
| 			if (mpext->ack64) { | ||||
| 				put_unaligned_be64(mpext->data_ack, ptr); | ||||
| 				ptr += 2; | ||||
| 			} else { | ||||
| 				put_unaligned_be32(mpext->data_ack32, ptr); | ||||
| 				ptr += 1; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (mpext->use_map) { | ||||
|  |  | |||
|  | @ -290,6 +290,7 @@ struct mptcp_subflow_context { | |||
| 		data_avail : 1, | ||||
| 		rx_eof : 1, | ||||
| 		data_fin_tx_enable : 1, | ||||
| 		use_64bit_ack : 1, /* Set when we received a 64-bit DSN */ | ||||
| 		can_ack : 1;	    /* only after processing the remote a key */ | ||||
| 	u64	data_fin_tx_seq; | ||||
| 	u32	remote_nonce; | ||||
|  |  | |||
|  | @ -667,9 +667,11 @@ static enum mapping_status get_mapping_status(struct sock *ssk) | |||
| 	if (!mpext->dsn64) { | ||||
| 		map_seq = expand_seq(subflow->map_seq, subflow->map_data_len, | ||||
| 				     mpext->data_seq); | ||||
| 		subflow->use_64bit_ack = 0; | ||||
| 		pr_debug("expanded seq=%llu", subflow->map_seq); | ||||
| 	} else { | ||||
| 		map_seq = mpext->data_seq; | ||||
| 		subflow->use_64bit_ack = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (subflow->map_valid) { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Christoph Paasch
						Christoph Paasch