tcp: add rfc3168, section 6.1.1.1. fallback
[deliverable/linux.git] / net / ipv4 / tcp_output.c
index 08c2cc40b26d65227eccaf3b5a068c16cef62fa1..e29d43b5a0bb46305b0ab4af29bd05a61abd522d 100644 (file)
@@ -350,6 +350,15 @@ static void tcp_ecn_send_syn(struct sock *sk, struct sk_buff *skb)
        }
 }
 
+static void tcp_ecn_clear_syn(struct sock *sk, struct sk_buff *skb)
+{
+       if (sock_net(sk)->ipv4.sysctl_tcp_ecn_fallback)
+               /* tp->ecn_flags are cleared at a later point in time when
+                * SYN ACK is ultimatively being received.
+                */
+               TCP_SKB_CB(skb)->tcp_flags &= ~(TCPHDR_ECE | TCPHDR_CWR);
+}
+
 static void
 tcp_ecn_make_synack(const struct request_sock *req, struct tcphdr *th,
                    struct sock *sk)
@@ -2615,6 +2624,10 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
                }
        }
 
+       /* RFC3168, section 6.1.1.1. ECN fallback */
+       if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN_ECN) == TCPHDR_SYN_ECN)
+               tcp_ecn_clear_syn(sk, skb);
+
        tcp_retrans_try_collapse(sk, skb, cur_mss);
 
        /* Make a copy, if the first transmission SKB clone we made
This page took 0.026632 seconds and 5 git commands to generate.