No packet in IOUserNetworkRxSubmissionQueue

I am writing a NetworkingDriverKit extension.

So I subclassed IOUserNetworkEthernet. In my class Start method, among hardware specific things here is what I do:

  • Allocate a IOUserNetworkPacketBufferPool, with IOUserNetworkPacketBufferPool::Create(this, "myPacketsPool", 5000, 5000, 10000, &ivars->PacketsPool);
  • Create an IODispatchQueue with IODispatchQueue::Create("myPacketsDispatchQueue", 0, 0, &ivars->PacketsDispatchQueue);
  • Create the IOUserNetworkPacketQueue objects:
IOUserNetworkRxSubmissionQueue::Create(ivars->PacketsPool, this, 250, 0, ivars->PacketsDispatchQueue, &ivars->RxSubmissionQueue);
IOUserNetworkRxCompletionQueue::Create(ivars->PacketsPool, this, 250, 0, ivars->PacketsDispatchQueue, &ivars->RxCompletionQueue);
IOUserNetworkTxSubmissionQueue::Create(ivars->PacketsPool, this, 250, 0, ivars->PacketsDispatchQueue, &ivars->TxSubmissionQueue);
IOUserNetworkTxCompletionQueue::Create(ivars->PacketsPool, this, 250, 0, ivars->PacketsDispatchQueue, &ivars->TxCompletionQueue);

queues[0] = ivars->RxSubmissionQueue;
queues[1] = ivars->RxCompletionQueue;
queues[2] = ivars->TxSubmissionQueue;
queues[3] = ivars->TxCompletionQueue;
  • I register the ethernet interface: RegisterEthernetInterface(mac, ivars->PacketsPool, queues, 4);
  • And I report link status with ReportLinkStatus(kIOUserNetworkLinkStatusActive, kIOUserNetworkMediaEthernet1000BaseT | kIOUserNetworkMediaOptionFullDuplex);

After that, the new network interface shows up in MacOS. I see that SetInterfaceEnable gets called with true as argument.

In the receive data path I get data from the USB device, which I want to pass to the network stack. So I try to get an empty packet with:

IOUserNetworkPacket * packet;
r = ivars->RxSubmissionQueue->DequeuePacket(&packet);

But at that point, I always get kIOReturnUnderrun.

Is there something else I should do to be able to dequeue empty packets from the IOUserNetworkRxSubmissionQueue ?

I already tried to enable the packets queues with:

ivars->RxSubmissionQueue->SetEnable(true);
ivars->RxCompletionQueue->SetEnable(true);
ivars->TxSubmissionQueue->SetEnable(true);
ivars->TxCompletionQueue->SetEnable(true);

But that doesn't change anything.

Replies

Try these suggestions and let me know if they solve your issue:

  1. IOUserNetworkPacketBufferPool::Create is deprecated. Please use IOUserNetworkPacketBufferPool::CreateWithOptions instead.
  2. You might opt to use CopyDispatchQueue instead of IODispatchQueue::Create, for example: CopyDispatchQueue("Default", &ivars->PacketsDispatchQueue);
  3. To confirm, are you calling RegisterService() after you call RegisterEthernetInterface(...)?
  4. kIOUserNetworkMediaOptionFullDuplex is not an IOUserNetworkMediaType. You shouldn't pass it to ReportLinkStatus or ReportAvailableMediaTypes.
  5. Both ReportLinkStatus and ReportAvailableMediaTypes are being deprecated. Please use reportLinkStatus and getSupportMediaArray respectively.
  6. Enable the queues in SetInterfaceEnable.