implement RFC3465 appropriate byte counting.

from Kentaro A. Kurahone, with minor adjustments by me.
the ack prediction part of the original patch was omitted because
it's a separate change.  reviewed by Rui Paulo.
This commit is contained in:
yamt 2006-10-19 11:40:51 +00:00
parent 4df50368d1
commit 81463c93c7
4 changed files with 84 additions and 15 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_congctl.c,v 1.7 2006/10/15 17:53:30 rpaulo Exp $ */
/* $NetBSD: tcp_congctl.c,v 1.8 2006/10/19 11:40:51 yamt Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999, 2001, 2005, 2006 The NetBSD Foundation, Inc.
@ -142,7 +142,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcp_congctl.c,v 1.7 2006/10/15 17:53:30 rpaulo Exp $");
__KERNEL_RCSID(0, "$NetBSD: tcp_congctl.c,v 1.8 2006/10/19 11:40:51 yamt Exp $");
#include "opt_inet.h"
#include "opt_tcp_debug.h"
@ -491,6 +491,7 @@ tcp_reno_slow_retransmit(struct tcpcb *tp)
tp->snd_ssthresh = win * tp->t_segsz;
tp->t_partialacks = -1;
tp->t_dupacks = 0;
tp->t_bytes_acked = 0;
}
static void
@ -511,6 +512,7 @@ tcp_reno_fast_retransmit_newack(struct tcpcb *tp, struct tcphdr *th __unused)
tp->snd_cwnd = tp->snd_ssthresh;
tp->t_partialacks = -1;
tp->t_dupacks = 0;
tp->t_bytes_acked = 0;
}
}
@ -519,17 +521,53 @@ tcp_reno_newack(struct tcpcb *tp, struct tcphdr *th __unused)
{
/*
* When new data is acked, open the congestion window.
* If the window gives us less than ssthresh packets
* in flight, open exponentially (segsz per packet).
* Otherwise open linearly: segsz per window
* (segsz^2 / cwnd per packet).
*/
u_int cw = tp->snd_cwnd;
u_int incr = tp->t_segsz;
if (cw >= tp->snd_ssthresh)
incr = incr * incr / cw;
if (tcp_do_abc) {
/*
* RFC 3465 Appropriate Byte Counting (ABC)
*/
int acked = th->th_ack - tp->snd_una;
if (cw >= tp->snd_ssthresh) {
tp->t_bytes_acked += acked;
if (tp->t_bytes_acked >= cw) {
/* Time to increase the window. */
tp->t_bytes_acked -= cw;
} else {
/* No need to increase yet. */
incr = 0;
}
} else {
/*
* use 2*SMSS or 1*SMSS for the "L" param,
* depending on sysctl setting.
*
* (See RFC 3465 2.3 Choosing the Limit)
*/
u_int abc_lim;
abc_lim = (tcp_abc_aggressive == 0) ? incr : incr * 2;
incr = min(acked, abc_lim);
}
} else {
/*
* If the window gives us less than ssthresh packets
* in flight, open exponentially (segsz per packet).
* Otherwise open linearly: segsz per window
* (segsz^2 / cwnd per packet).
*/
if (cw >= tp->snd_ssthresh) {
incr = incr * incr / cw;
}
}
tp->snd_cwnd = min(cw + incr, TCP_MAXWIN << tp->snd_scale);
}
@ -628,6 +666,7 @@ tcp_newreno_fast_retransmit_newack(struct tcpcb *tp, struct tcphdr *th)
tp->snd_cwnd = tp->snd_ssthresh;
tp->t_partialacks = -1;
tp->t_dupacks = 0;
tp->t_bytes_acked = 0;
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_subr.c,v 1.206 2006/10/17 18:21:29 dogcow Exp $ */
/* $NetBSD: tcp_subr.c,v 1.207 2006/10/19 11:40:51 yamt Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -98,7 +98,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.206 2006/10/17 18:21:29 dogcow Exp $");
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.207 2006/10/19 11:40:51 yamt Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -202,6 +202,8 @@ int tcp_compat_42 = 0;
int tcp_rst_ppslim = 100; /* 100pps */
int tcp_ackdrop_ppslim = 100; /* 100pps */
int tcp_do_loopback_cksum = 0;
int tcp_do_abc = 1; /* RFC3465 Appropriate byte counting. */
int tcp_abc_aggressive = 1; /* 1: L=2*SMSS 0: L=1*SMSS */
int tcp_sack_tp_maxholes = 32;
int tcp_sack_globalmaxholes = 1024;
int tcp_sack_globalholes = 0;
@ -935,6 +937,7 @@ static struct tcpcb tcpcb_template = {
.snd_numholes = 0,
.t_partialacks = -1,
.t_bytes_acked = 0,
};
/*
@ -1647,8 +1650,10 @@ tcp_quench(struct inpcb *inp, int errno __unused)
{
struct tcpcb *tp = intotcpcb(inp);
if (tp)
if (tp) {
tp->snd_cwnd = tp->t_segsz;
tp->t_bytes_acked = 0;
}
}
#endif
@ -1658,8 +1663,10 @@ tcp6_quench(struct in6pcb *in6p, int errno __unused)
{
struct tcpcb *tp = in6totcpcb(in6p);
if (tp)
if (tp) {
tp->snd_cwnd = tp->t_segsz;
tp->t_bytes_acked = 0;
}
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_usrreq.c,v 1.126 2006/10/16 18:13:56 rpaulo Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.127 2006/10/19 11:40:51 yamt Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -102,7 +102,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.126 2006/10/16 18:13:56 rpaulo Exp $");
__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.127 2006/10/19 11:40:51 yamt Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -1428,6 +1428,7 @@ sysctl_net_inet_tcp_setup2(struct sysctllog **clog, int pf, const char *pfname,
{
int ecn_node, congctl_node;
const struct sysctlnode *sack_node, *node;
const struct sysctlnode *abc_node;
#ifdef TCP_DEBUG
extern struct tcp_debug tcp_debug[TCP_NDEBUG];
extern int tcp_debx;
@ -1743,6 +1744,23 @@ sysctl_net_inet_tcp_setup2(struct sysctllog **clog, int pf, const char *pfname,
CTL_EOL);
#endif
/* ABC subtree */
sysctl_createv(clog, 0, NULL, &abc_node,
CTLFLAG_PERMANENT, CTLTYPE_NODE, "abc",
SYSCTL_DESCR("RFC3465 Appropriate Byte Counting (ABC)"),
NULL, 0, NULL, 0,
CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, &abc_node, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "enable",
SYSCTL_DESCR("Enable RFC3465 Appropriate Byte Counting"),
NULL, 0, &tcp_do_abc, 0, CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, &abc_node, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "aggressive",
SYSCTL_DESCR("1: L=2*SMSS 0: L=1*SMSS"),
NULL, 0, &tcp_abc_aggressive, 0, CTL_CREATE, CTL_EOL);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_var.h,v 1.139 2006/10/16 18:13:56 rpaulo Exp $ */
/* $NetBSD: tcp_var.h,v 1.140 2006/10/19 11:40:51 yamt Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -291,6 +291,9 @@ struct tcpcb {
u_int32_t ts_timebase; /* our timebase */
tcp_seq last_ack_sent;
/* RFC 3465 variables */
u_long t_bytes_acked; /* ABC "bytes_acked" parameter */
/* SACK stuff */
#define TCP_SACK_MAX 3
#define TCPSACK_NONE 0
@ -758,6 +761,8 @@ extern int tcp_do_rfc1948; /* ISS by cryptographic hash */
extern int tcp_sack_tp_maxholes; /* Max holes per connection. */
extern int tcp_sack_globalmaxholes; /* Max holes per system. */
extern int tcp_sack_globalholes; /* Number of holes present. */
extern int tcp_do_abc; /* RFC3465 ABC enabled/disabled? */
extern int tcp_abc_aggressive; /* 1: L=2*SMSS 0: L=1*SMSS */
extern int tcp_rst_ppslim;
extern int tcp_ackdrop_ppslim;