I've got a problem with 802.11 bridging (the radios involved are using madwifi-ng in WDS mode, madwifi-ng checked out on November 6, committed-rev=1306).
[...]
ath_hal: 0.9.16.3 (AR5210, AR5211, AR5212, RF5111, RF5112, RF2413, RF5413, DFS)
wlan: 0.8.4.2 (Atheros/multi-bss)
ath_rate_sample: 1.2
ath_pci: 0.9.4.5 (Atheros/multi-bss)
wifi0: 11a rates: 6Mbps 9Mbps 12Mbps 18Mbps 24Mbps 36Mbps 48Mbps 54Mbps
wifi0: 11b rates: 1Mbps 2Mbps 5.5Mbps 11Mbps
wifi0: 11g rates: 1Mbps 2Mbps 5.5Mbps 11Mbps 6Mbps 9Mbps 12Mbps 18Mbps 24Mbps 36Mbps 48Mbps 54Mbps
wifi0: turboA rates: 6Mbps 9Mbps 12Mbps 18Mbps 24Mbps 36Mbps 48Mbps 54Mbps
wifi0: turboG rates: 6Mbps 12Mbps 18Mbps 24Mbps 36Mbps 48Mbps 54Mbps
wifi0: H/W encryption support: WEP AES AES_CCM TKIP
wifi0: mac 5.9 phy 4.3 radio 3.6
[...]
Basically the problem is that managed (i.e. client) radio interfaces that are part of a bridge (and thus, in promiscuous mode) see their sent packets twice (once when they send and again when the master radio rebroadcasts). In /var/log/messages I see examples of this:
ath0: received packet with own address as source address
and tcpdumps confirm seeing the packets twice. It appears that perhaps these packets are confusing the bridge about which MAC lives on which port and results in a failure to deliver packets in the correct direction. For example:
A B C D
bridge: bridge: bridge: host:
eth0 eth0 eth0 --------- eth1
ath0(cl) --- ath0(ma) --- ath0(cl)
Pings from D to A disappear in the ICMP reply direction after they get to C. They appear at C but never show up at D. Likewise, pings from A to D disappear in the ICMP request direction when they get to C, and never appear at D. I say never, but actually they do sometimes, about 2% of the time. Pings from D to B and vice versa are fine. Even pings from D to other hosts hanging off of B's eth0 are fine.
When the traffic is passing from the other side of the bridge (e.g from D to A), and C sees the rebroadcast packet it just sent with a SRC MAC on ath0, the bridge is reassigning that MAC to the bridge port associated with ath0, not eth0. When packets return headed for D's MAC, they get to the bridge and the bridge fails to deliver to the port where that MAC actually lives. Boom. This problem does not occur when communicating client-to-master (or master-to-client), because these packets are not rebroadcast. The problem doesn't occur when the communication is strictly client-to-client, because even though the client still sees the rebroadcast packet, the bridge is smart enough to know not to reassign a local MAC addresses to a different port.
To test this model, I ping flooded from D to C and at the same time pinged from D to A. During the ping flood (which presumably is reteaching the bridge at C where D's MAC address should go) ping lossage from D to A goes from the usual of 98% or more down to about 17% or so.
The problem is probably solved by teaching the bridge to drop the masters rebroadcast of the packet it just sent before it can confuse the bridge tables.