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.