diff options
Diffstat (limited to 'net/ipv4/tcp_metrics.c')
-rw-r--r-- | net/ipv4/tcp_metrics.c | 147 |
1 files changed, 4 insertions, 143 deletions
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 0f46e5fe31ad..9d0d4f39e42b 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c | |||
@@ -45,8 +45,6 @@ struct tcp_metrics_block { | |||
45 | struct inetpeer_addr tcpm_saddr; | 45 | struct inetpeer_addr tcpm_saddr; |
46 | struct inetpeer_addr tcpm_daddr; | 46 | struct inetpeer_addr tcpm_daddr; |
47 | unsigned long tcpm_stamp; | 47 | unsigned long tcpm_stamp; |
48 | u32 tcpm_ts; | ||
49 | u32 tcpm_ts_stamp; | ||
50 | u32 tcpm_lock; | 48 | u32 tcpm_lock; |
51 | u32 tcpm_vals[TCP_METRIC_MAX_KERNEL + 1]; | 49 | u32 tcpm_vals[TCP_METRIC_MAX_KERNEL + 1]; |
52 | struct tcp_fastopen_metrics tcpm_fastopen; | 50 | struct tcp_fastopen_metrics tcpm_fastopen; |
@@ -123,8 +121,6 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm, | |||
123 | tm->tcpm_vals[TCP_METRIC_SSTHRESH] = dst_metric_raw(dst, RTAX_SSTHRESH); | 121 | tm->tcpm_vals[TCP_METRIC_SSTHRESH] = dst_metric_raw(dst, RTAX_SSTHRESH); |
124 | tm->tcpm_vals[TCP_METRIC_CWND] = dst_metric_raw(dst, RTAX_CWND); | 122 | tm->tcpm_vals[TCP_METRIC_CWND] = dst_metric_raw(dst, RTAX_CWND); |
125 | tm->tcpm_vals[TCP_METRIC_REORDERING] = dst_metric_raw(dst, RTAX_REORDERING); | 123 | tm->tcpm_vals[TCP_METRIC_REORDERING] = dst_metric_raw(dst, RTAX_REORDERING); |
126 | tm->tcpm_ts = 0; | ||
127 | tm->tcpm_ts_stamp = 0; | ||
128 | if (fastopen_clear) { | 124 | if (fastopen_clear) { |
129 | tm->tcpm_fastopen.mss = 0; | 125 | tm->tcpm_fastopen.mss = 0; |
130 | tm->tcpm_fastopen.syn_loss = 0; | 126 | tm->tcpm_fastopen.syn_loss = 0; |
@@ -273,48 +269,6 @@ static struct tcp_metrics_block *__tcp_get_metrics_req(struct request_sock *req, | |||
273 | return tm; | 269 | return tm; |
274 | } | 270 | } |
275 | 271 | ||
276 | static struct tcp_metrics_block *__tcp_get_metrics_tw(struct inet_timewait_sock *tw) | ||
277 | { | ||
278 | struct tcp_metrics_block *tm; | ||
279 | struct inetpeer_addr saddr, daddr; | ||
280 | unsigned int hash; | ||
281 | struct net *net; | ||
282 | |||
283 | if (tw->tw_family == AF_INET) { | ||
284 | inetpeer_set_addr_v4(&saddr, tw->tw_rcv_saddr); | ||
285 | inetpeer_set_addr_v4(&daddr, tw->tw_daddr); | ||
286 | hash = ipv4_addr_hash(tw->tw_daddr); | ||
287 | } | ||
288 | #if IS_ENABLED(CONFIG_IPV6) | ||
289 | else if (tw->tw_family == AF_INET6) { | ||
290 | if (ipv6_addr_v4mapped(&tw->tw_v6_daddr)) { | ||
291 | inetpeer_set_addr_v4(&saddr, tw->tw_rcv_saddr); | ||
292 | inetpeer_set_addr_v4(&daddr, tw->tw_daddr); | ||
293 | hash = ipv4_addr_hash(tw->tw_daddr); | ||
294 | } else { | ||
295 | inetpeer_set_addr_v6(&saddr, &tw->tw_v6_rcv_saddr); | ||
296 | inetpeer_set_addr_v6(&daddr, &tw->tw_v6_daddr); | ||
297 | hash = ipv6_addr_hash(&tw->tw_v6_daddr); | ||
298 | } | ||
299 | } | ||
300 | #endif | ||
301 | else | ||
302 | return NULL; | ||
303 | |||
304 | net = twsk_net(tw); | ||
305 | hash ^= net_hash_mix(net); | ||
306 | hash = hash_32(hash, tcp_metrics_hash_log); | ||
307 | |||
308 | for (tm = rcu_dereference(tcp_metrics_hash[hash].chain); tm; | ||
309 | tm = rcu_dereference(tm->tcpm_next)) { | ||
310 | if (addr_same(&tm->tcpm_saddr, &saddr) && | ||
311 | addr_same(&tm->tcpm_daddr, &daddr) && | ||
312 | net_eq(tm_net(tm), net)) | ||
313 | break; | ||
314 | } | ||
315 | return tm; | ||
316 | } | ||
317 | |||
318 | static struct tcp_metrics_block *tcp_get_metrics(struct sock *sk, | 272 | static struct tcp_metrics_block *tcp_get_metrics(struct sock *sk, |
319 | struct dst_entry *dst, | 273 | struct dst_entry *dst, |
320 | bool create) | 274 | bool create) |
@@ -573,8 +527,7 @@ reset: | |||
573 | tp->snd_cwnd_stamp = tcp_time_stamp; | 527 | tp->snd_cwnd_stamp = tcp_time_stamp; |
574 | } | 528 | } |
575 | 529 | ||
576 | bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst, | 530 | bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst) |
577 | bool paws_check, bool timestamps) | ||
578 | { | 531 | { |
579 | struct tcp_metrics_block *tm; | 532 | struct tcp_metrics_block *tm; |
580 | bool ret; | 533 | bool ret; |
@@ -584,94 +537,10 @@ bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst, | |||
584 | 537 | ||
585 | rcu_read_lock(); | 538 | rcu_read_lock(); |
586 | tm = __tcp_get_metrics_req(req, dst); | 539 | tm = __tcp_get_metrics_req(req, dst); |
587 | if (paws_check) { | 540 | if (tm && tcp_metric_get(tm, TCP_METRIC_RTT)) |
588 | if (tm && | ||
589 | (u32)get_seconds() - tm->tcpm_ts_stamp < TCP_PAWS_MSL && | ||
590 | ((s32)(tm->tcpm_ts - req->ts_recent) > TCP_PAWS_WINDOW || | ||
591 | !timestamps)) | ||
592 | ret = false; | ||
593 | else | ||
594 | ret = true; | ||
595 | } else { | ||
596 | if (tm && tcp_metric_get(tm, TCP_METRIC_RTT) && tm->tcpm_ts_stamp) | ||
597 | ret = true; | ||
598 | else | ||
599 | ret = false; | ||
600 | } | ||
601 | rcu_read_unlock(); | ||
602 | |||
603 | return ret; | ||
604 | } | ||
605 | |||
606 | void tcp_fetch_timewait_stamp(struct sock *sk, struct dst_entry *dst) | ||
607 | { | ||
608 | struct tcp_metrics_block *tm; | ||
609 | |||
610 | rcu_read_lock(); | ||
611 | tm = tcp_get_metrics(sk, dst, true); | ||
612 | if (tm) { | ||
613 | struct tcp_sock *tp = tcp_sk(sk); | ||
614 | |||
615 | if ((u32)get_seconds() - tm->tcpm_ts_stamp <= TCP_PAWS_MSL) { | ||
616 | tp->rx_opt.ts_recent_stamp = tm->tcpm_ts_stamp; | ||
617 | tp->rx_opt.ts_recent = tm->tcpm_ts; | ||
618 | } | ||
619 | } | ||
620 | rcu_read_unlock(); | ||
621 | } | ||
622 | EXPORT_SYMBOL_GPL(tcp_fetch_timewait_stamp); | ||
623 | |||
624 | /* VJ's idea. Save last timestamp seen from this destination and hold | ||
625 | * it at least for normal timewait interval to use for duplicate | ||
626 | * segment detection in subsequent connections, before they enter | ||
627 | * synchronized state. | ||
628 | */ | ||
629 | bool tcp_remember_stamp(struct sock *sk) | ||
630 | { | ||
631 | struct dst_entry *dst = __sk_dst_get(sk); | ||
632 | bool ret = false; | ||
633 | |||
634 | if (dst) { | ||
635 | struct tcp_metrics_block *tm; | ||
636 | |||
637 | rcu_read_lock(); | ||
638 | tm = tcp_get_metrics(sk, dst, true); | ||
639 | if (tm) { | ||
640 | struct tcp_sock *tp = tcp_sk(sk); | ||
641 | |||
642 | if ((s32)(tm->tcpm_ts - tp->rx_opt.ts_recent) <= 0 || | ||
643 | ((u32)get_seconds() - tm->tcpm_ts_stamp > TCP_PAWS_MSL && | ||
644 | tm->tcpm_ts_stamp <= (u32)tp->rx_opt.ts_recent_stamp)) { | ||
645 | tm->tcpm_ts_stamp = (u32)tp->rx_opt.ts_recent_stamp; | ||
646 | tm->tcpm_ts = tp->rx_opt.ts_recent; | ||
647 | } | ||
648 | ret = true; | ||
649 | } | ||
650 | rcu_read_unlock(); | ||
651 | } | ||
652 | return ret; | ||
653 | } | ||
654 | |||
655 | bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw) | ||
656 | { | ||
657 | struct tcp_metrics_block *tm; | ||
658 | bool ret = false; | ||
659 | |||
660 | rcu_read_lock(); | ||
661 | tm = __tcp_get_metrics_tw(tw); | ||
662 | if (tm) { | ||
663 | const struct tcp_timewait_sock *tcptw; | ||
664 | struct sock *sk = (struct sock *) tw; | ||
665 | |||
666 | tcptw = tcp_twsk(sk); | ||
667 | if ((s32)(tm->tcpm_ts - tcptw->tw_ts_recent) <= 0 || | ||
668 | ((u32)get_seconds() - tm->tcpm_ts_stamp > TCP_PAWS_MSL && | ||
669 | tm->tcpm_ts_stamp <= (u32)tcptw->tw_ts_recent_stamp)) { | ||
670 | tm->tcpm_ts_stamp = (u32)tcptw->tw_ts_recent_stamp; | ||
671 | tm->tcpm_ts = tcptw->tw_ts_recent; | ||
672 | } | ||
673 | ret = true; | 541 | ret = true; |
674 | } | 542 | else |
543 | ret = false; | ||
675 | rcu_read_unlock(); | 544 | rcu_read_unlock(); |
676 | 545 | ||
677 | return ret; | 546 | return ret; |
@@ -791,14 +660,6 @@ static int tcp_metrics_fill_info(struct sk_buff *msg, | |||
791 | jiffies - tm->tcpm_stamp, | 660 | jiffies - tm->tcpm_stamp, |
792 | TCP_METRICS_ATTR_PAD) < 0) | 661 | TCP_METRICS_ATTR_PAD) < 0) |
793 | goto nla_put_failure; | 662 | goto nla_put_failure; |
794 | if (tm->tcpm_ts_stamp) { | ||
795 | if (nla_put_s32(msg, TCP_METRICS_ATTR_TW_TS_STAMP, | ||
796 | (s32) (get_seconds() - tm->tcpm_ts_stamp)) < 0) | ||
797 | goto nla_put_failure; | ||
798 | if (nla_put_u32(msg, TCP_METRICS_ATTR_TW_TSVAL, | ||
799 | tm->tcpm_ts) < 0) | ||
800 | goto nla_put_failure; | ||
801 | } | ||
802 | 663 | ||
803 | { | 664 | { |
804 | int n = 0; | 665 | int n = 0; |