Andrew Morton wrote: > Obvious question: does it happen with 2.6.17.x or 2.6.18-rc5? > > > Begin forwarded message: > > Date: Tue, 29 Aug 2006 19:49:11 -0700 > From: [EMAIL PROTECTED] > To: [EMAIL PROTECTED] > Subject: [Bugme-new] [Bug 7074] New: Kernel Panic on kernel 2.6.16.1 > > > http://bugzilla.kernel.org/show_bug.cgi?id=7074 > > Summary: Kernel Panic on kernel 2.6.16.1 > Kernel Version: 2.6.16.1 > Status: NEW > Severity: high > Owner: [EMAIL PROTECTED] > Submitter: [EMAIL PROTECTED] > > > Most recent kernel where this bug did not occur: > Distribution: > Hardware Environment: P4 3.4G 1G Mem > Software Environment: FC3 Kernel 2.6.16.1 > Problem Description: > > kernel BUG at net/ipv4/netfilter/ip_conntrack_proto_tcp.c:911!
This can only happen if something corrupts the packet, probably within the bridge netfilter code. This patch from Stephen (rediffed against 2.6.16) fixes such a corruption, please try if it helps.
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h index de4d397..56ef3cb 100644 --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h @@ -66,15 +66,25 @@ #endif /* Only used in br_forward.c */ static inline -void nf_bridge_maybe_copy_header(struct sk_buff *skb) +int nf_bridge_maybe_copy_header(struct sk_buff *skb) { + int err; + if (skb->nf_bridge) { if (skb->protocol == __constant_htons(ETH_P_8021Q)) { + err = skb_cow(skb, 18); + if (err) + return err; memcpy(skb->data - 18, skb->nf_bridge->data, 18); skb_push(skb, 4); - } else + } else { + err = skb_cow(skb, 16); + if (err) + return err; memcpy(skb->data - 16, skb->nf_bridge->data, 16); + } } + return 0; } static inline diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 2d24fb4..dac7f06 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -37,11 +37,15 @@ int br_dev_queue_push_xmit(struct sk_buf else { #ifdef CONFIG_BRIDGE_NETFILTER /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */ - nf_bridge_maybe_copy_header(skb); + if (nf_bridge_maybe_copy_header(skb)) + kfree_skb(skb); + else #endif - skb_push(skb, ETH_HLEN); + { + skb_push(skb, ETH_HLEN); - dev_queue_xmit(skb); + dev_queue_xmit(skb); + } } return 0;