Re: 2.6.9 NAT problem

From: Martin Josefsson
Date: Wed Dec 15 2004 - 01:54:33 EST


On Tue, 2004-12-14 at 22:26, Giuliano Pochini wrote:

> > 2.6.9 contains a large update to the connectiontracking code. One thing
> > that was changed is that it now verifies the checksum of tcp and udp
> > packets. I know of at least one user who has been bitten by this and what
> > looks like a broken sungem NIC.
> >
> > Could you please try this:
> >
> > modprobe ipt_LOG
> > echo 255 > /proc/sys/net/ipv4/netfilter/ip_conntrack_log_invalid
> >
> > Then try again and then check the kernellog by executing 'dmesg', see if
> > it complains about bad checksums.
>
> Yes :(

:( It seems there are silicon revisions of the apple sungem that produce
broken checksums. This is what we were worried about, we'll probably
submit a patch soon that removes the checksum checking, then it'll
behave more like < 2.6.9-pre1

In the meantime you can use the patch below that simply comments that
code out. It's not diffed against 2.6.9 but should apply anyway.

Would be great if you could report a 'Yay' or 'Nay' on your success with
this patch.

--- linux-2.6.10-rc1-ck1/net/ipv4/netfilter/ip_conntrack_proto_tcp.c.orig 2004-12-15 07:46:30.000000000 +0100
+++ linux-2.6.10-rc1-ck1/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2004-12-15 07:47:34.000000000 +0100
@@ -800,7 +800,7 @@ static int tcp_error(struct sk_buff *skb
* and moreover root might send raw packets.
*/
/* FIXME: Source route IP option packets --RR */
- if (hooknum == NF_IP_PRE_ROUTING
+/* if (hooknum == NF_IP_PRE_ROUTING
&& csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP,
skb->ip_summed == CHECKSUM_HW ? skb->csum
: skb_checksum(skb, iph->ihl*4, tcplen, 0))) {
@@ -808,7 +808,7 @@ static int tcp_error(struct sk_buff *skb
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_tcp: bad TCP checksum ");
return -NF_ACCEPT;
- }
+ } */

/* Check TCP flags. */
tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR));
--- linux-2.6.10-rc1-ck1/net/ipv4/netfilter/ip_conntrack_proto_udp.c.orig 2004-12-15 07:46:37.000000000 +0100
+++ linux-2.6.10-rc1-ck1/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2004-12-15 07:47:59.000000000 +0100
@@ -119,7 +119,7 @@ static int udp_error(struct sk_buff *skb
* because the semantic of CHECKSUM_HW is different there
* and moreover root might send raw packets.
* FIXME: Source route IP option packets --RR */
- if (hooknum == NF_IP_PRE_ROUTING
+/* if (hooknum == NF_IP_PRE_ROUTING
&& csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP,
skb->ip_summed == CHECKSUM_HW ? skb->csum
: skb_checksum(skb, iph->ihl*4, udplen, 0))) {
@@ -127,7 +127,7 @@ static int udp_error(struct sk_buff *skb
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_udp: bad UDP checksum ");
return -NF_ACCEPT;
- }
+ } */

return NF_ACCEPT;
}
--- linux-2.6.10-rc1-ck1/net/ipv4/netfilter/ip_conntrack_proto_icmp.c.orig 2004-12-15 07:46:43.000000000 +0100
+++ linux-2.6.10-rc1-ck1/net/ipv4/netfilter/ip_conntrack_proto_icmp.c 2004-12-15 07:48:57.000000000 +0100
@@ -218,7 +218,7 @@ icmp_error(struct sk_buff *skb, enum ip_
}

/* See ip_conntrack_proto_tcp.c */
- if (hooknum != NF_IP_PRE_ROUTING)
+/* if (hooknum != NF_IP_PRE_ROUTING)
goto checksum_skipped;

switch (skb->ip_summed) {
@@ -238,7 +238,7 @@ icmp_error(struct sk_buff *skb, enum ip_
}
default:
break;
- }
+ } */

checksum_skipped:
/*

--
/Martin

Attachment: signature.asc
Description: This is a digitally signed message part