@@ -403,6 +403,45 @@ void tcp_req_err(struct sock *sk, u32 seq, bool abort)
403
403
}
404
404
EXPORT_SYMBOL (tcp_req_err );
405
405
406
+ /* TCP-LD (RFC 6069) logic */
407
+ static void tcp_ld_RTO_revert (struct sock * sk , u32 seq )
408
+ {
409
+ struct inet_connection_sock * icsk = inet_csk (sk );
410
+ struct tcp_sock * tp = tcp_sk (sk );
411
+ struct sk_buff * skb ;
412
+ s32 remaining ;
413
+ u32 delta_us ;
414
+
415
+ if (sock_owned_by_user (sk ))
416
+ return ;
417
+
418
+ if (seq != tp -> snd_una || !icsk -> icsk_retransmits ||
419
+ !icsk -> icsk_backoff )
420
+ return ;
421
+
422
+ skb = tcp_rtx_queue_head (sk );
423
+ if (WARN_ON_ONCE (!skb ))
424
+ return ;
425
+
426
+ icsk -> icsk_backoff -- ;
427
+ icsk -> icsk_rto = tp -> srtt_us ? __tcp_set_rto (tp ) : TCP_TIMEOUT_INIT ;
428
+ icsk -> icsk_rto = inet_csk_rto_backoff (icsk , TCP_RTO_MAX );
429
+
430
+ tcp_mstamp_refresh (tp );
431
+ delta_us = (u32 )(tp -> tcp_mstamp - tcp_skb_timestamp_us (skb ));
432
+ remaining = icsk -> icsk_rto - usecs_to_jiffies (delta_us );
433
+
434
+ if (remaining > 0 ) {
435
+ inet_csk_reset_xmit_timer (sk , ICSK_TIME_RETRANS ,
436
+ remaining , TCP_RTO_MAX );
437
+ } else {
438
+ /* RTO revert clocked out retransmission.
439
+ * Will retransmit now.
440
+ */
441
+ tcp_retransmit_timer (sk );
442
+ }
443
+ }
444
+
406
445
/*
407
446
* This routine is called by the ICMP module when it gets some
408
447
* sort of error condition. If err < 0 then the socket should
@@ -423,17 +462,13 @@ int tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
423
462
{
424
463
const struct iphdr * iph = (const struct iphdr * )icmp_skb -> data ;
425
464
struct tcphdr * th = (struct tcphdr * )(icmp_skb -> data + (iph -> ihl << 2 ));
426
- struct inet_connection_sock * icsk ;
427
465
struct tcp_sock * tp ;
428
466
struct inet_sock * inet ;
429
467
const int type = icmp_hdr (icmp_skb )-> type ;
430
468
const int code = icmp_hdr (icmp_skb )-> code ;
431
469
struct sock * sk ;
432
- struct sk_buff * skb ;
433
470
struct request_sock * fastopen ;
434
471
u32 seq , snd_una ;
435
- s32 remaining ;
436
- u32 delta_us ;
437
472
int err ;
438
473
struct net * net = dev_net (icmp_skb -> dev );
439
474
@@ -476,7 +511,6 @@ int tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
476
511
goto out ;
477
512
}
478
513
479
- icsk = inet_csk (sk );
480
514
tp = tcp_sk (sk );
481
515
/* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */
482
516
fastopen = rcu_dereference (tp -> fastopen_rsk );
@@ -521,41 +555,12 @@ int tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
521
555
}
522
556
523
557
err = icmp_err_convert [code ].errno ;
524
- /* check if icmp_skb allows revert of backoff
525
- * (see draft-zimmermann-tcp-lcd) */
526
- if (code != ICMP_NET_UNREACH && code != ICMP_HOST_UNREACH )
527
- break ;
528
- if (seq != tp -> snd_una || !icsk -> icsk_retransmits ||
529
- !icsk -> icsk_backoff || fastopen )
530
- break ;
531
-
532
- if (sock_owned_by_user (sk ))
533
- break ;
534
-
535
- skb = tcp_rtx_queue_head (sk );
536
- if (WARN_ON_ONCE (!skb ))
537
- break ;
538
-
539
- icsk -> icsk_backoff -- ;
540
- icsk -> icsk_rto = tp -> srtt_us ? __tcp_set_rto (tp ) :
541
- TCP_TIMEOUT_INIT ;
542
- icsk -> icsk_rto = inet_csk_rto_backoff (icsk , TCP_RTO_MAX );
543
-
544
-
545
- tcp_mstamp_refresh (tp );
546
- delta_us = (u32 )(tp -> tcp_mstamp - tcp_skb_timestamp_us (skb ));
547
- remaining = icsk -> icsk_rto -
548
- usecs_to_jiffies (delta_us );
549
-
550
- if (remaining > 0 ) {
551
- inet_csk_reset_xmit_timer (sk , ICSK_TIME_RETRANS ,
552
- remaining , TCP_RTO_MAX );
553
- } else {
554
- /* RTO revert clocked out retransmission.
555
- * Will retransmit now */
556
- tcp_retransmit_timer (sk );
557
- }
558
-
558
+ /* check if this ICMP message allows revert of backoff.
559
+ * (see RFC 6069)
560
+ */
561
+ if (!fastopen &&
562
+ (code == ICMP_NET_UNREACH || code == ICMP_HOST_UNREACH ))
563
+ tcp_ld_RTO_revert (sk , seq );
559
564
break ;
560
565
case ICMP_TIME_EXCEEDED :
561
566
err = EHOSTUNREACH ;
0 commit comments