mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
- Merge aicom-network-fixes up to r38205
svn path=/trunk/; revision=38213
This commit is contained in:
parent
5c760c2d22
commit
ed4682a617
7 changed files with 75 additions and 124 deletions
|
@ -10,9 +10,6 @@
|
|||
|
||||
#include "precomp.h"
|
||||
|
||||
/* Define this to bugcheck on double complete */
|
||||
/* #define BREAK_ON_DOUBLE_COMPLETE */
|
||||
|
||||
UINT TransferDataCalled = 0;
|
||||
UINT TransferDataCompleteCalled = 0;
|
||||
UINT LanReceiveWorkerCalled = 0;
|
||||
|
@ -51,54 +48,6 @@ BOOLEAN ProtocolRegistered = FALSE;
|
|||
LIST_ENTRY AdapterListHead;
|
||||
KSPIN_LOCK AdapterListLock;
|
||||
|
||||
/* Double complete protection */
|
||||
KSPIN_LOCK LanSendCompleteLock;
|
||||
LIST_ENTRY LanSendCompleteList;
|
||||
|
||||
VOID LanChainCompletion( PLAN_ADAPTER Adapter, PNDIS_PACKET NdisPacket ) {
|
||||
PLAN_WQ_ITEM PendingCompletion =
|
||||
ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) );
|
||||
|
||||
if( !PendingCompletion ) return;
|
||||
|
||||
PendingCompletion->Packet = NdisPacket;
|
||||
PendingCompletion->Adapter = Adapter;
|
||||
|
||||
ExInterlockedInsertTailList( &LanSendCompleteList,
|
||||
&PendingCompletion->ListEntry,
|
||||
&LanSendCompleteLock );
|
||||
}
|
||||
|
||||
BOOLEAN LanShouldComplete( PLAN_ADAPTER Adapter, PNDIS_PACKET NdisPacket ) {
|
||||
PLIST_ENTRY ListEntry;
|
||||
PLAN_WQ_ITEM CompleteEntry;
|
||||
KIRQL OldIrql;
|
||||
|
||||
KeAcquireSpinLock( &LanSendCompleteLock, &OldIrql );
|
||||
for( ListEntry = LanSendCompleteList.Flink;
|
||||
ListEntry != &LanSendCompleteList;
|
||||
ListEntry = ListEntry->Flink ) {
|
||||
CompleteEntry = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
|
||||
|
||||
if( CompleteEntry->Adapter == Adapter &&
|
||||
CompleteEntry->Packet == NdisPacket ) {
|
||||
RemoveEntryList( ListEntry );
|
||||
KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
|
||||
ExFreePool( CompleteEntry );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
|
||||
|
||||
DbgPrint("NDIS completed the same send packet twice "
|
||||
"(Adapter %x Packet %x)!!\n", Adapter, NdisPacket);
|
||||
#ifdef BREAK_ON_DOUBLE_COMPLETE
|
||||
KeBugCheck(0);
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NDIS_STATUS NDISCall(
|
||||
PLAN_ADAPTER Adapter,
|
||||
NDIS_REQUEST_TYPE Type,
|
||||
|
@ -283,13 +232,11 @@ VOID NTAPI ProtocolSendComplete(
|
|||
*/
|
||||
{
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Calling completion routine\n"));
|
||||
if( LanShouldComplete( (PLAN_ADAPTER)BindingContext, Packet ) ) {
|
||||
ASSERT_KM_POINTER(Packet);
|
||||
ASSERT_KM_POINTER(PC(Packet));
|
||||
ASSERT_KM_POINTER(PC(Packet)->DLComplete);
|
||||
(*PC(Packet)->DLComplete)( PC(Packet)->Context, Packet, Status);
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Finished\n"));
|
||||
}
|
||||
ASSERT_KM_POINTER(Packet);
|
||||
ASSERT_KM_POINTER(PC(Packet));
|
||||
ASSERT_KM_POINTER(PC(Packet)->DLComplete);
|
||||
(*PC(Packet)->DLComplete)( PC(Packet)->Context, Packet, Status);
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Finished\n"));
|
||||
}
|
||||
|
||||
VOID LanReceiveWorker( PVOID Context ) {
|
||||
|
@ -646,8 +593,6 @@ VOID LANTransmit(
|
|||
* not needed immediately */
|
||||
GetDataPtr( NdisPacket, 0, &Data, &Size );
|
||||
|
||||
LanChainCompletion( Adapter, NdisPacket );
|
||||
|
||||
switch (Adapter->Media) {
|
||||
case NdisMedium802_3:
|
||||
EHeader = (PETH_HEADER)Data;
|
||||
|
@ -1046,6 +991,7 @@ BOOLEAN BindAdapter(
|
|||
|
||||
if (NdisStatus != NDIS_STATUS_SUCCESS) {
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Could not set packet filter (0x%X).\n", NdisStatus));
|
||||
IPUnregisterInterface(IF);
|
||||
IPDestroyInterface(IF);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1380,24 +1326,4 @@ VOID LANUnregisterProtocol(
|
|||
}
|
||||
}
|
||||
|
||||
VOID LANStartup() {
|
||||
InitializeListHead( &LanSendCompleteList );
|
||||
KeInitializeSpinLock( &LanSendCompleteLock );
|
||||
}
|
||||
|
||||
VOID LANShutdown() {
|
||||
KIRQL OldIrql;
|
||||
PLAN_WQ_ITEM WorkItem;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
KeAcquireSpinLock( &LanSendCompleteLock, &OldIrql );
|
||||
while( !IsListEmpty( &LanSendCompleteList ) ) {
|
||||
ListEntry = RemoveHeadList( &LanSendCompleteList );
|
||||
WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
|
||||
FreeNdisPacket( WorkItem->Packet );
|
||||
ExFreePool( WorkItem );
|
||||
}
|
||||
KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -585,9 +585,6 @@ VOID NTAPI TiUnload(
|
|||
/* Shutdown network level protocol subsystem */
|
||||
IPShutdown();
|
||||
|
||||
/* Shutdown the lan worker */
|
||||
LANShutdown();
|
||||
|
||||
/* Free NDIS buffer descriptors */
|
||||
if (GlobalBufferPool)
|
||||
NdisFreeBufferPool(GlobalBufferPool);
|
||||
|
@ -827,9 +824,6 @@ DriverEntry(
|
|||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize the lan worker */
|
||||
LANStartup();
|
||||
|
||||
/* Register protocol with NDIS */
|
||||
/* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
|
||||
Status = LANRegisterProtocol(&strNdisDeviceName);
|
||||
|
@ -843,7 +837,6 @@ DriverEntry(
|
|||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
LANShutdown();
|
||||
TCPShutdown();
|
||||
UDPShutdown();
|
||||
RawIPShutdown();
|
||||
|
@ -863,7 +856,6 @@ DriverEntry(
|
|||
Status = LoopRegisterAdapter(NULL, NULL);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
|
||||
LANShutdown();
|
||||
TCPShutdown();
|
||||
UDPShutdown();
|
||||
RawIPShutdown();
|
||||
|
|
|
@ -22,6 +22,7 @@ typedef struct _LAN_WQ_ITEM {
|
|||
KSPIN_LOCK LoopWorkLock;
|
||||
LIST_ENTRY LoopWorkList;
|
||||
WORK_QUEUE_ITEM LoopWorkItem;
|
||||
BOOLEAN LoopReceiveWorkerBusy = FALSE;
|
||||
|
||||
VOID NTAPI LoopReceiveWorker( PVOID Context ) {
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
@ -34,43 +35,46 @@ VOID NTAPI LoopReceiveWorker( PVOID Context ) {
|
|||
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
|
||||
|
||||
ListEntry = ExInterlockedRemoveHeadList( &LoopWorkList, &LoopWorkLock );
|
||||
WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
|
||||
while( (ListEntry =
|
||||
ExInterlockedRemoveHeadList( &LoopWorkList, &LoopWorkLock )) ) {
|
||||
WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
|
||||
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem));
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem));
|
||||
|
||||
Packet = WorkItem->Packet;
|
||||
Adapter = WorkItem->Adapter;
|
||||
BytesTransferred = WorkItem->BytesTransferred;
|
||||
Packet = WorkItem->Packet;
|
||||
Adapter = WorkItem->Adapter;
|
||||
BytesTransferred = WorkItem->BytesTransferred;
|
||||
|
||||
ExFreePool( WorkItem );
|
||||
ExFreePool( WorkItem );
|
||||
|
||||
IPPacket.NdisPacket = Packet;
|
||||
IPPacket.NdisPacket = Packet;
|
||||
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n",
|
||||
Packet, Adapter, BytesTransferred));
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n",
|
||||
Packet, Adapter, BytesTransferred));
|
||||
|
||||
NdisGetFirstBufferFromPacket(Packet,
|
||||
&NdisBuffer,
|
||||
&IPPacket.Header,
|
||||
&IPPacket.ContigSize,
|
||||
&IPPacket.TotalSize);
|
||||
NdisGetFirstBufferFromPacket(Packet,
|
||||
&NdisBuffer,
|
||||
&IPPacket.Header,
|
||||
&IPPacket.ContigSize,
|
||||
&IPPacket.TotalSize);
|
||||
|
||||
IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred;
|
||||
/* Determine which upper layer protocol that should receive
|
||||
this packet and pass it to the correct receive handler */
|
||||
IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred;
|
||||
/* Determine which upper layer protocol that should receive
|
||||
this packet and pass it to the correct receive handler */
|
||||
|
||||
TI_DbgPrint(MID_TRACE,
|
||||
("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n",
|
||||
IPPacket.ContigSize, IPPacket.TotalSize,
|
||||
BytesTransferred));
|
||||
TI_DbgPrint(MID_TRACE,
|
||||
("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n",
|
||||
IPPacket.ContigSize, IPPacket.TotalSize,
|
||||
BytesTransferred));
|
||||
|
||||
IPPacket.Position = 0;
|
||||
IPPacket.Position = 0;
|
||||
|
||||
IPReceive(Loopback, &IPPacket);
|
||||
IPReceive(Loopback, &IPPacket);
|
||||
|
||||
FreeNdisPacket( Packet );
|
||||
FreeNdisPacket( Packet );
|
||||
}
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Leaving\n"));
|
||||
LoopReceiveWorkerBusy = FALSE;
|
||||
}
|
||||
|
||||
VOID LoopSubmitReceiveWork(
|
||||
|
@ -80,19 +84,34 @@ VOID LoopSubmitReceiveWork(
|
|||
UINT BytesTransferred) {
|
||||
PLAN_WQ_ITEM WQItem;
|
||||
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
|
||||
KIRQL OldIrql;
|
||||
|
||||
TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql );
|
||||
|
||||
WQItem = ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) );
|
||||
if( !WQItem ) return;
|
||||
if( !WQItem ) {
|
||||
TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
|
||||
return;
|
||||
}
|
||||
|
||||
WQItem->Packet = Packet;
|
||||
WQItem->Adapter = Adapter;
|
||||
WQItem->BytesTransferred = BytesTransferred;
|
||||
ExInterlockedInsertTailList( &LoopWorkList, &WQItem->ListEntry, &LoopWorkLock );
|
||||
InsertTailList( &LoopWorkList, &WQItem->ListEntry );
|
||||
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x BytesTrans %x\n",
|
||||
Packet, Adapter, BytesTransferred));
|
||||
|
||||
ExQueueWorkItem( &LoopWorkItem, CriticalWorkQueue );
|
||||
if( !LoopReceiveWorkerBusy ) {
|
||||
LoopReceiveWorkerBusy = TRUE;
|
||||
ExQueueWorkItem( &LoopWorkItem, CriticalWorkQueue );
|
||||
TI_DbgPrint(DEBUG_DATALINK,
|
||||
("Work item inserted %x %x\n", &LoopWorkItem, WQItem));
|
||||
} else {
|
||||
TI_DbgPrint(DEBUG_DATALINK,
|
||||
("LOOP WORKER BUSY %x %x\n", &LoopWorkItem, WQItem));
|
||||
}
|
||||
TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
|
||||
}
|
||||
|
||||
VOID LoopTransmit(
|
||||
|
|
|
@ -216,7 +216,13 @@ NTSTATUS SendFragments(
|
|||
return NDIS_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
return IPSendFragment(IFC->NdisPacket, NCE, IFC);
|
||||
if (!NT_SUCCESS((NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC))))
|
||||
{
|
||||
FreeNdisPacket(IFC->NdisPacket);
|
||||
ExFreePool(IFC);
|
||||
}
|
||||
|
||||
return NdisStatus;
|
||||
}
|
||||
|
||||
NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE,
|
||||
|
|
|
@ -230,7 +230,11 @@ NTSTATUS RawIPSendDatagram(
|
|||
|
||||
TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
|
||||
|
||||
IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL );
|
||||
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL )))
|
||||
{
|
||||
FreeNdisPacket(Packet.NdisPacket);
|
||||
return Status;
|
||||
}
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("Leaving\n"));
|
||||
|
||||
|
|
|
@ -102,7 +102,11 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
|
|||
Packet.SrcAddr = LocalAddress;
|
||||
Packet.DstAddr = RemoteAddress;
|
||||
|
||||
IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL );
|
||||
if (!NT_SUCCESS(IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL )))
|
||||
{
|
||||
FreeNdisPacket(Packet.NdisPacket);
|
||||
return OSK_EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -47,8 +47,6 @@ NTSTATUS AddUDPHeaderIPv4(
|
|||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
/* Build UDP header */
|
||||
UDPHeader = (PUDP_HEADER)((ULONG_PTR)IPPacket->Data - sizeof(UDP_HEADER));
|
||||
/* Port values are already big-endian values */
|
||||
UDPHeader->SourcePort = LocalPort;
|
||||
UDPHeader->DestPort = RemotePort;
|
||||
|
@ -57,8 +55,6 @@ NTSTATUS AddUDPHeaderIPv4(
|
|||
/* Length of UDP header and data */
|
||||
UDPHeader->Length = WH2N(DataLength + sizeof(UDP_HEADER));
|
||||
|
||||
IPPacket->Data = ((PCHAR)UDPHeader) + sizeof(UDP_HEADER);
|
||||
|
||||
TI_DbgPrint(MID_TRACE, ("Packet: %d ip %d udp %d payload\n",
|
||||
(PCHAR)UDPHeader - (PCHAR)IPPacket->Header,
|
||||
(PCHAR)IPPacket->Data - (PCHAR)UDPHeader,
|
||||
|
@ -204,7 +200,11 @@ NTSTATUS UDPSendDatagram(
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL );
|
||||
if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL )))
|
||||
{
|
||||
FreeNdisPacket(Packet.NdisPacket);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue