Re: 2.6.12: connection tracking broken?

Patrick McHardy <[email protected]>
Newsgroups gmane.comp.security.firewalls.netfilter.devel,gmane.linux.kernel,gmane.linux.network.bridge.ebtables.devel
Message-ID <[email protected]>
Bart De Schuymer wrote:
> Deferring the hooks makes the bridge-nf code alot more complicated, so I
> would be glad to get rid of it if it is the right thing to do. But
> backwards compatibility can't be maintained and I'd be surprised if
> every ruleset that now works will still be possible using an
> iptables/ebtables scheme.

I unfortunately don't see a way to remove it, but we should keep
thinking about it. Can you please check if the attached patch is
correct? It should exclude all packets handled by bridge-netfilter
from having their conntrack reference dropped. I didn't add nf_reset()'s
to the bridging code because with tc actions the packets can end up
anywhere else anyway, and this will hopefully get fixed right sometime.

BTW. this line from ip_sabotage_out() looks wrong, it will clear all
flags instead of setting the BRNF_DONT_TAKE_PARENT flag (second
patch):

                        nf_bridge->mask &= BRNF_DONT_TAKE_PARENT;

Signed-off-by: Patrick McHardy <[email protected]>
x (text/plain, 448 B)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -188,7 +188,12 @@ static inline int ip_finish_output2(stru
 		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;
10.diff (text/x-patch, 573 B)
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -882,7 +882,7 @@ static unsigned int ip_sabotage_out(unsi
 		 * 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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.