Commit 9666dae5 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[NETFILTER]: Fix connection tracking bug in 2.6.12

In 2.6.12 we started dropping the conntrack reference when a packet
leaves the IP layer. This broke connection tracking on a bridge,
because bridge-netfilter defers calling some NF_IP_* hooks to the bridge
layer for locally generated packets going out a bridge, where the
conntrack reference is no longer available. This patch keeps the
reference in this case as a temporary solution, long term we will
remove the defered hook calling. No attempt is made to drop the
reference in the bridge-code when it is no longer needed, tc actions
could already have sent the packet anywhere.
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bcd61272
...@@ -844,7 +844,7 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, ...@@ -844,7 +844,7 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb,
* doesn't use the bridge parent of the indev by using * doesn't use the bridge parent of the indev by using
* the BRNF_DONT_TAKE_PARENT mask. */ * the BRNF_DONT_TAKE_PARENT mask. */
if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) { if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) {
nf_bridge->mask &= BRNF_DONT_TAKE_PARENT; nf_bridge->mask |= BRNF_DONT_TAKE_PARENT;
nf_bridge->physindev = (struct net_device *)in; nf_bridge->physindev = (struct net_device *)in;
} }
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
......
...@@ -188,6 +188,12 @@ static inline int ip_finish_output2(struct sk_buff *skb) ...@@ -188,6 +188,12 @@ static inline int ip_finish_output2(struct sk_buff *skb)
skb = skb2; skb = skb2;
} }
#ifdef CONFIG_BRIDGE_NETFILTER
/* bridge-netfilter defers calling some IP hooks to the bridge layer
* and still needs the conntrack reference.
*/
if (skb->nf_bridge == NULL)
#endif
nf_reset(skb); nf_reset(skb);
if (hh) { if (hh) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment