Author: hiren
Date: Mon Jan 11 23:31:13 2016
New Revision: 293709
URL: https://svnweb.freebsd.org/changeset/base/293709

Log:
  MFC: r290122
  Calculate the correct amount of bytes that are in-flight for a connection as
  suggested by RFC 6675.
  
  MFC: r292046
  r290122 added 4 bytes and removed 8 in struct sackhint. Add a pad entry of 4
  bytes to restore the size.

Modified:
  stable/10/sys/netinet/tcp_input.c
  stable/10/sys/netinet/tcp_sack.c
  stable/10/sys/netinet/tcp_var.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/netinet/tcp_input.c
==============================================================================
--- stable/10/sys/netinet/tcp_input.c   Mon Jan 11 22:15:46 2016        
(r293708)
+++ stable/10/sys/netinet/tcp_input.c   Mon Jan 11 23:31:13 2016        
(r293709)
@@ -148,6 +148,11 @@ SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO,
     &VNET_NAME(drop_synfin), 0,
     "Drop TCP packets with SYN+FIN set");
 
+VNET_DEFINE(int, tcp_do_rfc6675_pipe) = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_pipe, CTLFLAG_VNET | CTLFLAG_RW,
+    &VNET_NAME(tcp_do_rfc6675_pipe), 0,
+    "Use calculated pipe/in-flight bytes per RFC 6675");
+
 VNET_DEFINE(int, tcp_do_rfc3042) = 1;
 #define        V_tcp_do_rfc3042        VNET(tcp_do_rfc3042)
 SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, rfc3042, CTLFLAG_RW,
@@ -2455,6 +2460,12 @@ tcp_do_segment(struct mbuf *m, struct tc
                    ((to.to_flags & TOF_SACK) ||
                     !TAILQ_EMPTY(&tp->snd_holes)))
                        tcp_sack_doack(tp, &to, th->th_ack);
+               else
+                       /*
+                        * Reset the value so that previous (valid) value
+                        * from the last ack with SACK doesn't get used.
+                        */
+                       tp->sackhint.sacked_bytes = 0;
 
                /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */
                hhook_run_tcp_est_in(tp, th, &to);
@@ -2505,8 +2516,12 @@ tcp_do_segment(struct mbuf *m, struct tc
                                                 * we have less than 1/2 the 
original window's
                                                 * worth of data in flight.
                                                 */
-                                               awnd = (tp->snd_nxt - 
tp->snd_fack) +
-                                                       
tp->sackhint.sack_bytes_rexmit;
+                                               if (V_tcp_do_rfc6675_pipe)
+                                                       awnd = 
tcp_compute_pipe(tp);
+                                               else
+                                                       awnd = (tp->snd_nxt - 
tp->snd_fack) +
+                                                               
tp->sackhint.sack_bytes_rexmit;
+
                                                if (awnd < tp->snd_ssthresh) {
                                                        tp->snd_cwnd += 
tp->t_maxseg;
                                                        if (tp->snd_cwnd > 
tp->snd_ssthresh)
@@ -3798,3 +3813,11 @@ tcp_newreno_partial_ack(struct tcpcb *tp
                tp->snd_cwnd = 0;
        tp->snd_cwnd += tp->t_maxseg;
 }
+
+int
+tcp_compute_pipe(struct tcpcb *tp)
+{
+       return (tp->snd_max - tp->snd_una +
+               tp->sackhint.sack_bytes_rexmit -
+               tp->sackhint.sacked_bytes);
+}

Modified: stable/10/sys/netinet/tcp_sack.c
==============================================================================
--- stable/10/sys/netinet/tcp_sack.c    Mon Jan 11 22:15:46 2016        
(r293708)
+++ stable/10/sys/netinet/tcp_sack.c    Mon Jan 11 23:31:13 2016        
(r293709)
@@ -368,6 +368,7 @@ tcp_sack_doack(struct tcpcb *tp, struct 
         * received new blocks from the other side.
         */
        if (to->to_flags & TOF_SACK) {
+               tp->sackhint.sacked_bytes = 0;  /* reset */
                for (i = 0; i < to->to_nsacks; i++) {
                        bcopy((to->to_sacks + i * TCPOLEN_SACK),
                            &sack, sizeof(sack));
@@ -378,8 +379,11 @@ tcp_sack_doack(struct tcpcb *tp, struct 
                            SEQ_GT(sack.start, th_ack) &&
                            SEQ_LT(sack.start, tp->snd_max) &&
                            SEQ_GT(sack.end, tp->snd_una) &&
-                           SEQ_LEQ(sack.end, tp->snd_max))
+                           SEQ_LEQ(sack.end, tp->snd_max)) {
                                sack_blocks[num_sack_blks++] = sack;
+                               tp->sackhint.sacked_bytes +=
+                                   (sack.end-sack.start);
+                       }
                }
        }
        /*

Modified: stable/10/sys/netinet/tcp_var.h
==============================================================================
--- stable/10/sys/netinet/tcp_var.h     Mon Jan 11 22:15:46 2016        
(r293708)
+++ stable/10/sys/netinet/tcp_var.h     Mon Jan 11 23:31:13 2016        
(r293709)
@@ -73,7 +73,12 @@ struct sackhint {
        tcp_seq         last_sack_ack;  /* Most recent/largest sacked ack */
 
        int             ispare;         /* explicit pad for 64bit alignment */
-       uint64_t        _pad[2];        /* 1 sacked_bytes, 1 TBD */
+       int             sacked_bytes;   /*
+                                        * Total sacked bytes reported by the
+                                        * receiver via sack option
+                                        */
+       uint32_t        _pad1[1];       /* TBD */
+       uint64_t        _pad[1];        /* TBD */
 };
 
 struct tcptemp {
@@ -668,6 +673,9 @@ VNET_DECLARE(int, tcp_ecn_maxretries);
 VNET_DECLARE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST + 1]);
 #define        V_tcp_hhh               VNET(tcp_hhh)
 
+VNET_DECLARE(int, tcp_do_rfc6675_pipe);
+#define V_tcp_do_rfc6675_pipe  VNET(tcp_do_rfc6675_pipe)
+
 int     tcp_addoptions(struct tcpopt *, u_char *);
 int     tcp_ccalgounload(struct cc_algo *unload_algo);
 struct tcpcb *
@@ -757,6 +765,7 @@ void         tcp_sack_partialack(struct tcpcb *
 void    tcp_free_sackholes(struct tcpcb *tp);
 int     tcp_newreno(struct tcpcb *, struct tcphdr *);
 u_long  tcp_seq_subtract(u_long, u_long );
+int     tcp_compute_pipe(struct tcpcb *);
 
 void   cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type);
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to