[NETFILTER]: bridge: fix double POST_ROUTING invocation

The bridge code incorrectly causes two POST_ROUTING hook invocations
for DNATed packets that end up on the same bridge device. This
happens because packets with a changed destination address are passed
to dst_output() to make them go through the neighbour output function
again to build a new destination MAC address, before they will continue
through the IP hooks simulated by bridge netfilter.

The resulting hook order is:
PREROUTING (bridge netfilter)
POSTROUTING (dst_output -> ip_output)
FORWARD (bridge netfilter)
POSTROUTING (bridge netfilter)

The deferred hooks used to abort the first POST_ROUTING invocation,
but since the only thing bridge netfilter actually really wants is
a new MAC address, we can avoid going through the IP stack completely
by simply calling the neighbour output function directly.

Tested, reported and lots of data provided by: Damien Thebault <damien.thebault@gmail.com>

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Patrick McHardy and committed by David S. Miller 2948d2eb 0ff4d77b

+12 -6
+12 -6
net/bridge/br_netfilter.c
··· 247 247 * Let us first consider the case that ip_route_input() succeeds: 248 248 * 249 249 * If skb->dst->dev equals the logical bridge device the packet 250 - * came in on, we can consider this bridging. We then call 251 - * skb->dst->output() which will make the packet enter br_nf_local_out() 250 + * came in on, we can consider this bridging. The packet is passed 251 + * through the neighbour output function to build a new destination 252 + * MAC address, which will make the packet enter br_nf_local_out() 252 253 * not much later. In that function it is assured that the iptables 253 254 * FORWARD chain is traversed for the packet. 254 255 * ··· 286 285 skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; 287 286 288 287 skb->dev = bridge_parent(skb->dev); 289 - if (!skb->dev) 290 - kfree_skb(skb); 291 - else { 288 + if (skb->dev) { 289 + struct dst_entry *dst = skb->dst; 290 + 292 291 nf_bridge_pull_encap_header(skb); 293 - skb->dst->output(skb); 292 + 293 + if (dst->hh) 294 + return neigh_hh_output(dst->hh, skb); 295 + else if (dst->neighbour) 296 + return dst->neighbour->output(skb); 294 297 } 298 + kfree_skb(skb); 295 299 return 0; 296 300 } 297 301