Page MenuHomeFreeBSD

D23230.id111188.diff
No OneTemporary

D23230.id111188.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 August 1, 2022
+.Dd September 29, 2022
.Dt TCP 4
.Os
.Sh NAME
@@ -515,6 +515,23 @@
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);
-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
@@ -102,6 +102,8 @@
#include <netinet/tcpip.h>
#include <netinet/tcp_ecn.h>
+static inline int
+tcp_ecn_get_ace(uint16_t);
/*
* Process incoming SYN,ACK packet
@@ -109,7 +111,6 @@
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) ||
@@ -195,6 +196,10 @@
break;
}
}
+ if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) {
+ if (V_tcp_ecn_generalized)
+ tp->t_flags2 |= TF2_ECN_PLUSPLUS;
+ }
}
/*
@@ -255,6 +260,10 @@
break;
}
}
+ if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) {
+ if (V_tcp_ecn_generalized)
+ tp->t_flags2 |= TF2_ECN_PLUSPLUS;
+ }
}
/*
@@ -335,31 +344,38 @@
/*
* 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)
+ return IPTOS_ECN_ECT0;
+ return IPTOS_ECN_NOTECT;
}
/*
@@ -378,11 +394,19 @@
* Ignore pure control packets, retransmissions
* and window probes.
*/
+ log(2, "%s:%d\t flags2:%03x state:%d general:%d\n", __func__, __LINE__, tp->t_flags2, tp->t_state, V_tcp_ecn_generalized);
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) {
+ if (newdata ||
+ /*
+ * RFC3168 ECN marking for new data segments, or
+ * for all segments as ECN-capable transport
+ * when ecn.generalized is set.
+ */
+ tp->t_flags2 & TF2_ECN_PLUSPLUS ||
+ (tp->t_state == TCPS_SYN_SENT &&
+ V_tcp_ecn_generalized)) {
ipecn = IPTOS_ECN_ECT0;
TCPSTAT_INC(tcps_ecn_ect0);
}
@@ -453,6 +477,10 @@
break;
}
}
+ if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) {
+ if (V_tcp_ecn_generalized)
+ tp->t_flags2 |= TF2_ECN_PLUSPLUS;
+ }
}
/*
@@ -521,45 +549,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;
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
@@ -209,8 +209,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;
@@ -218,6 +220,13 @@
&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");
+
VNET_DEFINE(int, tcp_insecure_syn) = 0;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, insecure_syn, CTLFLAG_VNET | CTLFLAG_RW,
&VNET_NAME(tcp_insecure_syn), 0,
@@ -4135,3 +4144,45 @@
return (4 * maxseg);
}
}
+
+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 > 2)
+ 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_output.c b/sys/netinet/tcp_output.c
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -202,6 +202,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;
@@ -1206,27 +1207,29 @@
* 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;
}
+ log(2, "%s:%d\tect:%d flags:%03x\n", __func__, __LINE__, ip->ip_tos, tp->t_flags2);
/*
* If we are doing retransmissions, then snd_nxt will
@@ -1539,7 +1542,6 @@
/* Save packet, if requested. */
tcp_pcap_add(th, m, &(tp->t_outpkts));
#endif
-
error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), 0,
tp->t_inpcb);
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
@@ -16686,6 +16686,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;
@@ -18521,26 +18522,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
@@ -2086,6 +2086,29 @@
}
#endif
+ /*
+ * Send out control packets with same IP ECN header
+ * bits, as when an established or listening socket
+ * would exist.
+ */
+ 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))))) {
+#ifdef INET6
+ if (isipv6)
+ ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
+#endif /* INET6 */
+#if defined(INET6) && defined(INET)
+ else
+#endif
+#ifdef INET
+ ip->ip_tos |= IPTOS_ECN_ECT0;
+#endif /* INET */
+ }
+
+ m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
#ifdef INET6
if (isipv6) {
if (port) {
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
@@ -132,7 +132,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,
@@ -1807,14 +1807,14 @@
* 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;
struct tcpopt to;
#ifdef INET6
struct ip6_hdr *ip6 = NULL;
@@ -1931,7 +1931,17 @@
th->th_win = htons(sc->sc_wnd);
th->th_urp = 0;
- flags = tcp_ecn_syncache_respond(flags, sc);
+ int 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_timewait.c b/sys/netinet/tcp_timewait.c
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -330,6 +330,7 @@
tw->rcv_nxt = tp->rcv_nxt;
tw->tw_time = 0;
tw->tw_flags = tp->t_flags;
+ tw->tw_flags2 = tp->t_flags2;
/* XXX
* If this code will
@@ -693,6 +694,28 @@
TCPMD5_OUTPUT(m, th, to.to_signature) != 0)
return (-1);
}
+
+ /*
+ * Send out control packets with same IP ECN header
+ * bits during TIMEWAIT as in ESTABLISHED.
+ */
+ if (V_tcp_ecn_generalized &&
+ ((V_tcp_do_ecn == 1) ||
+ (V_tcp_do_ecn == 3) ||
+ ((tw != NULL) &&
+ (tw->tw_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))))) {
+#ifdef INET6
+ if (isipv6)
+ ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
+#endif /* INET6 */
+#if defined(INET6) && defined(INET)
+ else
+#endif
+#ifdef INET
+ ip->ip_tos |= IPTOS_ECN_ECT0;
+#endif /* INET */
+ }
+
#endif
#ifdef INET6
if (isipv6) {
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
@@ -3080,6 +3080,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
@@ -570,6 +570,7 @@
#define TF2_ECN_SND_CWR 0x00000040 /* ECN CWR in queue */
#define TF2_ECN_SND_ECE 0x00000080 /* ECN ECE in queue */
#define TF2_ACE_PERMIT 0x00000100 /* Accurate ECN mode */
+#define TF2_ECN_PLUSPLUS 0x00000200 /* ECN++ session */
#define TF2_FBYTES_COMPLETE 0x00000400 /* We have first bytes in and out */
/*
* Structure to hold TCP options that are only used during segment
@@ -645,6 +646,7 @@
int tw_time;
TAILQ_ENTRY(tcptw) tw_2msl;
u_int tw_flags; /* tcpcb t_flags */
+ u_int tw_flags2; /* tcpcb t_flags2 */
};
#define intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb)
@@ -1006,6 +1008,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);
@@ -1052,6 +1055,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
Thu, Mar 26, 8:05 PM (16 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30394248
Default Alt Text
D23230.id111188.diff (17 KB)

Event Timeline