Page MenuHomeFreeBSD

D46140.id.diff
No OneTemporary

D46140.id.diff

diff --git a/share/man/man4/tcp.4 b/share/man/man4/tcp.4
--- a/share/man/man4/tcp.4
+++ b/share/man/man4/tcp.4
@@ -31,7 +31,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 21, 2024
+.Dd July 26, 2024
.Dt TCP 4
.Os
.Sh NAME
@@ -432,6 +432,17 @@
MIB, which can also be read or modified with
.Xr sysctl 8 .
.Bl -tag -width ".Va v6pmtud_blackhole_mss"
+.It Va ack_war_timewindow , ack_war_cnt
+The challenge ACK throttling algorithm defined in RFC 5961 limits
+the number of challenge ACKs sent per TCP connection to
+.Va ack_war_cnt
+during the time interval specified in milliseconds by
+.Va ack_war_timewindow .
+Setting
+.Va ack_war_timewindow
+or
+.Va ack_war_cnt
+to zero disables challenge ACK throttling.
.It Va always_keepalive
Assume that
.Dv SO_KEEPALIVE
@@ -1078,6 +1089,13 @@
.%T "The Addition of Explicit Congestion Notification (ECN) to IP"
.%O "RFC 3168"
.Re
+.Rs
+.%A "A. Ramaiah"
+.%A "R. Stewart"
+.%A "M. Dalal"
+.%T "Improving TCP's Robustness to Blind In-Window Attacks"
+.%O "RFC 5961"
+.Re
.Sh HISTORY
The
.Tn TCP
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -15547,7 +15547,7 @@
rack->r_ctl.rc_lower_rtt_us_cts = us_cts;
rack->r_ctl.rc_time_of_last_probertt = us_cts;
rack->r_ctl.rc_went_idle_time = us_cts;
- rack->r_ctl.challenge_ack_ts = tcp_ts_getticks() - (tcp_ack_war_time_window + 1);
+ rack->r_ctl.challenge_ack_ts = tcp_ts_getticks() - (V_tcp_ack_war_time_window + 1);
rack->r_ctl.rc_time_probertt_starts = 0;
rack->r_ctl.gp_rnd_thresh = rack_rnd_cnt_req & 0xff;
diff --git a/sys/netinet/tcp_stacks/rack_bbr_common.c b/sys/netinet/tcp_stacks/rack_bbr_common.c
--- a/sys/netinet/tcp_stacks/rack_bbr_common.c
+++ b/sys/netinet/tcp_stacks/rack_bbr_common.c
@@ -535,8 +535,8 @@
ctf_ack_war_checks(struct tcpcb *tp, uint32_t *ts, uint32_t *cnt)
{
if ((ts != NULL) && (cnt != NULL) &&
- (tcp_ack_war_time_window > 0) &&
- (tcp_ack_war_cnt > 0)) {
+ (V_tcp_ack_war_time_window > 0) &&
+ (V_tcp_ack_war_cnt > 0)) {
/* We are possibly doing ack war prevention */
uint32_t cts;
@@ -550,9 +550,9 @@
if (TSTMP_LT((*ts), cts)) {
/* Timestamp is in the past */
*cnt = 0;
- *ts = (cts + tcp_ack_war_time_window);
+ *ts = (cts + V_tcp_ack_war_time_window);
}
- if (*cnt < tcp_ack_war_cnt) {
+ if (*cnt < V_tcp_ack_war_cnt) {
*cnt = (*cnt + 1);
tp->t_flags |= TF_ACKNOW;
} else
@@ -772,8 +772,8 @@
KMOD_TCPSTAT_INC(tcps_badrst);
if ((ts != NULL) && (cnt != NULL) &&
- (tcp_ack_war_time_window > 0) &&
- (tcp_ack_war_cnt > 0)) {
+ (V_tcp_ack_war_time_window > 0) &&
+ (V_tcp_ack_war_cnt > 0)) {
/* We are possibly preventing an ack-rst war prevention */
uint32_t cts;
@@ -787,9 +787,9 @@
if (TSTMP_LT((*ts), cts)) {
/* Timestamp is in the past */
*cnt = 0;
- *ts = (cts + tcp_ack_war_time_window);
+ *ts = (cts + V_tcp_ack_war_time_window);
}
- if (*cnt < tcp_ack_war_cnt) {
+ if (*cnt < V_tcp_ack_war_cnt) {
*cnt = (*cnt + 1);
send_challenge = 1;
} else
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -139,16 +139,14 @@
VNET_DEFINE(int, tcp_v6mssdflt) = TCP6_MSS;
#endif
-uint32_t tcp_ack_war_time_window = 1000;
+VNET_DEFINE(uint32_t, tcp_ack_war_time_window) = 1000;
SYSCTL_UINT(_net_inet_tcp, OID_AUTO, ack_war_timewindow,
- CTLFLAG_RW,
- &tcp_ack_war_time_window, 1000,
- "If the tcp_stack does ack-war prevention how many milliseconds are in its time window?");
-uint32_t tcp_ack_war_cnt = 5;
-SYSCTL_UINT(_net_inet_tcp, OID_AUTO, ack_war_cnt,
- CTLFLAG_RW,
- &tcp_ack_war_cnt, 5,
- "If the tcp_stack does ack-war prevention how many acks can be sent in its time window?");
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_ack_war_time_window), 0,
+ "Time interval in ms used to limit the number (ack_war_cnt) of challenge ACKs sent per TCP connection");
+VNET_DEFINE(uint32_t, tcp_ack_war_cnt) = 5;
+SYSCTL_UINT(_net_inet_tcp, OID_AUTO, ack_war_cnt, CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(tcp_ack_war_cnt), 0,
+ "Maximum number of challenge ACKs sent per TCP connection during the time interval (ack_war_timewindow)");
struct rwlock tcp_function_lock;
@@ -2183,7 +2181,7 @@
/*
* Send a challenge ack (no data, no SACK option), but not more than
- * tcp_ack_war_cnt per tcp_ack_war_time_window (per TCP connection).
+ * V_tcp_ack_war_cnt per V_tcp_ack_war_time_window (per TCP connection).
*/
void
tcp_send_challenge_ack(struct tcpcb *tp, struct tcphdr *th, struct mbuf *m)
@@ -2191,7 +2189,7 @@
sbintime_t now;
bool send_challenge_ack;
- if (tcp_ack_war_time_window == 0 || tcp_ack_war_cnt == 0) {
+ if (V_tcp_ack_war_time_window == 0 || V_tcp_ack_war_cnt == 0) {
/* ACK war protection is disabled. */
send_challenge_ack = true;
} else {
@@ -2200,13 +2198,13 @@
if (tp->t_challenge_ack_end < now) {
tp->t_challenge_ack_cnt = 0;
tp->t_challenge_ack_end = now +
- tcp_ack_war_time_window * SBT_1MS;
+ V_tcp_ack_war_time_window * SBT_1MS;
}
/*
* Send a challenge ACK, if less than tcp_ack_war_cnt have been
* sent in the current epoch.
*/
- if (tp->t_challenge_ack_cnt < tcp_ack_war_cnt) {
+ if (tp->t_challenge_ack_cnt < V_tcp_ack_war_cnt) {
send_challenge_ack = true;
tp->t_challenge_ack_cnt++;
} else {
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1268,6 +1268,8 @@
VNET_DECLARE(int, drop_synfin);
VNET_DECLARE(int, path_mtu_discovery);
VNET_DECLARE(int, tcp_abc_l_var);
+VNET_DECLARE(uint32_t, tcp_ack_war_cnt);
+VNET_DECLARE(uint32_t, tcp_ack_war_time_window);
VNET_DECLARE(int, tcp_autorcvbuf_max);
VNET_DECLARE(int, tcp_autosndbuf_inc);
VNET_DECLARE(int, tcp_autosndbuf_max);
@@ -1319,6 +1321,8 @@
#define V_path_mtu_discovery VNET(path_mtu_discovery)
#define V_tcbinfo VNET(tcbinfo)
#define V_tcp_abc_l_var VNET(tcp_abc_l_var)
+#define V_tcp_ack_war_cnt VNET(tcp_ack_war_cnt)
+#define V_tcp_ack_war_time_window VNET(tcp_ack_war_time_window)
#define V_tcp_autorcvbuf_max VNET(tcp_autorcvbuf_max)
#define V_tcp_autosndbuf_inc VNET(tcp_autosndbuf_inc)
#define V_tcp_autosndbuf_max VNET(tcp_autosndbuf_max)

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 1, 11:01 PM (29 m, 48 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13285088
Default Alt Text
D46140.id.diff (6 KB)

Event Timeline