https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=165059

Timo Voelker <timo.voel...@fh-muenster.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timo.voel...@fh-muenster.de

--- Comment #45 from Timo Voelker <timo.voel...@fh-muenster.de> ---
As Michael wrote, my focus is more on bhyve. However, I have a setup with KVM
and qemu to compare behavior.

This is my current setup:

FreeBSD VM1    FreeBSD VM2 (router)
  vtnet0       vtnet0      vtnet1
1.1.1.1/24   1.1.1.2/24  2.2.2.2/24
     *          *           *
      \        /            |
       \      /             |
        \    /              |
Linux    *  *               *
Host    bridge0           bridge1
                         2.2.2.3/24

Ping from VM1 (1.1.1.1) to host's bridge1 (2.2.2.3) works, TCP does not. This
is my understanding of what happens, when VM1 sends a TCP segment to Host's
bridge1.

1. VM1 TCP/IP Stack: Outgoing interface vtnet0 has txcsum -> do not calculate
correct TCP checksum, set flag CSUM_IP_TCP and send with incorrect checksum
value.
2. VM1 vtnet0: Outgoing packet still needs a correct checksum (CSUM_IP_TCP set)
-> set virtio-net header flag VIRTIO_NET_HDR_F_NEEDS_CSUM.
3. VM2 vtnet0: Incoming packet has VIRTIO_NET_HDR_F_NEEDS_CSUM set -> packet is
likely from another VM on the same host -> trust the packet and set flag
CSUM_DATA_VALID (basically lie that the checksum has been validated).
4. VM2 TCP/IP Stack: Forward packet out over vtnet1. This is on IP layer, no
need to touch the TCP checksum.
5. VM2 vtnet1: Outgoing packet seems to have a correct checksum. No need to set
virtio-net header flag VIRTIO_NET_HDR_F_NEEDS_CSUM.
6. Host bridge1: Incoming packet without virtio-net header flag
VIRTIO_NET_HDR_F_NEEDS_CSUM set -> pass packet without setting CSUM flags.
7. Host TCP/IP: Incoming TCP segment with incorrect checksum. Drop segment.

The problem is the lie at point 3. That's works if the packet is for VM2, but
breaks in this case where VM2 only forwards the IP packet. Right now, I don't
have a good idea for a fix, but I'm working on it.

By the way, the behavior at point 3 is configurable. With
`hw.vtnet.fixup_needs_csum=1` set in /boot/loader.conf (and after a restart),
VM2 vtnet0 calculates the checksum and write the correct checksum into the TCP
header. With that, TCP from VM1 to host's bridge1 works, but this is not better
than disabling txcsum on VM1 vtnet0 because the checksum calculation is still
done in software, only on another VM.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
You are the assignee for the bug.

Reply via email to