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