tcp: be more strict before accepting ECN negociation
[pandora-kernel.git] / include / net / tcp.h
index c826ed7..92faa6a 100644 (file)
@@ -367,13 +367,6 @@ static inline void tcp_dec_quickack_mode(struct sock *sk,
 #define        TCP_ECN_DEMAND_CWR      4
 #define        TCP_ECN_SEEN            8
 
-static __inline__ void
-TCP_ECN_create_request(struct request_sock *req, struct tcphdr *th)
-{
-       if (sysctl_tcp_ecn && th->ece && th->cwr)
-               inet_rsk(req)->ecn_ok = 1;
-}
-
 enum tcp_tw_status {
        TCP_TW_SUCCESS = 0,
        TCP_TW_RST = 1,
@@ -671,6 +664,22 @@ struct tcp_skb_cb {
 
 #define TCP_SKB_CB(__skb)      ((struct tcp_skb_cb *)&((__skb)->cb[0]))
 
+/* RFC3168 : 6.1.1 SYN packets must not have ECT/ECN bits set
+ *
+ * If we receive a SYN packet with these bits set, it means a network is
+ * playing bad games with TOS bits. In order to avoid possible false congestion
+ * notifications, we disable TCP ECN negociation.
+ */
+static inline void
+TCP_ECN_create_request(struct request_sock *req, const struct sk_buff *skb)
+{
+       const struct tcphdr *th = tcp_hdr(skb);
+
+       if (sysctl_tcp_ecn && th->ece && th->cwr &&
+           INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield))
+               inet_rsk(req)->ecn_ok = 1;
+}
+
 /* Due to TSO, an SKB can be composed of multiple actual
  * packets.  To keep these tracked properly, we use this.
  */