tcp: be more strict before accepting ECN negociation
[pandora-kernel.git] / include / net / tcp.h
index bb18c4d..238255b 100644 (file)
@@ -251,6 +251,7 @@ extern int sysctl_tcp_max_ssthresh;
 extern int sysctl_tcp_cookie_size;
 extern int sysctl_tcp_thin_linear_timeouts;
 extern int sysctl_tcp_thin_dupack;
+extern int sysctl_tcp_challenge_ack_limit;
 
 extern atomic_long_t tcp_memory_allocated;
 extern struct percpu_counter tcp_sockets_allocated;
@@ -357,13 +358,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,
@@ -651,6 +645,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.
  */
@@ -930,6 +940,7 @@ static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
        if (sysctl_tcp_low_latency || !tp->ucopy.task)
                return 0;
 
+       skb_dst_force(skb);
        __skb_queue_tail(&tp->ucopy.prequeue, skb);
        tp->ucopy.memory += skb->truesize;
        if (tp->ucopy.memory > sk->sk_rcvbuf) {