[NETFILTER]: Fix connection tracking bug in 2.6.12
authorPatrick McHardy <kaber@trash.net>
Tue, 28 Jun 2005 23:04:44 +0000 (16:04 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 28 Jun 2005 23:04:44 +0000 (16:04 -0700)
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: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/bridge/br_netfilter.c
net/ipv4/ip_output.c

index 03ae4edddac35bf6dbfa8773f9031279b9aa4dd1..2d52fee63a8cf1653e90281be1ca154c61f24d70 100644 (file)
@@ -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
                 * the BRNF_DONT_TAKE_PARENT mask. */
                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;
                }
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
index ee07aec215a060fa3b980d0c88d8158a9638404b..6ce5c3292f9f74021c1fb3b8bce32dea75ade96f 100644 (file)
@@ -188,7 +188,13 @@ static inline int ip_finish_output2(struct sk_buff *skb)
                skb = skb2;
        }
 
-       nf_reset(skb);
+#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);
 
        if (hh) {
                int hh_alen;