Annulation des données réseau avec des anneaux réseau
Les pilotes clients NetAdapterCx annulent les données réseau lorsque l’infrastructure appelle leur fonction de rappel EvtPacketQueueCancel pour une file d’attente de paquets. Ce rappel est l’endroit où les pilotes clients effectuent tout traitement nécessaire avant que l’infrastructure supprime les files d’attente de paquets.
Dans votre fonction de rappel EvtPacketQueueCancel pour une file d’attente de transmission, vous avez la possibilité d’effectuer les paquets de transmission en attente. Contrairement à une file d’attente de réception, vous n’avez pas besoin de le faire. Si vous laissez des paquets en attente, NetAdapterCx appelle votre EvtPacketQueueAdvance pour la file d’attente de transmission, où vous les traitez dans le cadre de votre opération régulière.
Si votre matériel prend en charge l’annulation des transmissions en cours, vous devez également avancer l’itérateur de post-paquets de l’anneau net après tous les paquets annulés. Cela peut ressembler à l’exemple suivant :
void
MyEvtTxQueueCancel(
NETPACKETQUEUE TxQueue
)
{
// Get the transmit queue's context to retrieve the net ring collection
PMY_TX_QUEUE_CONTEXT txQueueContext = MyGetTxQueueContext(TxQueue);
NET_RING_COLLECTION const * ringCollection = txQueueContext->RingCollection;
NET_RING * packetRing = ringCollection->Rings[NET_RING_TYPE_PACKET];
UINT32 currentPacketIndex = packetRing->BeginIndex;
UINT32 packetEndIndex = packetRing->EndIndex;
while (currentPacketIndex != packetEndIndex)
{
// Mark this packet as canceled with the scratch field, then move past it
NET_PACKET * packet = NetRingGetPacketAtIndex(packetRing, currentPacketIndex);
packet->Scratch = 1;
currentPacketIndex = NetRingIncrementIndex(packetRing, currentPacketIndex);
}
packetRing->BeginIndex = packetRing->EndIndex;
}
Si votre matériel ne prend pas en charge l’annulation, ce rappel peut revenir sans action.
Dans votre fonction de rappel EvtPacketQueueCancel pour une file d’attente de réception, vous devez terminer les paquets de réception en attente. Si vous ne retournez pas tous les paquets, le système d’exploitation ne supprime pas la file d’attente et NetAdapterCx cesse d’appeler vos rappels pour la file d’attente.
Pour retourner des paquets, vous devez d’abord tenter d’indiquer les réceptions qui auraient pu être indiquées pendant la désactivation du chemin de réception, puis définir tous les paquets à ignorer et renvoyer tous les fragments au système d’exploitation. Cela peut ressembler à l’exemple de code suivant.
Notes
Cet exemple montre comment ne pas indiquer les réceptions. Pour obtenir un exemple de code de réception de données, consultez Réception de données réseau avec des anneaux réseau.
void
MyEvtRxQueueCancel(
NETPACKETQUEUE RxQueue
)
{
// Get the receive queue's context to retrieve the net ring collection
PMY_RX_QUEUE_CONTEXT rxQueueContext = MyGetRxQueueContext(RxQueue);
NET_RING_COLLECTION const * ringCollection = rxQueueContext->RingCollection;
NET_RING * packetRing = ringCollection->Rings[NET_RING_TYPE_PACKET];
NET_RING * fragmentRing = ringCollection->Rings[NET_RING_TYPE_FRAGMENT];
UINT32 currentPacketIndex = packetRing->BeginIndex;
UINT32 packetEndIndex = packetRing->EndIndex;
// Set hardware register for cancellation
...
//
// Indicate receives
...
//
// Get all packets and mark them for ignoring
currentPacketIndex = packetRing->BeginIndex;
while(currentPacketIndex != packetEndIndex)
{
NET_PACKET * packet = NetRingGetPacketAtIndex(packetRing, currentPacketIndex);
packet->Ignore = 1;
currentPacketIndex = NetRingIncrementIndex(packetRing, currentPacketIndex);
}
packetRing->BeginIndex = packetRing->EndIndex;
// Return all fragments to the OS
fragmentRing->BeginIndex = fragmentRing->EndIndex;
}