NdisMIndicateReceive platform differences

Hi,

I have an NDIS IM driver working smoothly on WXP and now I’m testing on W2K.
Found a couple minor issues to get me rolling, but now I have a problem on
W2K that I don’t have on WXP with the same code block (see below). So, this
code is running in the context of a system thread that my IM driver has
established.

I’m attempting to indicate a packet received previously where I

  1. extracted the data from a miniport driver’s up call,
  2. cached the data in my own allocated buffer
  3. then performed some processing on the data on my system thread.

This is a VPN-like product, so the original packet came in on a physical
miniport interface, but I want it to look like it came from a virtual
miniport interface to the protocol stack above.

So, when I step into the NDIS code to see what I can see, it appears that
NDIS thinks I’m trying to indicate a packet I don’t own. (I can see it
sending a DbgPrint message to that effect.)

Any insight is appreciated.

// allocate a packet
NdisAllocatePacket(&Status,
&pPacket,
pAdapt->SendPacketPoolHandle);
if (NDIS_STATUS_SUCCESS != Status)
{
// handle the error and get out
…snip
}

// Allocate a buffer descriptor
NdisAllocateBuffer(&Status,
&pNewNdisBfr,
pAdapt->hRecvBufferPool,
pNewPayload,
ulNewPayloadSize);
if (NDIS_STATUS_SUCCESS!=Status)
{
// handle the error and get out
…snip
}

// Show new NDIS_BUFFER used.
RecvRsvd = (PRECV_RSVD) (pPacket->MiniportReserved);
RecvRsvd->bNewBuffer = TRUE;
RecvRsvd->bInjectedPacket = FALSE;

// Chain new buffer descriptor to new packet.
NdisChainBufferAtFront(pPacket,
pNewNdisBfr);

// Set the header size
NDIS_SET_PACKET_HEADER_SIZE(pPacket, sizeof(ETHHDR));

// Set the packet status so that the upper layer protocol
will // copy the buffer immediately
NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_RESOURCES);

// indicate the packet to the upper level protocol
NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &pPacket,
1);


Paul Benware

KoolSpan Inc.
www.koolspan.com

Paul,

Shouldn’t you be using the receive rather than the send packet pool
to get a packet to be used for the indication to protocols? An error
you seem to be be getting sounds consistent with using the wrong
pool. I would also clear the OOB data in the packet if you don’t use
it, but this is 2005 so I would at least support VLANs/QoS. I assume
the MAC header for your virtual interface is built correctly. Looks Ok
to me otherwise.

Finally, a personal recommendation from my experience with multiple
NDIS intermediate drivers now in production, including those having
a worker thread: it might be a good idea to pre-allocate buffers at
startup as the NDIS buffer allocation start failing when a system is
under stress.

Hope it helps,

Ilya Faenson
Rockville, MD USA

-----Original Message-----
Subject: NdisMIndicateReceive platform differences
From: “Paul Benware”
Date: Wed, 5 Jan 2005 15:41:30 -0500
X-Message-Number: 32

Hi,

I have an NDIS IM driver working smoothly on WXP and now I’m testing on W2K.
Found a couple minor issues to get me rolling, but now I have a problem on
W2K that I don’t have on WXP with the same code block (see below). So, this
code is running in the context of a system thread that my IM driver has
established.

I’m attempting to indicate a packet received previously where I
1) extracted the data from a miniport driver’s up call,
2) cached the data in my own allocated buffer
3) then performed some processing on the data on my system thread.

This is a VPN-like product, so the original packet came in on a physical
miniport interface, but I want it to look like it came from a virtual
miniport interface to the protocol stack above.

So, when I step into the NDIS code to see what I can see, it appears that
NDIS thinks I’m trying to indicate a packet I don’t own. (I can see it
sending a DbgPrint message to that effect.)

Any insight is appreciated.

// allocate a packet
NdisAllocatePacket(&Status,
&pPacket,
pAdapt->SendPacketPoolHandle);
if (NDIS_STATUS_SUCCESS != Status)
{
// handle the error and get out
…snip
}

// Allocate a buffer descriptor
NdisAllocateBuffer(&Status,
&pNewNdisBfr,
pAdapt->hRecvBufferPool,
pNewPayload,
ulNewPayloadSize);
if (NDIS_STATUS_SUCCESS!=Status)
{
// handle the error and get out
…snip
}

// Show new NDIS_BUFFER used.
RecvRsvd = (PRECV_RSVD) (pPacket->MiniportReserved);
RecvRsvd->bNewBuffer = TRUE;
RecvRsvd->bInjectedPacket = FALSE;

// Chain new buffer descriptor to new packet.
NdisChainBufferAtFront(pPacket,
pNewNdisBfr);

// Set the header size
NDIS_SET_PACKET_HEADER_SIZE(pPacket, sizeof(ETHHDR));

// Set the packet status so that the upper layer protocol
will // copy the buffer immediately
NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_RESOURCES);

// indicate the packet to the upper level protocol
NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &pPacket,
1);