|
@@ -233,14 +233,21 @@ static inline void TCP_ECN_check_ce(struct tcp_sock *tp, const struct sk_buff *s
|
|
|
tcp_enter_quickack_mode((struct sock *)tp);
|
|
|
break;
|
|
|
case INET_ECN_CE:
|
|
|
+ if (tcp_ca_needs_ecn((struct sock *)tp))
|
|
|
+ tcp_ca_event((struct sock *)tp, CA_EVENT_ECN_IS_CE);
|
|
|
+
|
|
|
if (!(tp->ecn_flags & TCP_ECN_DEMAND_CWR)) {
|
|
|
/* Better not delay acks, sender can have a very low cwnd */
|
|
|
tcp_enter_quickack_mode((struct sock *)tp);
|
|
|
tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
|
|
|
}
|
|
|
- /* fallinto */
|
|
|
+ tp->ecn_flags |= TCP_ECN_SEEN;
|
|
|
+ break;
|
|
|
default:
|
|
|
+ if (tcp_ca_needs_ecn((struct sock *)tp))
|
|
|
+ tcp_ca_event((struct sock *)tp, CA_EVENT_ECN_NO_CE);
|
|
|
tp->ecn_flags |= TCP_ECN_SEEN;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -3429,10 +3436,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
|
|
tp->snd_una = ack;
|
|
|
flag |= FLAG_WIN_UPDATE;
|
|
|
|
|
|
- tcp_in_ack_event(sk, 0);
|
|
|
+ tcp_in_ack_event(sk, CA_ACK_WIN_UPDATE);
|
|
|
|
|
|
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPACKS);
|
|
|
} else {
|
|
|
+ u32 ack_ev_flags = CA_ACK_SLOWPATH;
|
|
|
+
|
|
|
if (ack_seq != TCP_SKB_CB(skb)->end_seq)
|
|
|
flag |= FLAG_DATA;
|
|
|
else
|
|
@@ -3444,10 +3453,15 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
|
|
flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una,
|
|
|
&sack_rtt_us);
|
|
|
|
|
|
- if (TCP_ECN_rcv_ecn_echo(tp, tcp_hdr(skb)))
|
|
|
+ if (TCP_ECN_rcv_ecn_echo(tp, tcp_hdr(skb))) {
|
|
|
flag |= FLAG_ECE;
|
|
|
+ ack_ev_flags |= CA_ACK_ECE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (flag & FLAG_WIN_UPDATE)
|
|
|
+ ack_ev_flags |= CA_ACK_WIN_UPDATE;
|
|
|
|
|
|
- tcp_in_ack_event(sk, CA_ACK_SLOWPATH);
|
|
|
+ tcp_in_ack_event(sk, ack_ev_flags);
|
|
|
}
|
|
|
|
|
|
/* We passed data and got it acked, remove any soft error
|