none
Send packet from TDI request with ndis send functions RRS feed

  • Question

  • In my ndis IM driver, I also filter TDI request by attach my device object to the TDI devices. When the TDI_CONNECT irp was sent to my filter device, I package a UDP packet, then use NdisSend to sent it directly. Then I pass the irp to next device by IoCallDriver. I run a packet capture program in another computer which connect to the same switch, then config the switch to mirro all packets to that computer.

    The result of packets capture indecates that both my UDP packet and TCP syn packets were transmitted to the wire successfully, but one thing is very strange. Sometimes, the TCP syn packets were transmitted before my UDP pakcet, the interval of syn and udp packet is about several us.

    In windows 7, I use ndis filter driver and WFP callout to do this, the problem is still exist, TCP hand shake packets is sent before my UDP packet.

    Why my packet is behand the tcp syn packets sometimes? How to avoid it?

    Wednesday, January 29, 2014 2:58 AM

Answers

  • It sounds like there's a race. This can happen in three ways:

    1. Each packet gets sent on a different processor.  It's nondeterministic which processor sends the packet first.
    2. The first packet is sent at a lower processor priority level (IRQL) than the second packet.  E.g., if you send a packet a PASSIVE_LEVEL, then immediately send a packet at DISPATCH_LEVEL, the second packet can overtake the first.
    3. The physical NIC has some deficiency where it reorders packets sometimes.

    We require NICs to generally preserve the order of packets, and there is a certification test that verifies a high percentage -- but not 100% -- of packets arrive in-order.  That means a lower-quality NIC driver may sometimes reorder packets, especially in edge cases around state transitions (power state changes, 802.11 mode changes, transitions out of USB selective suspend, etc).

    If you want certainty that the packets are going out in order, you have a couple options:

    • Send both packets yourself, at the same time, on the same processor, at DISPATCH_LEVEL.
    • Send one packet, wait for its completion, then send the second packet.
    Wednesday, January 29, 2014 3:42 AM

All replies

  • It sounds like there's a race. This can happen in three ways:

    1. Each packet gets sent on a different processor.  It's nondeterministic which processor sends the packet first.
    2. The first packet is sent at a lower processor priority level (IRQL) than the second packet.  E.g., if you send a packet a PASSIVE_LEVEL, then immediately send a packet at DISPATCH_LEVEL, the second packet can overtake the first.
    3. The physical NIC has some deficiency where it reorders packets sometimes.

    We require NICs to generally preserve the order of packets, and there is a certification test that verifies a high percentage -- but not 100% -- of packets arrive in-order.  That means a lower-quality NIC driver may sometimes reorder packets, especially in edge cases around state transitions (power state changes, 802.11 mode changes, transitions out of USB selective suspend, etc).

    If you want certainty that the packets are going out in order, you have a couple options:

    • Send both packets yourself, at the same time, on the same processor, at DISPATCH_LEVEL.
    • Send one packet, wait for its completion, then send the second packet.
    Wednesday, January 29, 2014 3:42 AM
  • Thank you very much.

    It seams like I shall modify a lot of my code. Pending the orignal IRP then send my packet, wait my packet complete then issue my IRP to take the place of the orignal one, at last, after my IRP completed, complete the original IRP. Can this work?


    • Edited by firtank Saturday, February 8, 2014 3:02 AM
    Saturday, February 8, 2014 2:33 AM