Page MenuHomeFreeBSD

D23230.id112811.diff
No OneTemporary

D23230.id112811.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
@@ -34,7 +34,7 @@
.\" From: @(#)tcp.4 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd November 7, 2022
+.Dd November 9, 2022
.Dt TCP 4
.Os
.Sh NAME
@@ -510,11 +510,28 @@
.It 3
Negotiate on incoming connection for Accurate ECN, ECN, or no ECN.
Outgoing connections will request Accurate ECN and fall back to
-ECN depending on the capabilities of the server.
+ECN depending on the capabilities of the remote host.
.It 4
Negotiate on incoming connection for Accurate ECN, ECN, or no ECN.
Outgoing connections will not request ECN.
.El
+.It Va ecn.generalized
+Enable sending all segments as ECN capable transport,
+including SYN, SYN/ACK, and retransmissions.
+This may only be enabled when ECN support itself is also active.
+Disabling ECN support will disable this feature automatically.
+Settings:
+.Bl -tag -compact
+.It 0
+Regular RFC3168 operation.
+Send only new data segments as ECN capable transport.
+(default)
+.It 1
+Support generalized ECN (ECN++), and send all segments of an ECN-enabled
+session as ECN capable transport.
+Also control packets to non-established and non-listening ports are
+identically marked, if outgoing sessions would request ECN.
+.El
.It Va ecn.maxretries
Number of retries (SYN or SYN/ACK retransmits) before disabling ECN on a
specific connection.
diff --git a/sys/netinet/tcp_ecn.h b/sys/netinet/tcp_ecn.h
--- a/sys/netinet/tcp_ecn.h
+++ b/sys/netinet/tcp_ecn.h
@@ -44,12 +44,11 @@
void tcp_ecn_input_syn_sent(struct tcpcb *, uint16_t, int);
void tcp_ecn_input_parallel_syn(struct tcpcb *, uint16_t, int);
int tcp_ecn_input_segment(struct tcpcb *, uint16_t, int, int, int);
-uint16_t tcp_ecn_output_syn_sent(struct tcpcb *);
+int tcp_ecn_output_syn_sent(struct tcpcb *, uint16_t *);
int tcp_ecn_output_established(struct tcpcb *, uint16_t *, int, bool);
void tcp_ecn_syncache_socket(struct tcpcb *, struct syncache *);
int tcp_ecn_syncache_add(uint16_t, int);
-uint16_t tcp_ecn_syncache_respond(uint16_t, struct syncache *);
-int tcp_ecn_get_ace(uint16_t);
+int tcp_ecn_syncache_respond(uint16_t *, struct syncache *);
#endif /* _KERNEL */
diff --git a/sys/netinet/tcp_ecn.c b/sys/netinet/tcp_ecn.c
--- a/sys/netinet/tcp_ecn.c
+++ b/sys/netinet/tcp_ecn.c
@@ -106,8 +106,10 @@
"TCP ECN");
VNET_DEFINE(int, tcp_do_ecn) = 2;
-SYSCTL_INT(_net_inet_tcp_ecn, OID_AUTO, enable,
- CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_ecn), 0,
+static int sysctl_net_inet_tcp_ecn_enable_check(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_net_inet_tcp_ecn, OID_AUTO, enable,
+ CTLFLAG_VNET | CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_NEEDGIANT,
+ &VNET_NAME(tcp_do_ecn), 0, &sysctl_net_inet_tcp_ecn_enable_check, "IU",
"TCP ECN support");
VNET_DEFINE(int, tcp_ecn_maxretries) = 1;
@@ -115,28 +117,37 @@
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_ecn_maxretries), 0,
"Max retries before giving up on ECN");
+VNET_DEFINE(int, tcp_ecn_generalized) = 0;
+static int sysctl_net_inet_tcp_ecn_generalized_check(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_net_inet_tcp_ecn, OID_AUTO, generalized,
+ CTLFLAG_VNET | CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_NEEDGIANT,
+ &VNET_NAME(tcp_ecn_generalized), 0, &sysctl_net_inet_tcp_ecn_generalized_check, "IU",
+ "Send all packets as ECT");
+
+static inline int
+tcp_ecn_get_ace(uint16_t);
+
/*
* Process incoming SYN,ACK packet
*/
void
tcp_ecn_input_syn_sent(struct tcpcb *tp, uint16_t thflags, int iptos)
{
-
- if (V_tcp_do_ecn == 0)
- return;
- if ((V_tcp_do_ecn == 1) ||
- (V_tcp_do_ecn == 2)) {
- /* RFC3168 ECN handling */
+ switch (V_tcp_do_ecn) {
+ default:
+ case 0: return;
+ break;
+ case 1:
+ case 2: /* RFC3168 ECN handling */
if ((thflags & (TH_CWR | TH_ECE)) == (0 | TH_ECE)) {
tp->t_flags2 |= TF2_ECN_PERMIT;
tp->t_flags2 &= ~TF2_ACE_PERMIT;
TCPSTAT_INC(tcps_ecn_shs);
}
- } else
- /* decoding Accurate ECN according to table in section 3.1.1 */
- if ((V_tcp_do_ecn == 3) ||
- (V_tcp_do_ecn == 4)) {
- /*
+ break;
+ case 3:
+ case 4: /* decoding Accurate ECN according to
+ * table in section 3.1.1
* on the SYN,ACK, process the AccECN
* flags indicating the state the SYN
* was delivered.
@@ -213,6 +224,11 @@
tp->t_rcep = 0b110;
break;
}
+ break;
+ }
+ if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) {
+ if (V_tcp_ecn_generalized)
+ tp->t_flags2 |= TF2_ECN_PLUSPLUS;
}
}
@@ -224,21 +240,21 @@
{
if (thflags & TH_ACK)
return;
- if (V_tcp_do_ecn == 0)
- return;
- if ((V_tcp_do_ecn == 1) ||
- (V_tcp_do_ecn == 2)) {
- /* RFC3168 ECN handling */
+ switch (V_tcp_do_ecn) {
+ default:
+ case 0: return;
+ break;
+ case 1:
+ case 2: /* RFC3168 ECN handling */
if ((thflags & (TH_CWR | TH_ECE)) == (TH_CWR | TH_ECE)) {
tp->t_flags2 |= TF2_ECN_PERMIT;
tp->t_flags2 &= ~TF2_ACE_PERMIT;
tp->t_flags2 |= TF2_ECN_SND_ECE;
TCPSTAT_INC(tcps_ecn_shs);
}
- } else
- if ((V_tcp_do_ecn == 3) ||
- (V_tcp_do_ecn == 4)) {
- /* AccECN handling */
+ break;
+ case 3:
+ case 4: /* AccECN handling */
switch (thflags & (TH_AE | TH_CWR | TH_ECE)) {
default:
case (0|0|0):
@@ -277,6 +293,11 @@
}
break;
}
+ break;
+ }
+ if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) {
+ if (V_tcp_ecn_generalized)
+ tp->t_flags2 |= TF2_ECN_PLUSPLUS;
}
}
@@ -363,31 +384,45 @@
/*
* Send ECN setup <SYN> packet header flags
*/
-uint16_t
-tcp_ecn_output_syn_sent(struct tcpcb *tp)
+int
+tcp_ecn_output_syn_sent(struct tcpcb *tp, uint16_t *thflags)
{
- uint16_t thflags = 0;
-
- if (V_tcp_do_ecn == 0)
- return thflags;
- if (V_tcp_do_ecn == 1) {
- /* Send a RFC3168 ECN setup <SYN> packet */
+ switch(V_tcp_do_ecn) {
+ case 0: /* No ECN */
+ case 2: /* passive RFC3168 */
+ case 4: /* passice AccECN */
+ default:
+ return IPTOS_ECN_NOTECT;
+ break;
+ case 1: /* Send a RFC3168 ECN setup <SYN> packet */
if (tp->t_rxtshift >= 1) {
if (tp->t_rxtshift <= V_tcp_ecn_maxretries)
- thflags = TH_ECE|TH_CWR;
+ *thflags |= TH_ECE|TH_CWR;
+ else
+ return IPTOS_ECN_NOTECT;
} else
- thflags = TH_ECE|TH_CWR;
- } else
- if (V_tcp_do_ecn == 3) {
- /* Send an Accurate ECN setup <SYN> packet */
+ *thflags |= TH_ECE|TH_CWR;
+ break;
+ case 3: /* Send an Accurate ECN setup <SYN> packet */
if (tp->t_rxtshift >= 1) {
if (tp->t_rxtshift <= V_tcp_ecn_maxretries)
- thflags = TH_ECE|TH_CWR|TH_AE;
+ *thflags |= TH_ECE|TH_CWR|TH_AE;
+ else
+ return IPTOS_ECN_NOTECT;
} else
- thflags = TH_ECE|TH_CWR|TH_AE;
+ *thflags |= TH_ECE|TH_CWR|TH_AE;
+ break;
}
-
- return thflags;
+ if (V_tcp_ecn_generalized) {
+ if (tp->t_flags2 & TF2_ECN_USE_ECT1) {
+ ipecn = IPTOS_ECN_ECT1;
+ TCPSTAT_INC(tcps_ecn_ect1);
+ } else {
+ ipecn = IPTOS_ECN_ECT0;
+ TCPSTAT_INC(tcps_ecn_ect0);
+ }
+ }
+ return IPTOS_ECN_NOTECT;
}
/*
@@ -409,8 +444,15 @@
newdata = (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) &&
!rxmit &&
!((tp->t_flags & TF_FORCEDATA) && len == 1));
- /* RFC3168 ECN marking, only new data segments */
- if (newdata) {
+ /*
+ * RFC3168 ECN marking for new data segments, or
+ * for all segments as ECN-capable transport
+ * when ecn.generalized is set.
+ */
+ if (newdata ||
+ tp->t_flags2 & TF2_ECN_PLUSPLUS ||
+ (tp->t_state == TCPS_SYN_SENT &&
+ V_tcp_ecn_generalized)) {
if (tp->t_flags2 & TF2_ECN_USE_ECT1) {
ipecn = IPTOS_ECN_ECT1;
TCPSTAT_INC(tcps_ecn_ect1);
@@ -486,6 +528,10 @@
break;
}
}
+ if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) {
+ if (V_tcp_ecn_generalized)
+ tp->t_flags2 |= TF2_ECN_PLUSPLUS;
+ }
}
/*
@@ -554,45 +600,62 @@
* Set up the ECN information for the <SYN,ACK> from
* syncache information.
*/
-uint16_t
-tcp_ecn_syncache_respond(uint16_t thflags, struct syncache *sc)
+int
+tcp_ecn_syncache_respond(uint16_t *thflags, struct syncache *sc)
{
- if ((thflags & TH_SYN) &&
+ int ipecn = IPTOS_ECN_NOTECT;
+
+ if ((*thflags & TH_SYN) &&
(sc->sc_flags & SCF_ECN_MASK)) {
switch (sc->sc_flags & SCF_ECN_MASK) {
case SCF_ECN:
- thflags |= (0 | 0 | TH_ECE);
+ *thflags |= (0 | 0 | TH_ECE);
TCPSTAT_INC(tcps_ecn_shs);
+ if ((V_tcp_ecn_generalized &&
+ (*thflags & TH_ACK)))
+ ipecn = IPTOS_ECN_ECT0;
break;
case SCF_ACE_N:
- thflags |= (0 | TH_CWR | 0);
+ *thflags |= (0 | TH_CWR | 0);
TCPSTAT_INC(tcps_ecn_shs);
TCPSTAT_INC(tcps_ace_nect);
+ if ((V_tcp_ecn_generalized &&
+ (*thflags & TH_ACK)))
+ ipecn = IPTOS_ECN_ECT0;
break;
case SCF_ACE_0:
- thflags |= (TH_AE | 0 | 0);
+ *thflags |= (TH_AE | 0 | 0);
TCPSTAT_INC(tcps_ecn_shs);
TCPSTAT_INC(tcps_ace_ect0);
+ if ((V_tcp_ecn_generalized &&
+ (*thflags & TH_ACK)))
+ ipecn = IPTOS_ECN_ECT0;
break;
case SCF_ACE_1:
- thflags |= (0 | TH_ECE | TH_CWR);
+ *thflags |= (0 | TH_ECE | TH_CWR);
TCPSTAT_INC(tcps_ecn_shs);
TCPSTAT_INC(tcps_ace_ect1);
+ if ((V_tcp_ecn_generalized &&
+ (*thflags & TH_ACK)))
+ ipecn = IPTOS_ECN_ECT0;
break;
case SCF_ACE_CE:
- thflags |= (TH_AE | TH_CWR | 0);
+ *thflags |= (TH_AE | TH_CWR | 0);
TCPSTAT_INC(tcps_ecn_shs);
TCPSTAT_INC(tcps_ace_ce);
+ if ((V_tcp_ecn_generalized &&
+ (*thflags & TH_ACK)))
+ ipecn = IPTOS_ECN_ECT0;
break;
/* undefined SCF codepoint */
default:
break;
}
}
- return thflags;
+ return ipecn;
}
-int
+static inline int
tcp_ecn_get_ace(uint16_t thflags)
{
int ace = 0;
@@ -605,3 +668,45 @@
ace += 4;
return ace;
}
+
+static int
+sysctl_net_inet_tcp_ecn_enable_check(SYSCTL_HANDLER_ARGS)
+{
+ uint32_t new;
+ int error;
+
+ new = V_tcp_do_ecn;
+ error = sysctl_handle_int(oidp, &new, 0, req);
+ if (error == 0 && req->newptr != NULL) {
+ if (new > 4)
+ error = EINVAL;
+ else {
+ V_tcp_do_ecn = new;
+ if (new == 0)
+ V_tcp_ecn_generalized = new;
+ }
+ }
+
+ return (error);
+}
+
+static int
+sysctl_net_inet_tcp_ecn_generalized_check(SYSCTL_HANDLER_ARGS)
+{
+ uint32_t new;
+ int error;
+
+ new = V_tcp_ecn_generalized;
+ error = sysctl_handle_int(oidp, &new, 0, req);
+ if (error == 0 && req->newptr != NULL) {
+ if (new > 1)
+ error = EINVAL;
+ else
+ if (!V_tcp_do_ecn && new == 1)
+ error = EINVAL;
+ else
+ V_tcp_ecn_generalized = new;
+ }
+
+ return (error);
+}
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -4105,3 +4105,4 @@
return (4 * maxseg);
}
}
+
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -201,6 +201,7 @@
int32_t len;
uint32_t recwin, sendwin;
uint16_t flags;
+ int ect = 0;
int off, error = 0; /* Keep compiler happy */
u_int if_hw_tsomaxsegcount = 0;
u_int if_hw_tsomaxsegsize = 0;
@@ -1205,26 +1206,27 @@
* RFC 3168.
*/
if (tp->t_state == TCPS_SYN_SENT && V_tcp_do_ecn) {
- flags |= tcp_ecn_output_syn_sent(tp);
+ ect = tcp_ecn_output_syn_sent(tp, &flags);
}
/* Also handle parallel SYN for ECN */
- if ((TCPS_HAVERCVDSYN(tp->t_state)) &&
- (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))) {
- int ect = tcp_ecn_output_established(tp, &flags, len, sack_rxmit);
+ if ((tp->t_flags2 & TF2_ECN_PLUSPLUS) ||
+ (TCPS_HAVERCVDSYN(tp->t_state) &&
+ (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)))) {
+ ect = tcp_ecn_output_established(tp, &flags, len, sack_rxmit);
if ((tp->t_state == TCPS_SYN_RECEIVED) &&
(tp->t_flags2 & TF2_ECN_SND_ECE))
tp->t_flags2 &= ~TF2_ECN_SND_ECE;
+ }
#ifdef INET6
- if (isipv6) {
- ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20);
- ip6->ip6_flow |= htonl(ect << 20);
- }
- else
+ if (isipv6) {
+ ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20);
+ ip6->ip6_flow |= htonl(ect << 20);
+ }
+ else
#endif
- {
- ip->ip_tos &= ~IPTOS_ECN_MASK;
- ip->ip_tos |= ect;
- }
+ {
+ ip->ip_tos &= ~IPTOS_ECN_MASK;
+ ip->ip_tos |= ect;
}
/*
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
@@ -16675,6 +16675,7 @@
struct socket *so;
uint32_t recwin;
uint32_t sb_offset, s_moff = 0;
+ uint8_t ect = 0;
int32_t len, error = 0;
uint16_t flags;
struct mbuf *m, *s_mb = NULL;
@@ -18511,26 +18512,27 @@
* as per RFC 3168.
*/
if (tp->t_state == TCPS_SYN_SENT && V_tcp_do_ecn) {
- flags |= tcp_ecn_output_syn_sent(tp);
+ ect |= tcp_ecn_output_syn_sent(tp, &flags);
}
/* Also handle parallel SYN for ECN */
- if (TCPS_HAVERCVDSYN(tp->t_state) &&
- (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))) {
- int ect = tcp_ecn_output_established(tp, &flags, len, sack_rxmit);
+ if ((tp->t_flags2 & TF2_ECN_PLUSPLUS) ||
+ (TCPS_HAVERCVDSYN(tp->t_state) &&
+ (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)))) {
+ ect = tcp_ecn_output_established(tp, &flags, len, sack_rxmit);
if ((tp->t_state == TCPS_SYN_RECEIVED) &&
(tp->t_flags2 & TF2_ECN_SND_ECE))
tp->t_flags2 &= ~TF2_ECN_SND_ECE;
+ }
#ifdef INET6
- if (isipv6) {
- ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20);
- ip6->ip6_flow |= htonl(ect << 20);
- }
- else
+ if (isipv6) {
+ ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20);
+ ip6->ip6_flow |= htonl(ect << 20);
+ }
+ else
#endif
- {
- ip->ip_tos &= ~IPTOS_ECN_MASK;
- ip->ip_tos |= ect;
- }
+ {
+ ip->ip_tos &= ~IPTOS_ECN_MASK;
+ ip->ip_tos |= ect;
}
/*
* If we are doing retransmissions, then snd_nxt will not reflect
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
@@ -1991,6 +1991,23 @@
optp = (u_char *) (nth + 1);
optm = m;
}
+ } else {
+ /*
+ * Send out control packets with same IP ECN header
+ */
+ if (V_tcp_ecn_generalized &&
+ ((V_tcp_do_ecn == 1) ||
+ (V_tcp_do_ecn == 3) ||
+ ((tp != NULL) &&
+ (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))))) {
+ if ((tp != NULL) && (tp->t_flags2 & TF2_ECN_USE_ECT1)) {
+ ipecn = IPTOS_ECN_ECT1;
+ TCPSTAT_INC(tcps_ecn_ect1);
+ } else {
+ ipecn = IPTOS_ECN_ECT0;
+ TCPSTAT_INC(tcps_ecn_ect0);
+ }
+ }
}
if (incl_opts) {
/* Timestamps. */
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -129,7 +129,7 @@
static void syncache_drop(struct syncache *, struct syncache_head *);
static void syncache_free(struct syncache *);
static void syncache_insert(struct syncache *, struct syncache_head *);
-static int syncache_respond(struct syncache *, const struct mbuf *, int);
+static int syncache_respond(struct syncache *, const struct mbuf *, uint16_t);
static struct socket *syncache_socket(struct syncache *, struct socket *,
struct mbuf *m);
static void syncache_timeout(struct syncache *sc, struct syncache_head *sch,
@@ -1805,14 +1805,15 @@
* i.e. m0 != NULL, or upon 3WHS ACK timeout, i.e. m0 == NULL.
*/
static int
-syncache_respond(struct syncache *sc, const struct mbuf *m0, int flags)
+syncache_respond(struct syncache *sc, const struct mbuf *m0, uint16_t flags)
{
struct ip *ip = NULL;
struct mbuf *m;
struct tcphdr *th = NULL;
struct udphdr *udp = NULL;
int optlen, error = 0; /* Make compiler happy */
- u_int16_t hlen, tlen, mssopt, ulen;
+ uint16_t hlen, tlen, mssopt, ulen;
+ int ect;
struct tcpopt to;
#ifdef INET6
struct ip6_hdr *ip6 = NULL;
@@ -1929,7 +1930,17 @@
th->th_win = htons(sc->sc_wnd);
th->th_urp = 0;
- flags = tcp_ecn_syncache_respond(flags, sc);
+ ect = tcp_ecn_syncache_respond(&flags, sc);
+#ifdef INET6
+ if (sc->sc_inc.inc_flags & INC_ISIPV6)
+ ip6->ip6_flow |= htonl(ect << 20);
+#endif
+#if defined(INET6) && defined(INET)
+ else
+#endif
+#ifdef INET
+ ip->ip_tos |= ect;
+#endif
tcp_set_flags(th, flags);
/* Tack on the TCP options. */
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -3036,6 +3036,10 @@
db_printf("%sTF2_ACE_PERMIT", comma ? ", " : "");
comma = 1;
}
+ if (t_flags2 & TF2_ECN_PLUSPLUS) {
+ db_printf("%sTF2_ECN_PLUSPLUS", comma ? ", " : "");
+ comma = 1;
+ }
if (t_flags2 & TF2_FBYTES_COMPLETE) {
db_printf("%sTF2_FBYTES_COMPLETE", comma ? ", " : "");
comma = 1;
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
@@ -586,6 +586,7 @@
#define TF2_ACE_PERMIT 0x00000100 /* Accurate ECN mode */
#define TF2_FBYTES_COMPLETE 0x00000400 /* We have first bytes in and out */
#define TF2_ECN_USE_ECT1 0x00000800 /* Use ECT(1) marking on session */
+#define TF2_ECN_PLUSPLUS 0x00001000 /* ECN++ session */
/*
* Structure to hold TCP options that are only used during segment
@@ -1002,6 +1003,7 @@
VNET_DECLARE(int, tcp_do_sack);
VNET_DECLARE(int, tcp_do_tso);
VNET_DECLARE(int, tcp_ecn_maxretries);
+VNET_DECLARE(int, tcp_ecn_generalized);
VNET_DECLARE(int, tcp_initcwnd_segments);
VNET_DECLARE(int, tcp_insecure_rst);
VNET_DECLARE(int, tcp_insecure_syn);
@@ -1048,6 +1050,7 @@
#define V_tcp_do_sack VNET(tcp_do_sack)
#define V_tcp_do_tso VNET(tcp_do_tso)
#define V_tcp_ecn_maxretries VNET(tcp_ecn_maxretries)
+#define V_tcp_ecn_generalized VNET(tcp_ecn_generalized)
#define V_tcp_initcwnd_segments VNET(tcp_initcwnd_segments)
#define V_tcp_insecure_rst VNET(tcp_insecure_rst)
#define V_tcp_insecure_syn VNET(tcp_insecure_syn)

File Metadata

Mime Type
text/plain
Expires
Fri, May 22, 12:25 AM (15 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33410675
Default Alt Text
D23230.id112811.diff (17 KB)

Event Timeline