@@ -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
@@ -419,27 +458,23 @@ EXPORT_SYMBOL(tcp_req_err);
419
458
*
420
459
*/
421
460
422
- int tcp_v4_err (struct sk_buff * icmp_skb , u32 info )
461
+ int tcp_v4_err (struct sk_buff * skb , u32 info )
423
462
{
424
- const struct iphdr * iph = (const struct iphdr * )icmp_skb -> data ;
425
- struct tcphdr * th = (struct tcphdr * )(icmp_skb -> data + (iph -> ihl << 2 ));
426
- struct inet_connection_sock * icsk ;
463
+ const struct iphdr * iph = (const struct iphdr * )skb -> data ;
464
+ struct tcphdr * th = (struct tcphdr * )(skb -> data + (iph -> ihl << 2 ));
427
465
struct tcp_sock * tp ;
428
466
struct inet_sock * inet ;
429
- const int type = icmp_hdr (icmp_skb )-> type ;
430
- const int code = icmp_hdr (icmp_skb )-> code ;
467
+ const int type = icmp_hdr (skb )-> type ;
468
+ const int code = icmp_hdr (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
- struct net * net = dev_net (icmp_skb -> dev );
473
+ struct net * net = dev_net (skb -> dev );
439
474
440
475
sk = __inet_lookup_established (net , & tcp_hashinfo , iph -> daddr ,
441
476
th -> dest , iph -> saddr , ntohs (th -> source ),
442
- inet_iif (icmp_skb ), 0 );
477
+ inet_iif (skb ), 0 );
443
478
if (!sk ) {
444
479
__ICMP_INC_STATS (net , ICMP_MIB_INERRORS );
445
480
return - ENOENT ;
@@ -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 );
@@ -490,7 +524,7 @@ int tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
490
524
switch (type ) {
491
525
case ICMP_REDIRECT :
492
526
if (!sock_owned_by_user (sk ))
493
- do_redirect (icmp_skb , sk );
527
+ do_redirect (skb , sk );
494
528
goto out ;
495
529
case ICMP_SOURCE_QUENCH :
496
530
/* Just silently ignore these. */
@@ -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 ;
@@ -573,7 +578,7 @@ int tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
573
578
if (fastopen && !fastopen -> sk )
574
579
break ;
575
580
576
- ip_icmp_error (sk , icmp_skb , err , th -> dest , info , (u8 * )th );
581
+ ip_icmp_error (sk , skb , err , th -> dest , info , (u8 * )th );
577
582
578
583
if (!sock_owned_by_user (sk )) {
579
584
sk -> sk_err = err ;
0 commit comments