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:
parent
4df50368d1
commit
81463c93c7
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue