[TCPIP]
authorCameron Gutman <aicommander@gmail.com>
Fri, 13 Jan 2012 18:32:30 +0000 (18:32 +0000)
committerCameron Gutman <aicommander@gmail.com>
Fri, 13 Jan 2012 18:32:30 +0000 (18:32 +0000)
- Configure route NCEs to never timeout to prevent them from falling out from under the routing code
- Fix a typo
- Fix detection of duplicate routes
[NETCFGX]
- Don't delete all routes for an interface when adding a default gateway

svn path=/branches/wlan-bringup/; revision=54939

dll/win32/netcfgx/tcpipconf_notify.c
drivers/network/tcpip/datalink/lan.c
drivers/network/tcpip/include/neighbor.h
drivers/network/tcpip/tcpip/dispatch.c
lib/drivers/ip/network/neighbor.c
lib/drivers/ip/network/router.c

index a71d0de..0f85550 100644 (file)
@@ -3243,7 +3243,8 @@ INetCfgComponentControl_fnApplyRegistryChanges(
                         {
                             for (Index = 0; Index < pIpForwardTable->dwNumEntries; Index++)
                             {
-                                if (pIpForwardTable->table[Index].dwForwardIfIndex == pOldConfig->Index)
+                                if (pIpForwardTable->table[Index].dwForwardIfIndex == pOldConfig->Index &&
+                                    pIpForwardTable->table[Index].dwForwardDest == 0)
                                 {
                                     DeleteIpForwardEntry(&pIpForwardTable->table[Index]);
                                 }
index e821915..6cc8e7b 100644 (file)
@@ -709,14 +709,14 @@ BOOLEAN ReconfigureAdapter(PLAN_ADAPTER Adapter, BOOLEAN FinishedReset)
             Interface->Broadcast.Type = IP_ADDRESS_V4;
             Interface->Broadcast.Address.IPv4Address = Interface->Unicast.Address.IPv4Address |
                                                       ~Interface->Netmask.Address.IPv4Address;
+            
+            /* Add the interface route for a static IP */
+            if (!AddrIsUnspecified(&Interface->Unicast))
+                IPAddInterfaceRoute(Interface);
 
             /* Add the default route */
             if (!AddrIsUnspecified(&Interface->StaticRouter))
                 RouterCreateRoute(&DefaultMask, &DefaultMask, &Interface->StaticRouter, Interface, 1);
-
-            /* Add the interface route for a static IP */
-            if (!AddrIsUnspecified(&Interface->Unicast))
-                IPAddInterfaceRoute(Interface);
         }
     }
     else if (!FinishedReset)
index 804ece8..4bc4c26 100644 (file)
@@ -43,16 +43,16 @@ typedef struct NEIGHBOR_CACHE_ENTRY {
 #define NUD_STALE      0x04
 
 /* Timeout for incomplete NCE ARP requests */
-#define ARP_INCOMPLETE_TIMEOUT 5
+#define ARP_INCOMPLETE_TIMEOUT 3
 
 /* Number of seconds between ARP transmissions */
 #define ARP_RATE 900
 
 /* Number of seconds before the NCE times out */
-#define ARP_COMPLETE_TIMEOUT (ARP_RATE + 15)
+#define ARP_COMPLETE_TIMEOUT (ARP_RATE + 9)
 
 /* Number of seconds before retransmission */
-#define ARP_TIMEOUT_RETRANSMISSION 5
+#define ARP_TIMEOUT_RETRANSMISSION 3
 
 extern NEIGHBOR_CACHE_TABLE NeighborCache[NB_HASHMASK + 1];
 
@@ -87,7 +87,8 @@ PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
 
 PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
     PIP_INTERFACE Interface,
-    PIP_ADDRESS Address);
+    PIP_ADDRESS Address,
+    BOOLEAN NoTimeout);
 
 BOOLEAN NBQueuePacket(
     PNEIGHBOR_CACHE_ENTRY NCE,
index d0417a9..e46524d 100644 (file)
@@ -1596,7 +1596,7 @@ NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
 
             IF->Netmask.Type = IP_ADDRESS_V4;
             IF->Netmask.Address.IPv4Address = 0;
-            IF->StaticNetmask = IF->StaticNetmask;
+            IF->StaticNetmask = IF->Netmask;
 
             IF->Broadcast.Type = IP_ADDRESS_V4;
             IF->Broadcast.Address.IPv4Address = 0;
index 07e7e8c..b4e3322 100644 (file)
@@ -106,17 +106,27 @@ VOID NBTimeout(VOID)
 
         for (PrevNCE = &NeighborCache[i].Cache;
              (NCE = *PrevNCE) != NULL;) {
+            if (NCE->State & NUD_INCOMPLETE)
+            {
+                /* Solicit for an address */
+                NBSendSolicit(NCE);
+                if (NCE->EventTimer == 0)
+                {
+                    NCE->EventCount++;
+                    if (NCE->EventCount == ARP_INCOMPLETE_TIMEOUT)
+                    {
+                        NBFlushPacketQueue(NCE, NDIS_STATUS_NETWORK_UNREACHABLE);
+                        NCE->EventCount = 0;
+                    }
+                }
+            }
+
             /* Check if event timer is running */
             if (NCE->EventTimer > 0)  {
                 ASSERT(!(NCE->State & NUD_PERMANENT));
                 NCE->EventCount++;
-                if (NCE->State & NUD_INCOMPLETE)
-                {
-                    /* We desperately need an address in this state or 
-                     * we timeout in 5 seconds */
-                    NBSendSolicit(NCE);
-                }
-                else if ((NCE->EventCount > ARP_RATE &&
+
+                if ((NCE->EventCount > ARP_RATE &&
                      NCE->EventCount % ARP_TIMEOUT_RETRANSMISSION == 0) ||
                     (NCE->EventCount == ARP_RATE))
                 {
@@ -129,7 +139,7 @@ VOID NBTimeout(VOID)
                 if (NCE->EventTimer - NCE->EventCount == 0) {
                     /* Unlink and destroy the NCE */
                     *PrevNCE = NCE->Next;
-
+                    
                     /* Choose the proper failure status */
                     if (NCE->State & NUD_INCOMPLETE)
                     {
@@ -141,8 +151,9 @@ VOID NBTimeout(VOID)
                         /* This guy was stale for way too long */
                         Status = NDIS_STATUS_REQUEST_ABORTED;
                     }
-
+                    
                     NBFlushPacketQueue(NCE, Status);
+
                     ExFreePoolWithTag(NCE, NCE_TAG);
 
                     continue;
@@ -367,7 +378,7 @@ VOID NBUpdateNeighbor(
 
     if( !(NCE->State & NUD_INCOMPLETE) )
     {
-        NCE->EventTimer = ARP_COMPLETE_TIMEOUT;
+        if (NCE->EventTimer) NCE->EventTimer = ARP_COMPLETE_TIMEOUT;
         NBSendPackets( NCE );
     }
 }
@@ -446,7 +457,8 @@ PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
 
 PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
   PIP_INTERFACE Interface,
-  PIP_ADDRESS Address)
+  PIP_ADDRESS Address,
+  BOOLEAN NoTimeout)
 /*
  * FUNCTION: Tries to find a neighbor and if unsuccesful, creates a new NCE
  * ARGUMENTS:
@@ -474,7 +486,7 @@ PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
                                 Interface->AddressLength, NUD_PERMANENT, 0);
         } else {
             NCE = NBAddNeighbor(Interface, Address, NULL,
-                                Interface->AddressLength, NUD_INCOMPLETE, ARP_INCOMPLETE_TIMEOUT);
+                                Interface->AddressLength, NUD_INCOMPLETE, NoTimeout ? 0 : ARP_INCOMPLETE_TIMEOUT);
             if (!NCE) return NULL;
             NBSendSolicit(NCE);
         }
index b30e656..09a8953 100644 (file)
@@ -327,7 +327,7 @@ PNEIGHBOR_CACHE_ENTRY RouteGetRouteToDestination(PIP_ADDRESS Destination)
     Interface = FindOnLinkInterface(Destination);
     if (Interface) {
        /* The destination address is on-link. Check our neighbor cache */
-       NCE = NBFindOrCreateNeighbor(Interface, Destination);
+       NCE = NBFindOrCreateNeighbor(Interface, Destination, FALSE);
     } else {
        /* Destination is not on any subnets we're on. Find a router to use */
        NCE = RouterGetRoute(Destination);
@@ -454,8 +454,10 @@ PFIB_ENTRY RouterCreateRoute(
 
         NCE   = Current->Router;
 
-        if( AddrIsEqual(NetworkAddress, &Current->NetworkAddress) &&
-           AddrIsEqual(Netmask, &Current->Netmask) ) {
+        if(AddrIsEqual(NetworkAddress, &Current->NetworkAddress) &&
+           AddrIsEqual(Netmask, &Current->Netmask) &&
+           NCE->Interface == Interface)
+        {
             TI_DbgPrint(DEBUG_ROUTER,("Attempting to add duplicate route to %s\n", A2S(NetworkAddress)));
             TcpipReleaseSpinLock(&FIBLock, OldIrql);
             return NULL;
@@ -467,7 +469,7 @@ PFIB_ENTRY RouterCreateRoute(
     TcpipReleaseSpinLock(&FIBLock, OldIrql);
 
     /* The NCE references RouterAddress. The NCE is referenced for us */
-    NCE = NBFindOrCreateNeighbor(Interface, RouterAddress);
+    NCE = NBFindOrCreateNeighbor(Interface, RouterAddress, TRUE);
 
     if (!NCE) {
         /* Not enough free resources */