Re: 2.6.12: connection tracking broken?

Patrick McHardy
2005-06-21T15:18:32Z

[-- Attachment #1: Type: text/plain, Size: 999 bytes --]

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 <kaber@trash.net>

[-- Attachment #2: x --]
[-- Type: text/plain, Size: 448 bytes --]

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;

[-- Attachment #3: 10.diff --]
[-- Type: text/x-patch, Size: 573 bytes --]

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)