From 9ccce3d818e556a6320432f3b0921606c538e40f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 19 Sep 2009 01:39:16 +0000 Subject: [PATCH] - Changed some behavior from the last neighbor cache rewrite - NCEs are no longer destroyed when they become stale so the hardware address can be saved for direct communication - The route selection code has been changed to choose against stale NCEs if possible svn path=/trunk/; revision=43077 --- .../drivers/network/tcpip/include/neighbor.h | 7 ++--- reactos/lib/drivers/ip/network/arp.c | 4 +-- reactos/lib/drivers/ip/network/ip.c | 2 +- reactos/lib/drivers/ip/network/neighbor.c | 30 ++++++++----------- reactos/lib/drivers/ip/network/router.c | 3 +- 5 files changed, 20 insertions(+), 26 deletions(-) diff --git a/reactos/drivers/network/tcpip/include/neighbor.h b/reactos/drivers/network/tcpip/include/neighbor.h index 7eb0e8f2dfe..f1a43b247e1 100644 --- a/reactos/drivers/network/tcpip/include/neighbor.h +++ b/reactos/drivers/network/tcpip/include/neighbor.h @@ -41,11 +41,8 @@ typedef struct NEIGHBOR_CACHE_ENTRY { /* NCE states */ #define NUD_INCOMPLETE 0x01 -#define NUD_REACHABLE 0x02 -#define NUD_PERMANENT 0x04 - -#define NUD_BROADCAST (NUD_PERMANENT | NUD_REACHABLE) -#define NUD_LOCAL (NUD_PERMANENT | NUD_REACHABLE) +#define NUD_PERMANENT 0x02 +#define NUD_STALE 0x04 /* Number of seconds before the NCE times out */ #define ARP_TIMEOUT 30 diff --git a/reactos/lib/drivers/ip/network/arp.c b/reactos/lib/drivers/ip/network/arp.c index e9c0367464d..0a8a460617e 100644 --- a/reactos/lib/drivers/ip/network/arp.c +++ b/reactos/lib/drivers/ip/network/arp.c @@ -215,13 +215,13 @@ VOID ARPReceive( if (NCE) { /* We know the sender. Update the hardware address and state in our neighbor address cache */ - NBUpdateNeighbor(NCE, SenderHWAddress, NUD_REACHABLE); + NBUpdateNeighbor(NCE, SenderHWAddress, 0); } else { /* The packet had our protocol address as target. The sender may want to communicate with us soon, so add his address to our address cache */ NCE = NBAddNeighbor(Interface, &Address, SenderHWAddress, - Header->HWAddrLen, NUD_REACHABLE, ARP_TIMEOUT); + Header->HWAddrLen, 0, ARP_TIMEOUT); } if (Header->Opcode != ARP_OPCODE_REQUEST) diff --git a/reactos/lib/drivers/ip/network/ip.c b/reactos/lib/drivers/ip/network/ip.c index e2f75035efc..fa9511a617d 100644 --- a/reactos/lib/drivers/ip/network/ip.c +++ b/reactos/lib/drivers/ip/network/ip.c @@ -212,7 +212,7 @@ VOID IPAddInterfaceRoute( PIP_INTERFACE IF ) { /* Add a permanent neighbor for this NTE */ NCE = NBAddNeighbor(IF, &IF->Unicast, IF->Address, IF->AddressLength, - NUD_LOCAL, 0); + NUD_PERMANENT, 0); if (!NCE) { TI_DbgPrint(MIN_TRACE, ("Could not create NCE.\n")); return; diff --git a/reactos/lib/drivers/ip/network/neighbor.c b/reactos/lib/drivers/ip/network/neighbor.c index 6bc7e2f583e..87171b95edc 100644 --- a/reactos/lib/drivers/ip/network/neighbor.c +++ b/reactos/lib/drivers/ip/network/neighbor.c @@ -30,7 +30,7 @@ VOID NBSendPackets( PNEIGHBOR_CACHE_ENTRY NCE ) { PNEIGHBOR_PACKET Packet; UINT HashValue; - ASSERT(NCE->State & NUD_REACHABLE); + ASSERT(!(NCE->State & NUD_INCOMPLETE)); HashValue = *(PULONG)(&NCE->Address.Address); HashValue ^= HashValue >> 16; @@ -105,26 +105,22 @@ VOID NBTimeout(VOID) TcpipAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql); for (PrevNCE = &NeighborCache[i].Cache; - (NCE = *PrevNCE) != NULL;) { + (NCE = *PrevNCE) != NULL; + PrevNCE = &NCE->Next) { /* Check if event timer is running */ if (NCE->EventTimer > 0) { + ASSERT(!(NCE->State & NUD_PERMANENT)); NCE->EventCount++; if (NCE->EventCount % ARP_RATE == 0) NBSendSolicit(NCE); if (NCE->EventTimer - NCE->EventCount == 0) { - ASSERT(!(NCE->State & NUD_PERMANENT)); + DbgPrint("Marking NCE stale: %s\n", A2S(&NCE->Address)); - /* Flush packet queue */ - NBFlushPacketQueue( NCE, NDIS_STATUS_REQUEST_ABORTED ); + NCE->State |= NUD_STALE; - *PrevNCE = NCE->Next; - - exFreePool(NCE); - - continue; + NCE->EventCount = 0; } } - PrevNCE = &NCE->Next; } TcpipReleaseSpinLock(&NeighborCache[i].Lock, OldIrql); @@ -304,7 +300,7 @@ VOID NBUpdateNeighbor( TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql); - if( NCE->State & NUD_REACHABLE ) + if( !(NCE->State & NUD_INCOMPLETE) ) NBSendPackets( NCE ); } @@ -376,7 +372,7 @@ PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor( AddrIsUnspecified(Address) ) { TI_DbgPrint(MID_TRACE,("Packet targeted at broadcast addr\n")); NCE = NBAddNeighbor(Interface, Address, NULL, - Interface->AddressLength, NUD_BROADCAST, 0); + Interface->AddressLength, NUD_PERMANENT, 0); } else { NCE = NBAddNeighbor(Interface, Address, NULL, Interface->AddressLength, NUD_INCOMPLETE, ARP_TIMEOUT); @@ -430,7 +426,7 @@ BOOLEAN NBQueuePacket( TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql); - if( NCE->State & NUD_REACHABLE ) + if( !(NCE->State & NUD_INCOMPLETE) ) NBSendPackets( NCE ); return TRUE; @@ -505,10 +501,10 @@ ULONG NBCopyNeighbors ArpTable[Size].LogAddr = CurNCE->Address.Address.IPv4Address; if( CurNCE->State & NUD_PERMANENT ) ArpTable[Size].Type = ARP_ENTRY_STATIC; - else if( CurNCE->State & NUD_REACHABLE ) - ArpTable[Size].Type = ARP_ENTRY_DYNAMIC; + else if( CurNCE->State & NUD_INCOMPLETE ) + ArpTable[Size].Type = ARP_ENTRY_INVALID; else - ArpTable[Size].Type = ARP_ENTRY_OTHER; + ArpTable[Size].Type = ARP_ENTRY_DYNAMIC; } Size++; } diff --git a/reactos/lib/drivers/ip/network/router.c b/reactos/lib/drivers/ip/network/router.c index d0c217a4728..a44d9e387b6 100644 --- a/reactos/lib/drivers/ip/network/router.c +++ b/reactos/lib/drivers/ip/network/router.c @@ -274,7 +274,8 @@ PNEIGHBOR_CACHE_ENTRY RouterGetRoute(PIP_ADDRESS Destination) TI_DbgPrint(DEBUG_ROUTER,("This-Route: %s (Sharing %d bits)\n", A2S(&NCE->Address), Length)); - if(Length >= MaskLength && (Length > BestLength || !BestLength)) { + if(Length >= MaskLength && (Length > BestLength || !BestLength) && + (!(State & NUD_STALE) || !BestState)) { /* This seems to be a better router */ BestNCE = NCE; BestLength = Length;