net-tcp: Fast Open client - cookie cache
With help from Eric Dumazet, add Fast Open metrics in tcp metrics cache. The basic ones are MSS and the cookies. Later patch will cache more to handle unfriendly middleboxes. Signed-off-by: Yuchung Cheng <ycheng@google.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
					parent
					
						
							
								2100c8d2d9
							
						
					
				
			
			
				commit
				
					
						1fe4c481ba
					
				
			
		
					 2 changed files with 55 additions and 0 deletions
				
			
		|  | @ -405,6 +405,10 @@ extern void tcp_metrics_init(void); | ||||||
| extern bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst, bool paws_check); | extern bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst, bool paws_check); | ||||||
| extern bool tcp_remember_stamp(struct sock *sk); | extern bool tcp_remember_stamp(struct sock *sk); | ||||||
| extern bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw); | extern bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw); | ||||||
|  | extern void tcp_fastopen_cache_get(struct sock *sk, u16 *mss, | ||||||
|  | 				   struct tcp_fastopen_cookie *cookie); | ||||||
|  | extern void tcp_fastopen_cache_set(struct sock *sk, u16 mss, | ||||||
|  | 				   struct tcp_fastopen_cookie *cookie); | ||||||
| extern void tcp_fetch_timewait_stamp(struct sock *sk, struct dst_entry *dst); | extern void tcp_fetch_timewait_stamp(struct sock *sk, struct dst_entry *dst); | ||||||
| extern void tcp_disable_fack(struct tcp_sock *tp); | extern void tcp_disable_fack(struct tcp_sock *tp); | ||||||
| extern void tcp_close(struct sock *sk, long timeout); | extern void tcp_close(struct sock *sk, long timeout); | ||||||
|  |  | ||||||
|  | @ -30,6 +30,11 @@ enum tcp_metric_index { | ||||||
| 	TCP_METRIC_MAX, | 	TCP_METRIC_MAX, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct tcp_fastopen_metrics { | ||||||
|  | 	u16	mss; | ||||||
|  | 	struct	tcp_fastopen_cookie	cookie; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| struct tcp_metrics_block { | struct tcp_metrics_block { | ||||||
| 	struct tcp_metrics_block __rcu	*tcpm_next; | 	struct tcp_metrics_block __rcu	*tcpm_next; | ||||||
| 	struct inetpeer_addr		tcpm_addr; | 	struct inetpeer_addr		tcpm_addr; | ||||||
|  | @ -38,6 +43,7 @@ struct tcp_metrics_block { | ||||||
| 	u32				tcpm_ts_stamp; | 	u32				tcpm_ts_stamp; | ||||||
| 	u32				tcpm_lock; | 	u32				tcpm_lock; | ||||||
| 	u32				tcpm_vals[TCP_METRIC_MAX]; | 	u32				tcpm_vals[TCP_METRIC_MAX]; | ||||||
|  | 	struct tcp_fastopen_metrics	tcpm_fastopen; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static bool tcp_metric_locked(struct tcp_metrics_block *tm, | static bool tcp_metric_locked(struct tcp_metrics_block *tm, | ||||||
|  | @ -118,6 +124,8 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm, struct dst_entry *dst) | ||||||
| 	tm->tcpm_vals[TCP_METRIC_REORDERING] = dst_metric_raw(dst, RTAX_REORDERING); | 	tm->tcpm_vals[TCP_METRIC_REORDERING] = dst_metric_raw(dst, RTAX_REORDERING); | ||||||
| 	tm->tcpm_ts = 0; | 	tm->tcpm_ts = 0; | ||||||
| 	tm->tcpm_ts_stamp = 0; | 	tm->tcpm_ts_stamp = 0; | ||||||
|  | 	tm->tcpm_fastopen.mss = 0; | ||||||
|  | 	tm->tcpm_fastopen.cookie.len = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst, | static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst, | ||||||
|  | @ -633,6 +641,49 @@ bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw) | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static DEFINE_SEQLOCK(fastopen_seqlock); | ||||||
|  | 
 | ||||||
|  | void tcp_fastopen_cache_get(struct sock *sk, u16 *mss, | ||||||
|  | 			    struct tcp_fastopen_cookie *cookie) | ||||||
|  | { | ||||||
|  | 	struct tcp_metrics_block *tm; | ||||||
|  | 
 | ||||||
|  | 	rcu_read_lock(); | ||||||
|  | 	tm = tcp_get_metrics(sk, __sk_dst_get(sk), false); | ||||||
|  | 	if (tm) { | ||||||
|  | 		struct tcp_fastopen_metrics *tfom = &tm->tcpm_fastopen; | ||||||
|  | 		unsigned int seq; | ||||||
|  | 
 | ||||||
|  | 		do { | ||||||
|  | 			seq = read_seqbegin(&fastopen_seqlock); | ||||||
|  | 			if (tfom->mss) | ||||||
|  | 				*mss = tfom->mss; | ||||||
|  | 			*cookie = tfom->cookie; | ||||||
|  | 		} while (read_seqretry(&fastopen_seqlock, seq)); | ||||||
|  | 	} | ||||||
|  | 	rcu_read_unlock(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void tcp_fastopen_cache_set(struct sock *sk, u16 mss, | ||||||
|  | 			    struct tcp_fastopen_cookie *cookie) | ||||||
|  | { | ||||||
|  | 	struct tcp_metrics_block *tm; | ||||||
|  | 
 | ||||||
|  | 	rcu_read_lock(); | ||||||
|  | 	tm = tcp_get_metrics(sk, __sk_dst_get(sk), true); | ||||||
|  | 	if (tm) { | ||||||
|  | 		struct tcp_fastopen_metrics *tfom = &tm->tcpm_fastopen; | ||||||
|  | 
 | ||||||
|  | 		write_seqlock_bh(&fastopen_seqlock); | ||||||
|  | 		tfom->mss = mss; | ||||||
|  | 		if (cookie->len > 0) | ||||||
|  | 			tfom->cookie = *cookie; | ||||||
|  | 		write_sequnlock_bh(&fastopen_seqlock); | ||||||
|  | 	} | ||||||
|  | 	rcu_read_unlock(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static unsigned long tcpmhash_entries; | static unsigned long tcpmhash_entries; | ||||||
| static int __init set_tcpmhash_entries(char *str) | static int __init set_tcpmhash_entries(char *str) | ||||||
| { | { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Yuchung Cheng
				Yuchung Cheng