source IP address of broadcast packets gets rewritten when using NAT

Bug #1078305 reported by Pallinger Péter on 2012-11-13
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
libvirt (Fedora)
Fix Released
Undecided
libvirt (Ubuntu)
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.168.122.251.42141 > 255.255.255.255.5000: [bad udp cksum 476f!] UDP, length 2

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.168.122.1.42141 > 255.255.255.255.5000: [bad udp cksum 3b71!] UDP, length 2

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.168.122.251.46821 > 192.168.122.255.5000: [bad udp cksum aee5!] UDP, length 2

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.168.122.251.46821 > 192.168.122.255.5000: [bad udp cksum aee5!] UDP, length 2

Is this a configuration issue, or a more fundamental issue of the virtual switch itself?

Pallinger Péter (pp-publikus) wrote :

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.

Pallinger Péter (pp-publikus) wrote :

Actually, the PREROUTING lines are not needed in the above script, sorry.

Pallinger Péter (pp-publikus) wrote :

Ok, I srewed up the iptables rules a little, so this is a working workaround script:

IFACE=$(route -n | grep '^0.0.0.0 ' | sed 's/.* //g')
main_broadcast_addr=$(ip -4 addr show "$IFACE" | grep 'inet .* brd ' | sed 's/.* brd //;s/\([0-9.]*\).*/\1/')

iptables -t nat -A OUTPUT -d 255.255.255.255 -p tcp -j DNAT --to-destination $main_broadcast_addr
iptables -t nat -A OUTPUT -d 255.255.255.255 -p udp -j DNAT --to-destination $main_broadcast_addr

Paolo Bonzini (bonzini) wrote :

NAT networking is provided by libvirt, changing the package.

affects: qemu → libvirt (Ubuntu)
Changed in libvirt (Ubuntu):
importance: Undecided → Medium
Serge Hallyn (serge-hallyn) wrote :

Thanks for reporting this bug.

To be honest this seems to me like a kernel bug. Markign as affecting linux to get their opinion.

This bug is missing log files that will aid in diagnosing the problem. From a terminal window please run:

apport-collect 1078305

and then change the status of the bug to 'Confirmed'.

If, due to the nature of the issue you have encountered, you are unable to run this command, please add a comment stating that fact and change the bug status to 'Confirmed'.

This change has been made by an automated script, maintained by the Ubuntu Kernel Team.

Changed in linux (Ubuntu):
status: New → Incomplete
Serge Hallyn (serge-hallyn) wrote :

Does

sudo iptables -t nat -I POSTROUTING 1 -s 192.168.122.0/24 -d 255.255.255.255 -j RETURN

(suggested by apw) also work for you?

Pallinger Péter (pp-publikus) wrote :

About logs: sorry, I am running debian, so apport-collect is not available. I mistakenly believed that this is the official qemu bug tracker. :( Shall I send this bug to upstream (http://libvirt.org/bugs.html)?

Pallinger Péter (pp-publikus) wrote :

Serge: no, the POSTROUTING rule does not work for me (the recipient still seems to get the packet from 192.168.122.1), but the rules I proposed do work.

Serge Hallyn (serge-hallyn) wrote :

Ah, thanks, I see. Please see http://libvirt.org/bugs.html for the upstream bug tracker. When you open a bug there, please do link that bug here. Thanks again.

no longer affects: linux (Ubuntu)
Changed in libvirt (Ubuntu):
status: New → Confirmed
Pallinger Péter (pp-publikus) wrote :

The bug is already upstream, reported by someone else two days ago based on this launchpad bug report:
https://bugzilla.redhat.com/show_bug.cgi?id=876541

Changed in libvirt (Ubuntu):
status: Confirmed → Triaged
Changed in libvirt (Fedora):
importance: Unknown → Undecided
status: Unknown → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.