patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / net / ipv4 / netfilter / ipt_ECN.c
index 341e845..8ca4025 100644 (file)
@@ -50,7 +50,7 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 
 /* Return 0 if there was an error. */
 static inline int
-set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
+set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo, int inward)
 {
        struct tcphdr tcph;
        u_int16_t diffs[2];
@@ -74,11 +74,15 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
                if (!skb_ip_make_writable(pskb,
                                          (*pskb)->nh.iph->ihl*4+sizeof(tcph)))
                        return 0;
-               tcph.check = csum_fold(csum_partial((char *)diffs,
-                                                   sizeof(diffs),
-                                                   tcph.check^0xFFFF));
+               if ((*pskb)->ip_summed != CHECKSUM_HW)
+                       tcph.check = csum_fold(csum_partial((char *)diffs,
+                                              sizeof(diffs),
+                                              tcph.check^0xFFFF));
                memcpy((*pskb)->data + (*pskb)->nh.iph->ihl*4,
                       &tcph, sizeof(tcph));
+               if ((*pskb)->ip_summed == CHECKSUM_HW)
+                       if (skb_checksum_help(pskb, inward))
+                               return 0;
                (*pskb)->nfcache |= NFC_ALTERED;
        }
        return 1;
@@ -100,7 +104,7 @@ target(struct sk_buff **pskb,
 
        if (einfo->operation & (IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR)
            && (*pskb)->nh.iph->protocol == IPPROTO_TCP)
-               if (!set_ect_tcp(pskb, einfo))
+               if (!set_ect_tcp(pskb, einfo, (out == NULL)))
                        return NF_DROP;
 
        return IPT_CONTINUE;