Page MenuHomeFreeBSD

D28822.id86386.diff
No OneTemporary

D28822.id86386.diff

Index: sys/netinet/tcp_input.c
===================================================================
--- sys/netinet/tcp_input.c
+++ sys/netinet/tcp_input.c
@@ -153,11 +153,6 @@
&VNET_NAME(drop_synfin), 0,
"Drop TCP packets with SYN+FIN set");
-VNET_DEFINE(int, tcp_do_prr_conservative) = 0;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_prr_conservative, CTLFLAG_VNET | CTLFLAG_RW,
- &VNET_NAME(tcp_do_prr_conservative), 0,
- "Do conservative Proportional Rate Reduction");
-
VNET_DEFINE(int, tcp_do_prr) = 1;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_prr, CTLFLAG_VNET | CTLFLAG_RW,
&VNET_NAME(tcp_do_prr), 1,
@@ -2575,7 +2570,11 @@
CC_DUPACK);
if (V_tcp_do_prr &&
IN_FASTRECOVERY(tp->t_flags)) {
- tcp_do_prr_ack(tp, th, &to);
+ /*
+ * While dealing with DupAcks,
+ * always use PRR-CRB
+ */
+ tcp_do_prr_ack(tp, th, &to, 2);
} else if ((tp->t_flags & TF_SACK_PERMIT) &&
(to.to_flags & TOF_SACK) &&
IN_FASTRECOVERY(tp->t_flags)) {
@@ -2783,7 +2782,7 @@
if (V_tcp_do_prr && to.to_flags & TOF_SACK) {
tcp_timer_activate(tp, TT_REXMT, 0);
tp->t_rtttime = 0;
- tcp_do_prr_ack(tp, th, &to);
+ tcp_do_prr_ack(tp, th, &to, sack_changed);
tp->t_flags |= TF_ACKNOW;
(void) tcp_output(tp);
} else
@@ -2797,7 +2796,11 @@
if (V_tcp_do_prr) {
tp->sackhint.delivered_data = BYTES_THIS_ACK(tp, th);
tp->snd_fack = th->th_ack;
- tcp_do_prr_ack(tp, th, &to);
+ /*
+ * During ECN cwnd reduction
+ * always use PRR-SSRB
+ */
+ tcp_do_prr_ack(tp, th, &to, 1);
(void) tcp_output(tp);
}
} else
@@ -3926,7 +3929,7 @@
}
void
-tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to)
+tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to, int sack_changed)
{
int snd_cnt = 0, limit = 0, del_data = 0, pipe = 0;
int maxseg = tcp_maxseg(tp);
@@ -3967,7 +3970,17 @@
tp->snd_ssthresh, tp->sackhint.recover_fs) -
tp->sackhint.prr_out;
} else {
- if (V_tcp_do_prr_conservative || (del_data == 0))
+ /*
+ * PRR 6937bis heuristic:
+ * - A partial ack without SACK block beneath snd_recover
+ * indicates further loss.
+ * - An SACK scoreboard update adding a new hole indicates
+ * further loss, so be conservative and send at most one
+ * segment.
+ * - Prevent ACK splitting attacks, by being conservative
+ * when no new data is acked.
+ */
+ if ((sack_changed == 2) || (del_data == 0))
limit = tp->sackhint.prr_delivered -
tp->sackhint.prr_out;
else
Index: sys/netinet/tcp_sack.c
===================================================================
--- sys/netinet/tcp_sack.c
+++ sys/netinet/tcp_sack.c
@@ -533,7 +533,8 @@
* Process cumulative ACK and the TCP SACK option to update the scoreboard.
* tp->snd_holes is an ordered list of holes (oldest to newest, in terms of
* the sequence space).
- * Returns 1 if incoming ACK has previously unknown SACK information,
+ * Returns 2 if incoming ACK indicates ongoing loss (hole split, new hole),
+ * 1 if incoming ACK has previously unknown SACK information,
* 0 otherwise.
*/
int
@@ -639,7 +640,7 @@
tp->snd_fack = sblkp->end;
/* Go to the previous sack block. */
sblkp--;
- sack_changed = 1;
+ sack_changed = 2;
} else {
/*
* We failed to add a new hole based on the current
@@ -656,7 +657,12 @@
SEQ_LT(tp->snd_fack, sblkp->end)) {
delivered_data += sblkp->end - tp->snd_fack;
tp->snd_fack = sblkp->end;
- sack_changed = 1;
+ /*
+ * While the Scoreboard didn't change in
+ * size, we only ended up here because
+ * some SACK data had to be dismissed.
+ */
+ sack_changed = 2;
}
}
} else if (SEQ_LT(tp->snd_fack, sblkp->end)) {
@@ -725,6 +731,7 @@
*/
temp = tcp_sackhole_insert(tp, sblkp->end,
cur->end, cur);
+ sack_changed = 2;
if (temp != NULL) {
if (SEQ_GT(cur->rxmit, temp->rxmit)) {
temp->rxmit = cur->rxmit;
Index: sys/netinet/tcp_var.h
===================================================================
--- sys/netinet/tcp_var.h
+++ sys/netinet/tcp_var.h
@@ -871,7 +871,6 @@
VNET_DECLARE(struct inpcbinfo, tcbinfo);
#define V_tcp_do_prr VNET(tcp_do_prr)
-#define V_tcp_do_prr_conservative VNET(tcp_do_prr_conservative)
#define V_tcp_do_newcwv VNET(tcp_do_newcwv)
#define V_drop_synfin VNET(drop_synfin)
#define V_path_mtu_discovery VNET(path_mtu_discovery)
@@ -1065,7 +1064,7 @@
void tcp_clean_sackreport(struct tcpcb *tp);
void tcp_sack_adjust(struct tcpcb *tp);
struct sackhole *tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt);
-void tcp_do_prr_ack(struct tcpcb *, struct tcphdr *, struct tcpopt *);
+void tcp_do_prr_ack(struct tcpcb *, struct tcphdr *, struct tcpopt *, int);
void tcp_sack_partialack(struct tcpcb *, struct tcphdr *);
void tcp_free_sackholes(struct tcpcb *tp);
int tcp_newreno(struct tcpcb *, struct tcphdr *);

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 22, 12:05 AM (10 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31940217
Default Alt Text
D28822.id86386.diff (4 KB)

Event Timeline