Re: conntrack doesn't always work when a bridge is used

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Patrick McHardy wrote:
Damien Thébault wrote:
On the router, I'm using this script :

ifconfig eth0 0.0.0.0 up
brctl addbr br0
brctl addif br0 eth0
ifconfig br0 192.168.1.70 up
ifconfig br0:0 192.168.2.70 up
iptables -t nat -A POSTROUTING -d 192.168.2.0/24 -j MASQUERADE
iptables -t nat -A PREROUTING -d 192.168.2.250 -j DNAT
--to-destination 192.168.2.50


Thanks. Its the DNAT rule thats causing this, the bridge netfilter code
calls dst_output directly for bridged dnated frames, causing these
hook invocations:

               PREROUTING
dst_output()    POSTROUTING
               FORWARD
               POSTROUTING


which is obviously broken. I'll see if I can come up with a fix for this.

It appears this has always been broken. Could you test this patch please?

The bridge code only calls dst_output to get a new destination MAC
address for the DNATed packet when the new destination is reachable
on the same bridge, so this patch simply hands the packet to the
neighbour output function without going through the IP stack.


diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index c1757c7..362fe89 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -285,12 +285,17 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
 	skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
 
 	skb->dev = bridge_parent(skb->dev);
-	if (!skb->dev)
-		kfree_skb(skb);
-	else {
+	if (skb->dev) {
+		struct dst_entry *dst = skb->dst;
+
 		nf_bridge_pull_encap_header(skb);
-		skb->dst->output(skb);
+
+		if (dst->hh)
+			return neigh_hh_output(dst->hh, skb);
+		else if (dst->neighbour)
+			return dst->neighbour->output(skb);
 	}
+	kfree_skb(skb);
 	return 0;
 }
 

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux