Virtio-net device not receiving packets in VirtualBox

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
coderTrevor
Posts: 10
Joined: Fri Mar 22, 2019 12:34 pm

Virtio-net device not receiving packets in VirtualBox

Post by coderTrevor »

Hello OSDev forums!

Lately I've been trying to implement a driver for the virtio-net paravirtual device. I've gotten this working well in Qemu but I'm still having some trouble getting it to work in VirtualBox.

Thanks to this thread I was able to make VirtualBox actually transmit my packet (thanks SpyderTL!), but I'm still unable to receive any responses. I've tried sending a DHCP discover packet and an ARP request.

I've managed to get capture files of the traffic by following these instructions, and Wireshark does show that responses are going to the VM, but my driver never sees them. I've tried just about everything and I'm running out of ideas.
Wireshark Capture.png
In VBox, I never receive an interrupt for received packets. Also, I've added a command to my shell that dumps out some info about the receive queue, so I know that the used index is never being incremented. It also inspects all of the 16 receive buffers I make available to the receive queue, and they all stay empty. I also notice that the device area (the used ring) of the receive queue has the VIRTQ_USED_F_NO_NOTIFY flag set by the device, so I think I'm setting up the virtqueues correctly in memory. Also, like I said, it works OK in Qemu and all the same memory addresses are being used in both environments.
Screenshot.png
This behavior is with the Windows build of VirtualBox. I also tried using VirtualBox in Linux (running in another VM) and had the same results.

I'm pretty much running out of things to try. The only other thing I can think is to build and debug Virtualbox myself but I have every indication that just building it is far from trivial.

I'd really appreciate it if anyone could share some ideas as to where I'm going wrong!

My code is here and the relevant parts are this header and source file. The driver starts with VirtIO_Net_Init().

Thanks in advance! :)
coderTrevor
Posts: 10
Joined: Fri Mar 22, 2019 12:34 pm

Re: Virtio-net device not receiving packets in VirtualBox

Post by coderTrevor »

Update: I managed to find the problem and fix it. :)

After spending about a week in dependency hell, I was finally able to build a debug version of VirtualBox. After another few hours of dealing with their over-engineered logging system, I was able to get the output I needed. After another five minutes, I had my answer.

I was surprised to find that this is a bug with VirtualBox. The easiest way of working around VirtualBox's buggy device implementation is to negotiate and implement the VIRTIO_NET_F_MRG_RXBUF feature. I imagine all the drivers that have been thrown at VirtualBox prior to mine have implemented this feature.

As soon as I have the time I'll post some more details. I'll also create a pull-request to have this fixed and update the wiki with what I've learned.
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: Virtio-net device not receiving packets in VirtualBox

Post by SpyderTL »

Glad I could help! :)

I'm surprised that this is not working for you in VBox, as my code seemed to work fine the last time I tested it, but that was probably 2+ years ago. It may have been broken since then.

I'll put it on my list of todo's to test it out again and see if I run into any issues.

The only real issue I ran into back then was figuring out that reading packets was a bit more complicated than sending them, because receiving data required both readable segments and writable segments. Sending packets only involves read-only data (from the host side). A buffer can be read-only or write-only, but not both.

So the only way I could get sending packets to work was to break up a single network packet into multiple buffers, where the first segment was read-only, the next segment was write-only, the next segment was read-only, and so on.

If you are already doing this, then it probably is just broken in the current version. But I am curious to hear what you found and how you fixed it.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Post Reply