diff -urp linux-2.6.18-cs1-xenU.orig/net/ipv4/netfilter/ip_nat_helper.c linux-2.6.18-cs1-xenU/net/ipv4/netfilter/ip_nat_helper.c --- linux-2.6.18-cs1-xenU.orig/net/ipv4/netfilter/ip_nat_helper.c 2006-09-28 23:44:19.000000000 +0200 +++ linux-2.6.18-cs1-xenU/net/ipv4/netfilter/ip_nat_helper.c 2006-09-28 23:43:55.000000000 +0200 @@ -184,9 +184,18 @@ ip_nat_mangle_tcp_packet(struct sk_buff match_offset, match_len, rep_buffer, rep_len); datalen = (*pskb)->len - iph->ihl*4; - tcph->check = 0; - tcph->check = tcp_v4_check(tcph, datalen, iph->saddr, iph->daddr, - csum_partial((char *)tcph, datalen, 0)); +#ifdef CONFIG_XEN + if (!(*pskb)->proto_csum_blank) { +#endif + tcph->check = 0; + tcph->check = tcp_v4_check(tcph, datalen, iph->saddr, iph->daddr, + csum_partial((char *)tcph, datalen, 0)); +#ifdef CONFIG_XEN + } else if (rep_len != match_len) + tcph->check = + ip_nat_cheat_check(htons(datalen - rep_len + match_len), + htons(datalen) ^ 0xFFFF, tcph->check); +#endif if (rep_len != match_len) { set_bit(IPS_SEQ_ADJUST_BIT, &ct->status); @@ -245,6 +254,9 @@ ip_nat_mangle_udp_packet(struct sk_buff udph->len = htons((*pskb)->len - iph->ihl*4); /* fix udp checksum if udp checksum was previously calculated */ +#ifdef CONFIG_XEN + if (!(*pskb)->proto_csum_blank) { +#endif if (udph->check) { int datalen = (*pskb)->len - iph->ihl * 4; udph->check = 0; @@ -253,6 +265,14 @@ ip_nat_mangle_udp_packet(struct sk_buff csum_partial((char *)udph, datalen, 0)); } +#ifdef CONFIG_XEN + } else if (rep_len != match_len && udph->check) { + int datalen = (*pskb)->len - iph->ihl * 4; + udph->check = + ip_nat_cheat_check(htons(datalen - rep_len + match_len), + htons(datalen) ^ 0xFFFF, udph->check); + } +#endif return 1; } @@ -293,6 +313,9 @@ sack_adjust(struct sk_buff *skb, ntohl(sack->start_seq), new_start_seq, ntohl(sack->end_seq), new_end_seq); +#ifdef CONFIG_XEN + if (!skb->proto_csum_blank) +#endif tcph->check = ip_nat_cheat_check(~sack->start_seq, new_start_seq, ip_nat_cheat_check(~sack->end_seq, @@ -381,6 +404,9 @@ ip_nat_seq_adjust(struct sk_buff **pskb, newack = ntohl(tcph->ack_seq) - other_way->offset_before; newack = htonl(newack); +#ifdef CONFIG_XEN + if (!(*pskb)->proto_csum_blank) +#endif tcph->check = ip_nat_cheat_check(~tcph->seq, newseq, ip_nat_cheat_check(~tcph->ack_seq, newack, diff -urp linux-2.6.18-cs1-xenU.orig/net/ipv4/netfilter/ipt_ECN.c linux-2.6.18-cs1-xenU/net/ipv4/netfilter/ipt_ECN.c --- linux-2.6.18-cs1-xenU.orig/net/ipv4/netfilter/ipt_ECN.c 2006-09-28 23:44:19.000000000 +0200 +++ linux-2.6.18-cs1-xenU/net/ipv4/netfilter/ipt_ECN.c 2006-09-28 23:39:46.000000000 +0200 @@ -82,6 +82,9 @@ set_ect_tcp(struct sk_buff **pskb, const diffs[1] = ((u_int16_t *)tcph)[6]; diffs[0] = diffs[0] ^ 0xFFFF; +#ifdef CONFIG_XEN + if (!(*pskb)->proto_csum_blank) +#endif if ((*pskb)->ip_summed != CHECKSUM_UNNECESSARY) tcph->check = csum_fold(csum_partial((char *)diffs, sizeof(diffs), diff -urp linux-2.6.18-cs1-xenU.orig/net/ipv4/netfilter/ipt_REJECT.c linux-2.6.18-cs1-xenU/net/ipv4/netfilter/ipt_REJECT.c --- linux-2.6.18-cs1-xenU.orig/net/ipv4/netfilter/ipt_REJECT.c 2006-09-28 23:44:19.000000000 +0200 +++ linux-2.6.18-cs1-xenU/net/ipv4/netfilter/ipt_REJECT.c 2006-09-28 23:39:46.000000000 +0200 @@ -183,6 +183,10 @@ static void send_reset(struct sk_buff *o tcph->window = 0; tcph->urg_ptr = 0; +#ifdef CONFIG_XEN + nskb->proto_csum_blank = 0; +#endif + /* Adjust TCP checksum */ tcph->check = 0; tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),