]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/ipv4/tcp_input.c
net: tcp: more detailed ACK events and events for CE marked packets
[karo-tx-linux.git] / net / ipv4 / tcp_input.c
index 8a38774cc66efc0351599a0a47da97846aa39eaa..fc133178c787484c5d58e0bf52036de7302efb10 100644 (file)
@@ -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