Page MenuHomeFreeBSD

D37281.id112657.diff
No OneTemporary

D37281.id112657.diff

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
@@ -43,7 +43,7 @@
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 tcp_ecn_input_segment(struct tcpcb *, uint16_t, int, int, int);
uint16_t tcp_ecn_output_syn_sent(struct tcpcb *);
int tcp_ecn_output_established(struct tcpcb *, uint16_t *, int, bool);
void tcp_ecn_syncache_socket(struct tcpcb *, struct syncache *);
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
@@ -271,9 +271,9 @@
* TCP ECN processing.
*/
int
-tcp_ecn_input_segment(struct tcpcb *tp, uint16_t thflags, int iptos)
+tcp_ecn_input_segment(struct tcpcb *tp, uint16_t thflags, int tlen, int pkts, int iptos)
{
- int delta_ace = 0;
+ int delta_cep = 0;
if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) {
switch (iptos & IPTOS_ECN_MASK) {
@@ -292,9 +292,12 @@
if ((iptos & IPTOS_ECN_MASK) == IPTOS_ECN_CE)
tp->t_rcep += 1;
if (tp->t_flags2 & TF2_ECN_PERMIT) {
- delta_ace = (tcp_ecn_get_ace(thflags) + 8 -
- (tp->t_scep & 0x07)) & 0x07;
- tp->t_scep += delta_ace;
+ delta_cep = (tcp_ecn_get_ace(thflags) + 8 -
+ (tp->t_scep & 7)) & 7;
+ if (delta_cep < pkts)
+ delta_cep = pkts -
+ ((pkts - delta_cep) & 7);
+ tp->t_scep += delta_cep;
} else {
/*
* process the final ACK of the 3WHS
@@ -325,8 +328,10 @@
}
} else {
/* RFC3168 ECN handling */
- if ((thflags & (TH_SYN | TH_ECE)) == TH_ECE)
- delta_ace = 1;
+ if ((thflags & (TH_SYN | TH_ECE)) == TH_ECE) {
+ delta_cep = 1;
+ tp->t_scep++;
+ }
if (thflags & TH_CWR) {
tp->t_flags2 &= ~TF2_ECN_SND_ECE;
tp->t_flags |= TF_ACKNOW;
@@ -339,7 +344,7 @@
cc_ecnpkt_handler_flags(tp, thflags, iptos);
}
- return delta_ace;
+ return delta_cep;
}
/*
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
@@ -1627,7 +1627,9 @@
/*
* TCP ECN processing.
*/
- if (tcp_ecn_input_segment(tp, thflags, iptos))
+ if (tcp_ecn_input_segment(tp, thflags, tlen,
+ tcp_packets_this_ack(tp, th->th_ack),
+ iptos))
cc_cong_signal(tp, th, CC_ECN);
/*
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
@@ -13528,8 +13528,10 @@
rack_cc_after_idle(rack, tp);
}
tp->t_rcvtime = ticks;
- /* Now what about ECN? */
- if (tcp_ecn_input_segment(tp, ae->flags, ae->codepoint))
+ /* Now what about ECN of a chain of pure ACKs? */
+ if (tcp_ecn_input_segment(tp, ae->flags, 0,
+ tcp_packets_this_ack(tp, ae->ack),
+ ae->codepoint))
rack_cong_signal(tp, CC_ECN, ae->ack, __LINE__);
#ifdef TCP_ACCOUNTING
/* Count for the specific type of ack in */
@@ -14320,7 +14322,9 @@
* TCP ECN processing. XXXJTL: If we ever use ECN, we need to move
* this to occur after we've validated the segment.
*/
- if (tcp_ecn_input_segment(tp, thflags, iptos))
+ if (tcp_ecn_input_segment(tp, thflags, tlen,
+ tcp_packets_this_ack(tp, th->th_ack),
+ iptos))
rack_cong_signal(tp, CC_ECN, th->th_ack, __LINE__);
/*
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
@@ -551,6 +551,12 @@
#endif
#define BYTES_THIS_ACK(tp, th) (th->th_ack - tp->snd_una)
+static int inline
+tcp_packets_this_ack(struct tcpcb *tp, tcp_seq ack)
+{
+ return ((ack - tp->snd_una) / tp->t_maxseg +
+ ((ack - tp->snd_una) % tp->t_maxseg) != 0 ? 1 : 0);
+}
/*
* Flags for the t_oobflags field.

File Metadata

Mime Type
text/plain
Expires
Thu, May 14, 9:47 PM (7 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33062901
Default Alt Text
D37281.id112657.diff (3 KB)

Event Timeline