source IP address of broadcast packets gets rewritten when using NAT
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
libvirt (Fedora) |
Fix Released
|
Undecided
|
|||
libvirt (Ubuntu) |
Triaged
|
Medium
|
Unassigned |
Bug Description
If I send a broadcast message like this to the limited broadcast address:
echo a | nc -bu 255.255.255.255 5000
then the resulting packet looks like this on the sender side:
14:36:17.997662 02:00:c0:a8:7a:fb (oui Unknown) > Broadcast, ethertype IPv4 (0x0800), length 44: (tos 0x0, ttl 64, id 25278, offset 0, flags [DF], proto UDP (17), length 30)
192.
However, an other VM on the same host sees the following packet:
14:36:19.247793 02:00:c0:a8:7a:fb (oui Unknown) > Broadcast, ethertype IPv4 (0x0800), length 44: (tos 0x0, ttl 64, id 25278, offset 0, flags [DF], proto UDP (17), length 30)
192.
So the source MAC address and other headers are untouched, but the source IP address is changed to the default gateway's!
If I use a the subnet-specific broadcast, then the packets are left untouched, i.e.:
echo a | nc -bu 192.168.122.255 5000
14:41:33.313490 02:00:c0:a8:7a:fb (oui Unknown) > Broadcast, ethertype IPv4 (0x0800), length 44: (tos 0x0, ttl 64, id 38571, offset 0, flags [DF], proto UDP (17), length 30)
192.
14:41:34.563615 02:00:c0:a8:7a:fb (oui Unknown) > Broadcast, ethertype IPv4 (0x0800), length 44: (tos 0x0, ttl 64, id 38571, offset 0, flags [DF], proto UDP (17), length 30)
192.
Is this a configuration issue, or a more fundamental issue of the virtual switch itself?
Changed in libvirt (Ubuntu): | |
importance: | Undecided → Medium |
Changed in libvirt (Ubuntu): | |
status: | Confirmed → Triaged |
Changed in libvirt (Fedora): | |
importance: | Unknown → Undecided |
status: | Unknown → Fix Released |
A possible workaround is:
local_bcast_ addr=192. 168.122. 255 # here you should rather detect this than specify it
iptables -A PREROUTING -d 255.255.255.255 -p udp -j DNAT --to-destination $local_bcast_addr
iptables -A PREROUTING -d 255.255.255.255 -p tcp -j DNAT --to-destination $local_bcast_addr
iptables -A OUTPUT -d 255.255.255.255 -p tcp -j DNAT --to-destination $local_bcast_addr
iptables -A OUTPUT -d 255.255.255.255 -p udp -j DNAT --to-destination $local_bcast_addr
Not very elegant, and may not work for some cases, but works for tinc's LocalDiscovery, which relies on UDP broadcast.