I'm trying to set up host-only networking between my Linux host (running Fedora 33) and a QEMU instance (a fork for Xilinx devices), more specifically between a bridge interface (host) and a tap interface (QEMU).
When trying to connect from the host TCP client to QEMU TCP server, the host seems to ignore the SYN/ACK packet from QEMU, or at least that's what I can gather from sniffing packets on the bridge interface.
Here's what I'm doing:
I'm creating a bridge interface
br0
, a tap interfacetap0
, connectingtap0
tobr0
, and assigning a static address192.168.2.210/24
to the bridge.ip link add name br0 type bridge ip tuntap add name tap0 mode tap ip link set tap0 master br0 ip link set br0 up ip link set tap0 up ip addr add 192.168.2.210/24 dev br0
I'm spinning up the QEMU guest with all the relevant arguments for my target platform, plus the argument to make QEMU attach to the tap interface I have created. The interface on the guest OS has a static IP as well, in the subnet of the host's address:
192.168.2.215/24
../qemu/build-v2020.1/arm-softmmu/qemu-system-arm \ -nic tap,ifname=tap0,script=no,downscript=no \ [PLATFORM_SPECIFIC_ARGUMENTS]
On the host, I'm launching a Python script to connect to an open TCP port on the guest.
import socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect(('192.168.2.215', 1275))
What happens: on the guest/TCP server, I can see the first SYN packet coming in, and the SYN/ACK packet going out. On the host/TCP client, sniffing on br0
, I can see the first SYN packet going out, and the SYN/ACK packet coming in, but it looks like that SYN/ACK packet is ignored, or does not reach the Python process (I've tried with a C++ program as well, same thing). The client is stuck in sock.connect()
, and a packet capture shows the client retransmitting SYN packets, as well as the server reacting to these retransmissions with more SYN/ACK packets.
No. Time Source Destination Protocol Length Info
1 0.000000000 fe80::e083:d7ff:fe6e:5ce2 ff02::16 ICMPv6 150 Multicast Listener Report Message v2
2 0.000024907 192.168.2.210 224.0.0.22 IGMPv3 54 Membership Report / Join group 224.0.0.252 for any sources
3 0.331992771 192.168.2.210 224.0.0.22 IGMPv3 54 Membership Report / Join group 224.0.0.252 for any sources
4 0.707989061 fe80::e083:d7ff:fe6e:5ce2 ff02::16 ICMPv6 150 Multicast Listener Report Message v2
5 5.960512301 e2:83:d7:6e:5c:e2 Broadcast ARP 42 Who has 192.168.2.215? Tell 192.168.2.210
6 5.967187240 02:00:00:00:00:01 e2:83:d7:6e:5c:e2 ARP 60 192.168.2.215 is at 02:00:00:00:00:01
7 5.967225848 192.168.2.210 192.168.2.215 TCP 74 59130 → 1275 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM=1 TSval=1376754999 TSecr=0 WS=128
8 6.002308149 192.168.2.215 192.168.2.210 TCP 66 1275 → 59130 [SYN, ACK] Seq=0 Ack=1 Win=7300 Len=0 MSS=1460 WS=1 SACK_PERM=1
9 6.980032443 192.168.2.210 192.168.2.215 TCP 74 [TCP Retransmission] 59130 → 1275 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM=1 TSval=1376756019 TSecr=0 WS=128
10 6.981422696 192.168.2.215 192.168.2.210 TCP 66 [TCP Retransmission] 1275 → 59130 [SYN, ACK] Seq=0 Ack=1 Win=7300 Len=0 MSS=1460 WS=1 SACK_PERM=1
11 9.027996685 192.168.2.210 192.168.2.215 TCP 74 [TCP Retransmission] 59130 → 1275 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM=1 TSval=1376758067 TSecr=0 WS=128
12 9.029198423 192.168.2.215 192.168.2.210 TCP 66 [TCP Retransmission] 1275 → 59130 [SYN, ACK] Seq=0 Ack=1 Win=7300 Len=0 MSS=1460 WS=1 SACK_PERM=1
Why is it that I see these SYN/ACK packets coming into br0
, but somehow not reaching the socket?
Some thoughts:
- I don't think it is a TCP checksum error: enabling checksum verification in Wireshark confirms that checksums of incoming packets is correct.
- I don't think it is a missing ARP table entry either: in the packet capture, I can see ARP request and reply as expected. Plus, looking into the sniffed packets, MAC-layer source and destination addresses of the SYN and SYN/ACK packets look correct.
- Can it be a firewall issue? I've tried
systemctl stop firewalld.service
, but I still get the same behaviour.
Details of my set-up:
- Host OS: Fedora 33
- Guest OS: bare-metal FreeRTOS with TCP stack
- QEMU fork for Xilinx devices (https://github.com/Xilinx/qemu)