aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_output.c
diff options
context:
space:
mode:
authorRui Paulo <rpaulo@FreeBSD.org>2008-07-31 15:10:09 +0000
committerRui Paulo <rpaulo@FreeBSD.org>2008-07-31 15:10:09 +0000
commitf2512ba12a4287ab799825c7c4f4f260846cf596 (patch)
tree8b911acf57ec2b96a01e7db35ef80bd6af6601a0 /sys/netinet/tcp_output.c
parent6d9e8f2b3a71b1983adccf0ef8ac8caa809ef932 (diff)
downloadsrc-f2512ba12a4287ab799825c7c4f4f260846cf596.tar.gz
src-f2512ba12a4287ab799825c7c4f4f260846cf596.zip
MFp4 (//depot/projects/tcpecn/):
TCP ECN support. Merge of my GSoC 2006 work for NetBSD. TCP ECN is defined in RFC 3168. Partly reviewed by: dwmalone, silby Obtained from: NetBSD
Notes
Notes: svn path=/head/; revision=181056
Diffstat (limited to 'sys/netinet/tcp_output.c')
-rw-r--r--sys/netinet/tcp_output.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index 8d9c07e0d4a0..ac8b9e054982 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -877,6 +877,49 @@ send:
tp->snd_nxt == tp->snd_max)
tp->snd_nxt--;
/*
+ * If we are starting a connection, send ECN setup
+ * SYN packet. If we are on a retransmit, we may
+ * resend those bits a number of times as per
+ * RFC 3168.
+ */
+ if (tp->t_state == TCPS_SYN_SENT && tcp_do_ecn) {
+ if (tp->t_rxtshift >= 1) {
+ if (tp->t_rxtshift <= tcp_ecn_maxretries)
+ flags |= TH_ECE|TH_CWR;
+ } else
+ flags |= TH_ECE|TH_CWR;
+ }
+
+ if (tp->t_state == TCPS_ESTABLISHED &&
+ (tp->t_flags & TF_ECN_PERMIT)) {
+ /*
+ * If the peer has ECN, mark data packets with
+ * ECN capable transmission (ECT).
+ * Ignore pure ack packets, retransmissions and window probes.
+ */
+ if (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) &&
+ !((tp->t_flags & TF_FORCEDATA) && len == 1)) {
+#ifdef INET6
+ if (isipv6)
+ ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
+ else
+#endif
+ ip->ip_tos |= IPTOS_ECN_ECT0;
+ tcpstat.tcps_ecn_ect0++;
+ }
+
+ /*
+ * Reply with proper ECN notifications.
+ */
+ if (tp->t_flags & TF_ECN_SND_CWR) {
+ flags |= TH_CWR;
+ tp->t_flags &= ~TF_ECN_SND_CWR;
+ }
+ if (tp->t_flags & TF_ECN_SND_ECE)
+ flags |= TH_ECE;
+ }
+
+ /*
* If we are doing retransmissions, then snd_nxt will
* not reflect the first unsent octet. For ACK only
* packets, we do not want the sequence number of the