- 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
This commit is contained in:
Cameron Gutman 2009-09-19 01:39:16 +00:00
parent 3db65819eb
commit 9ccce3d818
5 changed files with 20 additions and 26 deletions

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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++;
}

View file

@ -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;