Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5047 lines
143 KiB

  1. // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
  2. //
  3. // Copyright (c) 1985-2000 Microsoft Corporation
  4. //
  5. // This file is part of the Microsoft Research IPv6 Network Protocol Stack.
  6. // You should have received a copy of the Microsoft End-User License Agreement
  7. // for this software along with this release; see the file "license.txt".
  8. // If not, please see http://www.research.microsoft.com/msripv6/license.htm,
  9. // or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
  10. //
  11. // Abstract:
  12. //
  13. // General IPv6 initialization code lives here.
  14. // Actually, this file is mostly interface/address management code.
  15. //
  16. #include "oscfg.h"
  17. #include "ndis.h"
  18. #include "ip6imp.h"
  19. #include "ip6def.h"
  20. #include "llip6if.h"
  21. #include "route.h"
  22. #include "select.h"
  23. #include "icmp.h"
  24. #include "neighbor.h"
  25. #include <tdiinfo.h>
  26. #include <tdi.h>
  27. #include <tdikrnl.h>
  28. #include "alloca.h"
  29. #include "security.h"
  30. #include "mld.h"
  31. #include "md5.h"
  32. #include "info.h"
  33. #include <ntddip6.h>
  34. extern void TCPRemoveIF(Interface *IF);
  35. static void InterfaceStopForwarding(Interface *IF);
  36. //
  37. // Useful IPv6 Address Constants.
  38. //
  39. IPv6Addr UnspecifiedAddr = { 0 };
  40. IPv6Addr LoopbackAddr = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  41. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
  42. IPv6Addr AllNodesOnNodeAddr = {0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  43. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
  44. IPv6Addr AllNodesOnLinkAddr = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  45. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
  46. IPv6Addr AllRoutersOnLinkAddr = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  47. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
  48. IPv6Addr LinkLocalPrefix = {0xfe, 0x80, };
  49. IPv6Addr SiteLocalPrefix = {0xfe, 0xc0, };
  50. IPv6Addr SixToFourPrefix = {0x20, 0x02, };
  51. IPv6Addr V4MappedPrefix = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  52. 0x00, 0x00, 0xff, 0xff, };
  53. IPv6Addr MulticastPrefix = {0xff, };
  54. static uint MulticastScopes[] = {
  55. ADE_INTERFACE_LOCAL,
  56. ADE_LINK_LOCAL,
  57. ADE_SITE_LOCAL,
  58. ADE_ORG_LOCAL,
  59. ADE_GLOBAL
  60. };
  61. //
  62. // These variables are initialized from the registry.
  63. // See ConfigureGlobalParameters.
  64. //
  65. uint DefaultCurHopLimit;
  66. uint MaxAnonDADAttempts;
  67. uint MaxAnonPreferredLifetime;
  68. uint MaxAnonValidLifetime;
  69. uint AnonRegenerateTime;
  70. uint UseAnonymousAddresses;
  71. uint MaxAnonRandomTime;
  72. uint AnonRandomTime;
  73. #define AnonPreferredLifetime (MaxAnonPreferredLifetime - AnonRandomTime)
  74. //
  75. // Timer variables.
  76. //
  77. KTIMER IPv6Timer;
  78. KDPC IPv6TimeoutDpc;
  79. int IPv6TimerStarted = FALSE;
  80. uint PacketPoolSize;
  81. NDIS_HANDLE IPv6PacketPool, IPv6BufferPool;
  82. //
  83. // Statistics
  84. //
  85. IPInternalPerCpuStats IPPerCpuStats[IPS_MAX_PROCESSOR_BUCKETS];
  86. CACHE_ALIGN IPSNMPInfo IPSInfo;
  87. uint NumForwardingInterfaces;
  88. //
  89. // The NetTableListLock may be acquired while holding an interface lock.
  90. //
  91. NetTableEntry *NetTableList; // Global list of NTEs.
  92. KSPIN_LOCK NetTableListLock; // Lock protecting this list.
  93. //
  94. // The IFListLock may be acquired while holding an interface lock
  95. // or route lock.
  96. //
  97. KSPIN_LOCK IFListLock; // Lock protecting this list.
  98. Interface *IFList = NULL; // List of interfaces active.
  99. //
  100. // The ZoneUpdateLock prevents concurrent updates
  101. // of interface ZoneIndices.
  102. //
  103. KSPIN_LOCK ZoneUpdateLock;
  104. //
  105. // Used to assign indices to interfaces.
  106. // See InterfaceIndex.
  107. //
  108. uint NextIFIndex = 0;
  109. //* AddNTEToNetTableList
  110. //
  111. // Called with the list already locked.
  112. //
  113. void
  114. AddNTEToNetTableList(NetTableEntry *NTE)
  115. {
  116. if (NetTableList != NULL)
  117. NetTableList->PrevOnNTL = &NTE->NextOnNTL;
  118. NTE->PrevOnNTL = &NetTableList;
  119. NTE->NextOnNTL = NetTableList;
  120. NetTableList = NTE;
  121. IPSInfo.ipsi_numaddr++;
  122. }
  123. //* RemoveNTEFromNetTableList
  124. //
  125. // Called with the list already locked.
  126. //
  127. void
  128. RemoveNTEFromNetTableList(NetTableEntry *NTE)
  129. {
  130. NetTableEntry *NextNTE;
  131. NextNTE = NTE->NextOnNTL;
  132. *NTE->PrevOnNTL = NextNTE;
  133. if (NextNTE != NULL)
  134. NextNTE->PrevOnNTL = NTE->PrevOnNTL;
  135. IPSInfo.ipsi_numaddr--;
  136. }
  137. //* AddNTEToInterface
  138. //
  139. // Adds an NTE to an Interface's list of ADEs.
  140. //
  141. // Called with the interface already locked.
  142. //
  143. void
  144. AddNTEToInterface(Interface *IF, NetTableEntry *NTE)
  145. {
  146. //
  147. // The NTE holds a reference for the interface,
  148. // so anyone with a reference for the NTE
  149. // can safely dereference NTE->IF.
  150. //
  151. AddRefIF(IF);
  152. NTE->IF = IF;
  153. NTE->Next = IF->ADE;
  154. IF->ADE = (AddressEntry *)NTE;
  155. }
  156. //* RemoveNTEFromInterface
  157. //
  158. // Removes a new NTE from the Interface's list of ADEs.
  159. //
  160. // Called with the interface already locked.
  161. // The NTE must be first on the list.
  162. //
  163. void
  164. RemoveNTEFromInterface(Interface *IF, NetTableEntry *NTE)
  165. {
  166. ASSERT(IF->ADE == (AddressEntry *)NTE);
  167. IF->ADE = NTE->Next;
  168. ReleaseIF(IF);
  169. }
  170. typedef struct SynchronizeMulticastContext {
  171. WORK_QUEUE_ITEM WQItem;
  172. Interface *IF;
  173. } SynchronizeMulticastContext;
  174. //* SynchronizeMulticastAddresses
  175. //
  176. // Synchronize the interface's list of link-layer multicast addresses
  177. // with the link's knowledge of those addresses.
  178. //
  179. // Callable from thread context, not from DPC context.
  180. // Called with no locks held.
  181. //
  182. void
  183. SynchronizeMulticastAddresses(void *Context)
  184. {
  185. SynchronizeMulticastContext *smc = (SynchronizeMulticastContext *) Context;
  186. Interface *IF = smc->IF;
  187. void *LinkAddresses;
  188. LinkLayerMulticastAddress *MCastAddr;
  189. uint SizeofLLMA = SizeofLinkLayerMulticastAddress(IF);
  190. uint NumKeep, NumDeleted, NumAdded, Position;
  191. uint i;
  192. NDIS_STATUS Status;
  193. KIRQL OldIrql;
  194. ExFreePool(smc);
  195. //
  196. // First acquire the heavy-weight lock used to serialize
  197. // SetMCastAddrList operations.
  198. //
  199. KeWaitForSingleObject(&IF->WorkerLock, Executive, KernelMode,
  200. FALSE, NULL);
  201. //
  202. // Second acquire the lock that protects the interface,
  203. // so we can examine IF->MCastAddresses et al.
  204. //
  205. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  206. //
  207. // If this interface is going away, do nothing.
  208. //
  209. if (IsDisabledIF(IF)) {
  210. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  211. "SynchronizeMulticastContext(IF %p)"
  212. " - disabled (%u refs)\n", IF, IF->RefCnt));
  213. goto ErrorExit;
  214. }
  215. //
  216. // Allocate sufficient space for the link addresses
  217. // that we will pass to SetMCastAddrList.
  218. // This is actually an over-estimate.
  219. //
  220. LinkAddresses = ExAllocatePool(NonPagedPool,
  221. IF->MCastAddrNum * IF->LinkAddressLength);
  222. if (LinkAddresses == NULL) {
  223. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  224. "SynchronizeMulticastContext(IF %p) - no pool\n", IF));
  225. goto ErrorExit;
  226. }
  227. //
  228. // Make three passes through the address array,
  229. // constructing LinkAddresses.
  230. //
  231. NumKeep = 0;
  232. MCastAddr = IF->MCastAddresses;
  233. for (i = 0; i < IF->MCastAddrNum; i++) {
  234. if ((MCastAddr->RefCntAndFlags & LLMA_FLAG_REGISTERED) &&
  235. IsLLMAReferenced(MCastAddr)) {
  236. //
  237. // This address has already been registered,
  238. // and we are keeping it.
  239. //
  240. Position = NumKeep++;
  241. RtlCopyMemory(((uchar *)LinkAddresses +
  242. Position * IF->LinkAddressLength),
  243. MCastAddr->LinkAddress,
  244. IF->LinkAddressLength);
  245. }
  246. MCastAddr = (LinkLayerMulticastAddress *)
  247. ((uchar *)MCastAddr + SizeofLLMA);
  248. }
  249. if (NumKeep == IF->MCastAddrNum) {
  250. //
  251. // Can happen if there are races between worker threads,
  252. // but should be rare.
  253. //
  254. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  255. "SynchronizeMulticastAddresses - noop?\n"));
  256. ExFreePool(LinkAddresses);
  257. goto ErrorExit;
  258. }
  259. NumAdded = 0;
  260. MCastAddr = IF->MCastAddresses;
  261. for (i = 0; i < IF->MCastAddrNum; i++) {
  262. if (!(MCastAddr->RefCntAndFlags & LLMA_FLAG_REGISTERED) &&
  263. IsLLMAReferenced(MCastAddr)) {
  264. //
  265. // This address has not been registered,
  266. // and we are adding it.
  267. // We set LLMA_FLAG_REGISTERED below,
  268. // after we are past all error cases.
  269. //
  270. Position = NumKeep + NumAdded++;
  271. RtlCopyMemory(((uchar *)LinkAddresses +
  272. Position * IF->LinkAddressLength),
  273. MCastAddr->LinkAddress,
  274. IF->LinkAddressLength);
  275. }
  276. MCastAddr = (LinkLayerMulticastAddress *)
  277. ((uchar *)MCastAddr + SizeofLLMA);
  278. }
  279. NumDeleted = 0;
  280. MCastAddr = IF->MCastAddresses;
  281. for (i = 0; i < IF->MCastAddrNum; i++) {
  282. if ((MCastAddr->RefCntAndFlags & LLMA_FLAG_REGISTERED) &&
  283. !IsLLMAReferenced(MCastAddr)) {
  284. //
  285. // This address has already been registered,
  286. // and we are deleting it.
  287. //
  288. Position = NumKeep + NumAdded + NumDeleted++;
  289. RtlCopyMemory(((uchar *)LinkAddresses +
  290. Position * IF->LinkAddressLength),
  291. MCastAddr->LinkAddress,
  292. IF->LinkAddressLength);
  293. }
  294. MCastAddr = (LinkLayerMulticastAddress *)
  295. ((uchar *)MCastAddr + SizeofLLMA);
  296. }
  297. //
  298. // Some addresses might have been added & removed
  299. // before being registered, so they have a zero RefCnt.
  300. // We do not want to notify the link-layer about them.
  301. //
  302. ASSERT(NumKeep + NumAdded + NumDeleted <= IF->MCastAddrNum);
  303. //
  304. // Remove any unreferenced addresses.
  305. //
  306. if (NumKeep + NumAdded != IF->MCastAddrNum) {
  307. LinkLayerMulticastAddress *NewMCastAddresses;
  308. LinkLayerMulticastAddress *NewMCastAddr;
  309. LinkLayerMulticastAddress *MCastAddrMark;
  310. LinkLayerMulticastAddress *NextMCastAddr;
  311. UINT_PTR Length;
  312. if (NumKeep + NumAdded == 0) {
  313. //
  314. // None left.
  315. //
  316. NewMCastAddresses = NULL;
  317. }
  318. else {
  319. NewMCastAddresses = ExAllocatePool(NonPagedPool,
  320. ((NumKeep + NumAdded) * SizeofLLMA));
  321. if (NewMCastAddresses == NULL) {
  322. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  323. "SynchronizeMulticastContext(IF %p)"
  324. " - no pool\n", IF));
  325. ExFreePool(LinkAddresses);
  326. goto ErrorExit;
  327. }
  328. //
  329. // Copy the addresses that are still referenced
  330. // to the new array. Normally there will only be
  331. // one unreferenced address, so it's faster to search
  332. // for it and then copy the elements before and after.
  333. // Of course there might be multiple unreferenced addresses.
  334. //
  335. NewMCastAddr = NewMCastAddresses;
  336. MCastAddrMark = IF->MCastAddresses;
  337. for (i = 0, MCastAddr = IF->MCastAddresses;
  338. i < IF->MCastAddrNum;
  339. i++, MCastAddr = NextMCastAddr) {
  340. NextMCastAddr = (LinkLayerMulticastAddress *)
  341. ((uchar *)MCastAddr + SizeofLLMA);
  342. if (!IsLLMAReferenced(MCastAddr)) {
  343. //
  344. // Remove this address because it has no references.
  345. //
  346. if (MCastAddrMark < MCastAddr) {
  347. Length = (uchar *)MCastAddr - (uchar *)MCastAddrMark;
  348. RtlCopyMemory(NewMCastAddr, MCastAddrMark, Length);
  349. NewMCastAddr = (LinkLayerMulticastAddress *)
  350. ((uchar *)NewMCastAddr + Length);
  351. }
  352. MCastAddrMark = NextMCastAddr;
  353. }
  354. else {
  355. //
  356. // Remember that we are registering this address.
  357. //
  358. MCastAddr->RefCntAndFlags |= LLMA_FLAG_REGISTERED;
  359. }
  360. }
  361. if (MCastAddrMark < MCastAddr) {
  362. Length = (uchar *)MCastAddr - (uchar *)MCastAddrMark;
  363. RtlCopyMemory(NewMCastAddr, MCastAddrMark, Length);
  364. }
  365. }
  366. ExFreePool(IF->MCastAddresses);
  367. IF->MCastAddresses = NewMCastAddresses;
  368. IF->MCastAddrNum = NumKeep + NumAdded;
  369. }
  370. else {
  371. //
  372. // We need to set LLMA_FLAG_REGISTERED.
  373. //
  374. MCastAddr = IF->MCastAddresses;
  375. for (i = 0; i < IF->MCastAddrNum; i++) {
  376. MCastAddr->RefCntAndFlags |= LLMA_FLAG_REGISTERED;
  377. MCastAddr = (LinkLayerMulticastAddress *)
  378. ((uchar *)MCastAddr + SizeofLLMA);
  379. }
  380. }
  381. //
  382. // We have constructed the LinkAddresses array from the interface.
  383. // Before we can call SetMCastAddrList, we must drop the interface lock.
  384. // We still hold the heavy-weight WorkerLock, so multiple SetMCastAddrList
  385. // calls are properly serialized.
  386. //
  387. KeReleaseSpinLock(&IF->Lock, OldIrql);
  388. //
  389. // Pass the multicast link addresses down to the link layer,
  390. // if there's actually anything changed.
  391. //
  392. if (NumAdded + NumDeleted == 0) {
  393. //
  394. // Can happen if there are races between worker threads,
  395. // but should be very rare.
  396. //
  397. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  398. "SynchronizeMulticastAddresses - noop?\n"));
  399. }
  400. else {
  401. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  402. "SynchronizeMulticastAddresses(IF %p) %u + %u + %u\n",
  403. IF, NumKeep, NumAdded, NumDeleted));
  404. Status = (*IF->SetMCastAddrList)(IF->LinkContext, LinkAddresses,
  405. NumKeep, NumAdded, NumDeleted);
  406. if (Status != NDIS_STATUS_SUCCESS) {
  407. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  408. "SynchronizeMulticastAddresses(%p) -> %x\n", IF, Status));
  409. }
  410. }
  411. KeReleaseMutex(&IF->WorkerLock, FALSE);
  412. ExFreePool(LinkAddresses);
  413. ReleaseIF(IF);
  414. return;
  415. ErrorExit:
  416. KeReleaseSpinLock(&IF->Lock, OldIrql);
  417. KeReleaseMutex(&IF->WorkerLock, FALSE);
  418. ReleaseIF(IF);
  419. }
  420. //* DeferSynchronizeMulticastAddresses
  421. //
  422. // Because SynchronizeMulticastAddresses can only be called
  423. // from a thread context with no locks held, this function
  424. // provides a way to defer a call to SynchronizeMulticastAddresses
  425. // when running at DPC level.
  426. //
  427. // In error cases (memory allocation failure),
  428. // we return with IF_FLAG_MCAST_SYNC still set,
  429. // so we will be called again later.
  430. //
  431. // Called with the interface lock held.
  432. //
  433. void
  434. DeferSynchronizeMulticastAddresses(Interface *IF)
  435. {
  436. SynchronizeMulticastContext *smc;
  437. smc = ExAllocatePool(NonPagedPool, sizeof *smc);
  438. if (smc == NULL) {
  439. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  440. "DeferSynchronizeMulticastAddresses - no pool\n"));
  441. return;
  442. }
  443. ExInitializeWorkItem(&smc->WQItem, SynchronizeMulticastAddresses, smc);
  444. smc->IF = IF;
  445. AddRefIF(IF);
  446. IF->Flags &= ~IF_FLAG_MCAST_SYNC;
  447. ExQueueWorkItem(&smc->WQItem, CriticalWorkQueue);
  448. }
  449. //* CheckLinkLayerMulticastAddress
  450. //
  451. // Is the interface receiving this link-layer multicast address?
  452. //
  453. // Callable from thread or DPC context.
  454. // Called with no locks held.
  455. //
  456. int
  457. CheckLinkLayerMulticastAddress(Interface *IF, const void *LinkAddress)
  458. {
  459. if (IF->SetMCastAddrList == NULL) {
  460. //
  461. // The interface does not track multicast link-layer addresses.
  462. // For example, point-to-point or loopback interfaces.
  463. // We must assume that the interface wants to receive all
  464. // link-layer multicasts.
  465. //
  466. return TRUE;
  467. }
  468. else {
  469. KIRQL OldIrql;
  470. LinkLayerMulticastAddress *MCastAddr;
  471. uint SizeofLLMA = SizeofLinkLayerMulticastAddress(IF);
  472. uint i;
  473. int Found = FALSE;
  474. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  475. MCastAddr = IF->MCastAddresses;
  476. for (i = 0; i < IF->MCastAddrNum; i++) {
  477. //
  478. // Have we found the link-layer address?
  479. //
  480. if (RtlCompareMemory(MCastAddr->LinkAddress, LinkAddress,
  481. IF->LinkAddressLength) ==
  482. IF->LinkAddressLength) {
  483. if (IsLLMAReferenced(MCastAddr))
  484. Found = TRUE;
  485. break;
  486. }
  487. MCastAddr = (LinkLayerMulticastAddress *)
  488. ((uchar *)MCastAddr + SizeofLLMA);
  489. }
  490. KeReleaseSpinLock(&IF->Lock, OldIrql);
  491. return Found;
  492. }
  493. }
  494. //* AddLinkLayerMulticastAddress
  495. //
  496. // Called to indicate interest in the link-layer multicast address
  497. // corresponding to the supplied IPv6 multicast address.
  498. //
  499. // Called with the interface locked.
  500. //
  501. void
  502. AddLinkLayerMulticastAddress(Interface *IF, const IPv6Addr *Address)
  503. {
  504. //
  505. // If the interface doesn't keep track of link-layer multicast
  506. // addresses (e.g., if it's P2P), we don't need to do anything.
  507. //
  508. if (IF->SetMCastAddrList != NULL) {
  509. void *LinkAddress = alloca(IF->LinkAddressLength);
  510. LinkLayerMulticastAddress *MCastAddr;
  511. uint SizeofLLMA = SizeofLinkLayerMulticastAddress(IF);
  512. uint i;
  513. //
  514. // Create the link-layer multicast address
  515. // that corresponds to the IPv6 multicast address.
  516. //
  517. (*IF->ConvertAddr)(IF->LinkContext, Address, LinkAddress);
  518. //
  519. // Check if the link-layer multicast address is already present.
  520. //
  521. MCastAddr = IF->MCastAddresses;
  522. for (i = 0; i < IF->MCastAddrNum; i++) {
  523. //
  524. // Have we found the link-layer address?
  525. //
  526. if (RtlCompareMemory(MCastAddr->LinkAddress, LinkAddress,
  527. IF->LinkAddressLength) ==
  528. IF->LinkAddressLength)
  529. goto FoundMCastAddr;
  530. MCastAddr = (LinkLayerMulticastAddress *)
  531. ((uchar *)MCastAddr + SizeofLLMA);
  532. }
  533. //
  534. // We must add this link-layer multicast address.
  535. //
  536. MCastAddr = ExAllocatePool(NonPagedPool,
  537. (IF->MCastAddrNum + 1) * SizeofLLMA);
  538. if (MCastAddr == NULL) {
  539. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  540. "AddLinkLayerMulticastAddress - no pool\n"));
  541. return;
  542. }
  543. if (IF->MCastAddresses != NULL) {
  544. RtlCopyMemory(MCastAddr, IF->MCastAddresses,
  545. IF->MCastAddrNum * SizeofLLMA);
  546. ExFreePool(IF->MCastAddresses);
  547. }
  548. IF->MCastAddresses = MCastAddr;
  549. MCastAddr = (LinkLayerMulticastAddress *)
  550. ((uchar *)MCastAddr + IF->MCastAddrNum * SizeofLLMA);
  551. MCastAddr->RefCntAndFlags = 0;
  552. RtlCopyMemory(MCastAddr->LinkAddress, LinkAddress, IF->LinkAddressLength);
  553. IF->MCastAddrNum++;
  554. IF->Flags |= IF_FLAG_MCAST_SYNC;
  555. FoundMCastAddr:
  556. AddRefLLMA(MCastAddr);
  557. }
  558. }
  559. //* DelLinkLayerMulticastAddress
  560. //
  561. // Called to retract interest in the link-layer multicast address
  562. // corresponding to the supplied IPv6 multicast address.
  563. //
  564. // Called with the interface locked.
  565. //
  566. void
  567. DelLinkLayerMulticastAddress(Interface *IF, IPv6Addr *Address)
  568. {
  569. //
  570. // If the interface doesn't keep track of link-layer multicast
  571. // addresses (e.g., if it's P2P), we don't need to do anything.
  572. //
  573. if (IF->SetMCastAddrList != NULL) {
  574. void *LinkAddress = alloca(IF->LinkAddressLength);
  575. LinkLayerMulticastAddress *MCastAddr;
  576. uint SizeofLLMA = SizeofLinkLayerMulticastAddress(IF);
  577. uint i;
  578. //
  579. // Create the link-layer multicast address
  580. // that corresponds to the IPv6 multicast address.
  581. //
  582. (*IF->ConvertAddr)(IF->LinkContext, Address, LinkAddress);
  583. //
  584. // Find the link-layer multicast address.
  585. // It must be present, but if it isn't, we avoid crashing.
  586. //
  587. MCastAddr = IF->MCastAddresses;
  588. for (i = 0; i < IF->MCastAddrNum; i++) {
  589. //
  590. // Have we found the link-layer address?
  591. //
  592. if (RtlCompareMemory(MCastAddr->LinkAddress, LinkAddress,
  593. IF->LinkAddressLength) ==
  594. IF->LinkAddressLength) {
  595. //
  596. // Decrement the address's refcount.
  597. // If it hits zero, indicate a need to synchronize.
  598. //
  599. ASSERT(IsLLMAReferenced(MCastAddr));
  600. ReleaseLLMA(MCastAddr);
  601. if (!IsLLMAReferenced(MCastAddr))
  602. IF->Flags |= IF_FLAG_MCAST_SYNC;
  603. break;
  604. }
  605. MCastAddr = (LinkLayerMulticastAddress *)
  606. ((uchar *)MCastAddr + SizeofLLMA);
  607. }
  608. ASSERT(i != IF->MCastAddrNum);
  609. }
  610. }
  611. //* RestartLinkLayerMulticast
  612. //
  613. // Resets the status of link-layer multicast addresses,
  614. // so that they are registered again with the link layer.
  615. // The ResetDone function is called under a lock that serializes
  616. // it with SetMCastAddrList calls.
  617. //
  618. // Callable from thread context, not DPC context.
  619. //
  620. void
  621. RestartLinkLayerMulticast(
  622. void *Context,
  623. void (*ResetDone)(void *Context))
  624. {
  625. Interface *IF = (Interface *) Context;
  626. KIRQL OldIrql;
  627. ASSERT(IF->SetMCastAddrList != NULL);
  628. //
  629. // Serialize with SetMCastAddrList operations.
  630. //
  631. KeWaitForSingleObject(&IF->WorkerLock, Executive, KernelMode,
  632. FALSE, NULL);
  633. //
  634. // So we can play with IF->MCastAddresses et al.
  635. //
  636. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  637. //
  638. // If this interface is going away, do nothing.
  639. //
  640. if (IsDisabledIF(IF)) {
  641. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  642. "RestartLinkLayerMulticast(IF %p)"
  643. " - disabled (%u refs)\n", IF, IF->RefCnt));
  644. KeReleaseSpinLock(&IF->Lock, OldIrql);
  645. }
  646. else {
  647. LinkLayerMulticastAddress *MCastAddr;
  648. uint SizeofLLMA = SizeofLinkLayerMulticastAddress(IF);
  649. uint i;
  650. //
  651. // Reset the registered flag for all multicast addresses.
  652. //
  653. MCastAddr = IF->MCastAddresses;
  654. for (i = 0; i < IF->MCastAddrNum; i++) {
  655. if (IsLLMAReferenced(MCastAddr)) {
  656. MCastAddr->RefCntAndFlags &= ~LLMA_FLAG_REGISTERED;
  657. IF->Flags |= IF_FLAG_MCAST_SYNC;
  658. }
  659. MCastAddr = (LinkLayerMulticastAddress *)
  660. ((uchar *)MCastAddr + SizeofLLMA);
  661. }
  662. if (IsMCastSyncNeeded(IF))
  663. DeferSynchronizeMulticastAddresses(IF);
  664. KeReleaseSpinLock(&IF->Lock, OldIrql);
  665. //
  666. // Let the link-layer know that the reset is done.
  667. //
  668. (*ResetDone)(IF->LinkContext);
  669. }
  670. KeReleaseMutex(&IF->WorkerLock, FALSE);
  671. }
  672. typedef enum {
  673. CONTROL_LOOPBACK_DISABLED,
  674. CONTROL_LOOPBACK_ENABLED,
  675. CONTROL_LOOPBACK_DESTROY
  676. } ControlLoopbackOp;
  677. //* ControlLoopback
  678. //
  679. // Controls loopback functionality for a unicast or anycast address.
  680. //
  681. // This function is used in three ways, depending on Op:
  682. // create a disabled loopback route (or disable an existing route),
  683. // create an enabled loopback route (or enable an existing route),
  684. // destroy any existing loopback route.
  685. //
  686. // It returns FALSE if there is a resource shortage.
  687. // In actual usage, it will only fail when an NTE/AAE
  688. // is first created, because subsequently the RTE and NCE
  689. // will already exist.
  690. //
  691. // Called with the interface lock held.
  692. //
  693. int
  694. ControlLoopback(Interface *IF, const IPv6Addr *Address,
  695. ControlLoopbackOp Op)
  696. {
  697. NeighborCacheEntry *NCE;
  698. int Loopback;
  699. uint Lifetime;
  700. uint Type;
  701. int rc;
  702. NTSTATUS Status;
  703. switch (Op) {
  704. case CONTROL_LOOPBACK_DISABLED:
  705. Loopback = FALSE;
  706. Lifetime = 0;
  707. Type = RTE_TYPE_SYSTEM;
  708. break;
  709. case CONTROL_LOOPBACK_ENABLED:
  710. Loopback = TRUE;
  711. Lifetime = INFINITE_LIFETIME;
  712. Type = RTE_TYPE_SYSTEM;
  713. break;
  714. case CONTROL_LOOPBACK_DESTROY:
  715. Loopback = FALSE;
  716. Lifetime = 0;
  717. Type = 0; // Special value for destroying system routes.
  718. break;
  719. default:
  720. ASSERT(!"ControlLoopback bad op");
  721. }
  722. //
  723. // Get the NCE for this address.
  724. //
  725. NCE = FindOrCreateNeighbor(IF, Address);
  726. if (NCE == NULL)
  727. return FALSE;
  728. //
  729. // Update the loopback route for this address.
  730. //
  731. Status = RouteTableUpdate(NULL, // System update.
  732. IF, NCE, Address, IPV6_ADDRESS_LENGTH, 0,
  733. Lifetime, Lifetime,
  734. ROUTE_PREF_LOOPBACK,
  735. Type,
  736. FALSE, FALSE);
  737. if (NT_SUCCESS(Status)) {
  738. //
  739. // Update the address's loopback status in the neighbor cache.
  740. //
  741. ControlNeighborLoopback(NCE, Loopback);
  742. rc = TRUE;
  743. }
  744. else {
  745. //
  746. // If RouteTableUpdate failed because the interface is
  747. // being destroyed, then we succeed without doing anything.
  748. //
  749. rc = (Status == STATUS_INVALID_PARAMETER_1);
  750. }
  751. ReleaseNCE(NCE);
  752. return rc;
  753. }
  754. //* DeleteMAE
  755. //
  756. // Cleanup and delete an MAE because the multicast address
  757. // is no longer assigned to the interface.
  758. // It is already removed from the interface's list.
  759. //
  760. // Called with the interface already locked.
  761. //
  762. void
  763. DeleteMAE(Interface *IF, MulticastAddressEntry *MAE)
  764. {
  765. int SendDoneMsg;
  766. KeAcquireSpinLockAtDpcLevel(&QueryListLock);
  767. if (!IsDisabledIF(IF) && (MAE->MCastFlags & MAE_LAST_REPORTER)) {
  768. //
  769. // We need to send a Done message.
  770. // Put the MAE on the QueryList with a zero timer.
  771. //
  772. if (MAE->MCastTimer == 0)
  773. AddToQueryList(MAE);
  774. else
  775. MAE->MCastTimer = 0;
  776. AddRefIF(IF);
  777. MAE->IF = IF;
  778. SendDoneMsg = TRUE;
  779. }
  780. else {
  781. //
  782. // If the MLD timer is running, remove from the query list.
  783. //
  784. if (MAE->MCastTimer != 0)
  785. RemoveFromQueryList(MAE);
  786. SendDoneMsg = FALSE;
  787. }
  788. KeReleaseSpinLockFromDpcLevel(&QueryListLock);
  789. //
  790. // Retract our interest in the corresponding
  791. // link-layer multicast address.
  792. //
  793. DelLinkLayerMulticastAddress(IF, &MAE->Address);
  794. //
  795. // Delete the MAE, unless we left it on the QueryList
  796. // pending a Done message.
  797. //
  798. if (!SendDoneMsg)
  799. ExFreePool(MAE);
  800. }
  801. //* FindAndReleaseMAE
  802. //
  803. // Finds the MAE for a multicast address and releases one reference
  804. // for the MAE. May result in the MAE disappearing.
  805. //
  806. // If successful, returns the MAE.
  807. // Note that it may be an invalid pointer!
  808. // Returns NULL on failure.
  809. //
  810. // Called with the interface already locked.
  811. //
  812. MulticastAddressEntry *
  813. FindAndReleaseMAE(Interface *IF, const IPv6Addr *Addr)
  814. {
  815. AddressEntry **pADE;
  816. MulticastAddressEntry *MAE;
  817. pADE = FindADE(IF, Addr);
  818. MAE = (MulticastAddressEntry *) *pADE;
  819. if (MAE != NULL) {
  820. if (MAE->Type == ADE_MULTICAST) {
  821. ASSERT(MAE->MCastRefCount != 0);
  822. if (--MAE->MCastRefCount == 0) {
  823. //
  824. // The MAE has no more references.
  825. // Remove it from the Interface and delete it.
  826. //
  827. *pADE = MAE->Next;
  828. DeleteMAE(IF, MAE);
  829. }
  830. }
  831. else {
  832. //
  833. // Return NULL for error.
  834. //
  835. MAE = NULL;
  836. }
  837. }
  838. return MAE;
  839. }
  840. //* FindAndReleaseSolicitedNodeMAE
  841. //
  842. // Finds the MAE for the corresponding solicited-node multicast address
  843. // and releases one reference for the MAE.
  844. // May result in the MAE disappearing.
  845. //
  846. // Called with the interface already locked.
  847. //
  848. void
  849. FindAndReleaseSolicitedNodeMAE(Interface *IF, const IPv6Addr *Addr)
  850. {
  851. if (IF->Flags & IF_FLAG_NEIGHBOR_DISCOVERS) {
  852. IPv6Addr MCastAddr;
  853. MulticastAddressEntry *MAE;
  854. //
  855. // Create the corresponding solicited-node multicast address.
  856. //
  857. CreateSolicitedNodeMulticastAddress(Addr, &MCastAddr);
  858. //
  859. // Release the MAE for the solicited-node address.
  860. // NB: This may fail during interface shutdown
  861. // if we remove the solicited-node MAE before the NTE or AAE.
  862. //
  863. MAE = FindAndReleaseMAE(IF, &MCastAddr);
  864. ASSERT((MAE != NULL) || IsDisabledIF(IF));
  865. }
  866. }
  867. //* FindOrCreateMAE
  868. //
  869. // If an MAE for the multicast address already exists,
  870. // just bump the reference count. Otherwise create a new MAE.
  871. // Returns NULL for failure.
  872. //
  873. // If an NTE is supplied and an MAE is created,
  874. // then the MAE is associated with the NTE.
  875. //
  876. // Called with the interface already locked.
  877. //
  878. MulticastAddressEntry *
  879. FindOrCreateMAE(
  880. Interface *IF,
  881. const IPv6Addr *Addr,
  882. NetTableEntry *NTE)
  883. {
  884. AddressEntry **pADE;
  885. MulticastAddressEntry *MAE;
  886. //
  887. // Can not create a new MAE if the interface is shutting down.
  888. //
  889. if (IsDisabledIF(IF))
  890. return NULL;
  891. pADE = FindADE(IF, Addr);
  892. MAE = (MulticastAddressEntry *) *pADE;
  893. if (MAE == NULL) {
  894. //
  895. // Create a new MAE.
  896. //
  897. MAE = ExAllocatePool(NonPagedPool, sizeof(MulticastAddressEntry));
  898. if (MAE == NULL)
  899. return NULL;
  900. //
  901. // Initialize the new MAE.
  902. //
  903. if (NTE != NULL)
  904. MAE->NTE = NTE;
  905. else
  906. MAE->IF = IF;
  907. MAE->Address = *Addr;
  908. MAE->Type = ADE_MULTICAST;
  909. MAE->Scope = MulticastAddressScope(Addr);
  910. MAE->MCastRefCount = 0; // Incremented below.
  911. MAE->MCastTimer = 0;
  912. MAE->NextQL = NULL;
  913. //
  914. // With any luck the compiler will optimize these
  915. // field assignments...
  916. //
  917. if (IsMLDReportable(MAE)) {
  918. //
  919. // We should send MLD reports for this address.
  920. // Start by sending initial reports immediately.
  921. //
  922. MAE->MCastFlags = MAE_REPORTABLE;
  923. MAE->MCastCount = MLD_NUM_INITIAL_REPORTS;
  924. MAE->MCastTimer = 1; // Immediately.
  925. KeAcquireSpinLockAtDpcLevel(&QueryListLock);
  926. AddToQueryList(MAE);
  927. KeReleaseSpinLockFromDpcLevel(&QueryListLock);
  928. }
  929. else {
  930. MAE->MCastFlags = 0;
  931. MAE->MCastCount = 0;
  932. MAE->MCastTimer = 0;
  933. }
  934. //
  935. // Add the MAE to the interface's ADE list.
  936. //
  937. MAE->Next = NULL;
  938. *pADE = (AddressEntry *)MAE;
  939. //
  940. // Indicate our interest in the corresponding
  941. // link-layer multicast address.
  942. //
  943. AddLinkLayerMulticastAddress(IF, Addr);
  944. }
  945. else {
  946. ASSERT(MAE->Type == ADE_MULTICAST);
  947. }
  948. MAE->MCastRefCount++;
  949. return MAE;
  950. }
  951. //* FindOrCreateSolicitedNodeMAE
  952. //
  953. // Called with a unicast or anycast address.
  954. //
  955. // If an MAE for the solicited-node multicast address already exists,
  956. // just bump the reference count. Otherwise create a new MAE.
  957. // Returns TRUE for success.
  958. //
  959. // Called with the interface already locked.
  960. //
  961. int
  962. FindOrCreateSolicitedNodeMAE(Interface *IF, const IPv6Addr *Addr)
  963. {
  964. if (IF->Flags & IF_FLAG_NEIGHBOR_DISCOVERS) {
  965. IPv6Addr MCastAddr;
  966. //
  967. // Create the corresponding solicited-node multicast address.
  968. //
  969. CreateSolicitedNodeMulticastAddress(Addr, &MCastAddr);
  970. //
  971. // Find or create an MAE for the solicited-node multicast address.
  972. //
  973. return FindOrCreateMAE(IF, &MCastAddr, NULL) != NULL;
  974. }
  975. else {
  976. //
  977. // Only interfaces that support Neighbor Discovery
  978. // use solicited-node multicast addresses.
  979. //
  980. return TRUE;
  981. }
  982. }
  983. //* FindOrCreateAAE
  984. //
  985. // Adds an anycast address to the interface,
  986. // associated with the NTE.
  987. //
  988. // If the interface already has the anycast address assigned,
  989. // then this does nothing.
  990. //
  991. // Returns TRUE for success.
  992. //
  993. // Called with NO locks held.
  994. // Callable from thread or DPC context.
  995. //
  996. int
  997. FindOrCreateAAE(Interface *IF, const IPv6Addr *Addr,
  998. NetTableEntryOrInterface *NTEorIF)
  999. {
  1000. AddressEntry **pADE;
  1001. AnycastAddressEntry *AAE;
  1002. KIRQL OldIrql;
  1003. int rc;
  1004. if (NTEorIF == NULL)
  1005. NTEorIF = CastFromIF(IF);
  1006. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  1007. if (IsDisabledIF(IF)) {
  1008. //
  1009. // Can't create a new AAE if the interface is shutting down.
  1010. //
  1011. rc = FALSE;
  1012. }
  1013. else {
  1014. pADE = FindADE(IF, Addr);
  1015. AAE = (AnycastAddressEntry *) *pADE;
  1016. if (AAE == NULL) {
  1017. //
  1018. // Create an AAE for the anycast address.
  1019. //
  1020. AAE = ExAllocatePool(NonPagedPool, sizeof(AnycastAddressEntry));
  1021. if (AAE == NULL) {
  1022. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1023. "FindOrCreateAAE: no pool\n"));
  1024. rc = FALSE;
  1025. goto ErrorReturn;
  1026. }
  1027. //
  1028. // Initialize the new AAE.
  1029. //
  1030. AAE->NTEorIF = NTEorIF;
  1031. AAE->Address = *Addr;
  1032. AAE->Type = ADE_ANYCAST;
  1033. AAE->Scope = UnicastAddressScope(Addr);
  1034. //
  1035. // Add the AAE to the interface's ADE list.
  1036. // NB: FindOrCreateSolicitedNodeMAE may add an MAE at the end,
  1037. // so we do this first.
  1038. //
  1039. AAE->Next = NULL;
  1040. *pADE = (AddressEntry *)AAE;
  1041. //
  1042. // Create the corresponding solicited-node
  1043. // multicast address MAE.
  1044. //
  1045. rc = FindOrCreateSolicitedNodeMAE(IF, Addr);
  1046. if (! rc) {
  1047. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1048. "FindOrCreateAAE: "
  1049. "FindOrCreateSolicitedNodeMAE failed\n"));
  1050. goto ErrorReturnFreeAAE;
  1051. }
  1052. //
  1053. // Create a loopback route for this address.
  1054. //
  1055. rc = ControlLoopback(IF, Addr, CONTROL_LOOPBACK_ENABLED);
  1056. if (! rc) {
  1057. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  1058. "FindOrCreateAAE: "
  1059. "ControlLoopback failed\n"));
  1060. FindAndReleaseSolicitedNodeMAE(IF, Addr);
  1061. ErrorReturnFreeAAE:
  1062. //
  1063. // An MAE may have been added & removed above,
  1064. // but at this point the AAE should be last.
  1065. //
  1066. ASSERT((*pADE == (AddressEntry *)AAE) && (AAE->Next == NULL));
  1067. *pADE = NULL;
  1068. ExFreePool(AAE);
  1069. ErrorReturn:
  1070. ;
  1071. }
  1072. }
  1073. else {
  1074. //
  1075. // The ADE already exists -
  1076. // just verify that it is anycast.
  1077. //
  1078. rc = (AAE->Type == ADE_ANYCAST);
  1079. }
  1080. if (IsMCastSyncNeeded(IF))
  1081. DeferSynchronizeMulticastAddresses(IF);
  1082. }
  1083. KeReleaseSpinLock(&IF->Lock, OldIrql);
  1084. return rc;
  1085. }
  1086. //* DeleteAAE
  1087. //
  1088. // Cleanup and delete an AAE.
  1089. // It is already removed from the interface's list.
  1090. //
  1091. // Called with the interface lock held.
  1092. //
  1093. void
  1094. DeleteAAE(Interface *IF, AnycastAddressEntry *AAE)
  1095. {
  1096. int rc;
  1097. //
  1098. // The corresponding solicited-node address is not needed.
  1099. //
  1100. FindAndReleaseSolicitedNodeMAE(IF, &AAE->Address);
  1101. //
  1102. // The loopback route is not needed.
  1103. //
  1104. rc = ControlLoopback(IF, &AAE->Address, CONTROL_LOOPBACK_DESTROY);
  1105. ASSERT(rc);
  1106. ExFreePool(AAE);
  1107. }
  1108. //* FindAndDeleteAAE
  1109. //
  1110. // Deletes an anycast address from the interface.
  1111. // Returns TRUE for success.
  1112. //
  1113. // Called with NO locks held.
  1114. // Callable from thread or DPC context.
  1115. //
  1116. int
  1117. FindAndDeleteAAE(Interface *IF, const IPv6Addr *Addr)
  1118. {
  1119. AddressEntry **pADE;
  1120. AnycastAddressEntry *AAE;
  1121. KIRQL OldIrql;
  1122. int rc;
  1123. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  1124. pADE = FindADE(IF, Addr);
  1125. AAE = (AnycastAddressEntry *) *pADE;
  1126. if (AAE != NULL) {
  1127. if (AAE->Type == ADE_ANYCAST) {
  1128. //
  1129. // Delete the AAE.
  1130. //
  1131. *pADE = AAE->Next;
  1132. DeleteAAE(IF, AAE);
  1133. rc = TRUE;
  1134. }
  1135. else {
  1136. //
  1137. // This is an error - it should be anycast.
  1138. //
  1139. rc = FALSE;
  1140. }
  1141. }
  1142. else {
  1143. //
  1144. // If the address already doesn't exist, then OK.
  1145. //
  1146. rc = TRUE;
  1147. }
  1148. if (IsMCastSyncNeeded(IF))
  1149. DeferSynchronizeMulticastAddresses(IF);
  1150. KeReleaseSpinLock(&IF->Lock, OldIrql);
  1151. return rc;
  1152. }
  1153. //* LeaveGroupAtAllScopes
  1154. //
  1155. // Leave a multicast group at all scopes.
  1156. // Called with the interface already locked.
  1157. //
  1158. void
  1159. LeaveGroupAtAllScopes(Interface *IF, IPv6Addr *GroupAddr, uint MaxScope)
  1160. {
  1161. IPv6Addr Address = *GroupAddr;
  1162. MulticastAddressEntry *MAE;
  1163. uint i;
  1164. for (i = 0;
  1165. ((i < sizeof MulticastScopes / sizeof MulticastScopes[0]) &&
  1166. (MulticastScopes[i] <= MaxScope));
  1167. i++) {
  1168. Address.s6_bytes[1] = ((Address.s6_bytes[1] & 0xf0) |
  1169. MulticastScopes[i]);
  1170. MAE = FindAndReleaseMAE(IF, &Address);
  1171. ASSERT(MAE != NULL);
  1172. }
  1173. }
  1174. //* JoinGroupAtAllScopes
  1175. //
  1176. // Join a multicast group at all scopes up to the specified scope.
  1177. // Returns TRUE for success.
  1178. // Called with the interface already locked.
  1179. //
  1180. int
  1181. JoinGroupAtAllScopes(Interface *IF, IPv6Addr *GroupAddr, uint MaxScope)
  1182. {
  1183. IPv6Addr Address = *GroupAddr;
  1184. MulticastAddressEntry *MAE;
  1185. uint i, j;
  1186. for (i = 0;
  1187. ((i < sizeof MulticastScopes / sizeof MulticastScopes[0]) &&
  1188. (MulticastScopes[i] <= MaxScope));
  1189. i++) {
  1190. Address.s6_bytes[1] = (Address.s6_bytes[1] & 0xf0) | MulticastScopes[i];
  1191. MAE = FindOrCreateMAE(IF, &Address, NULL);
  1192. if (MAE == NULL) {
  1193. //
  1194. // Failure. Leave the groups that we did manage to join.
  1195. //
  1196. if (i != 0)
  1197. LeaveGroupAtAllScopes(IF, GroupAddr, MulticastScopes[i-1]);
  1198. return FALSE;
  1199. }
  1200. }
  1201. return TRUE;
  1202. }
  1203. //* DestroyADEs
  1204. //
  1205. // Destroy all AddressEntries that reference an NTE.
  1206. //
  1207. // Called with the interface already locked.
  1208. //
  1209. // (Actually, we are at DPC level because we hold the interface lock.)
  1210. //
  1211. void
  1212. DestroyADEs(Interface *IF, NetTableEntry *NTE)
  1213. {
  1214. AddressEntry *AnycastList = NULL;
  1215. AddressEntry *ADE, **PrevADE;
  1216. PrevADE = &IF->ADE;
  1217. while ((ADE = *PrevADE) != NULL) {
  1218. if (ADE == (AddressEntry *)NTE) {
  1219. //
  1220. // Remove the NTE from the list but do not
  1221. // free the memory - that happens later.
  1222. //
  1223. *PrevADE = ADE->Next;
  1224. }
  1225. else if (ADE->NTE == NTE) {
  1226. //
  1227. // Remove this ADE because it references the NTE.
  1228. //
  1229. *PrevADE = ADE->Next;
  1230. switch (ADE->Type) {
  1231. case ADE_UNICAST:
  1232. ASSERTMSG("DestroyADEs: unicast ADE?\n", FALSE);
  1233. break;
  1234. case ADE_ANYCAST: {
  1235. //
  1236. // We can't call FindAndReleaseSolicitedNodeMAE here
  1237. // because it could mess up our list traversal.
  1238. // So put the ADE on our temporary list and do it later.
  1239. //
  1240. ADE->Next = AnycastList;
  1241. AnycastList = ADE;
  1242. break;
  1243. }
  1244. case ADE_MULTICAST: {
  1245. MulticastAddressEntry *MAE = (MulticastAddressEntry *) ADE;
  1246. DeleteMAE(IF, MAE);
  1247. break;
  1248. }
  1249. }
  1250. }
  1251. else {
  1252. if (ADE->Type == ADE_UNICAST) {
  1253. AnonNetTableEntry *AnonNTE = (AnonNetTableEntry *) ADE;
  1254. if ((AnonNTE->AddrConf == ADDR_CONF_ANONYMOUS) &&
  1255. (AnonNTE->Public == NTE)) {
  1256. //
  1257. // Break the public/anonymous association
  1258. // and invalidate the anonymous address.
  1259. // We can't use DestroyNTE directly here
  1260. // because it would mess up our traversal.
  1261. //
  1262. AnonNTE->Public = NULL;
  1263. AnonNTE->ValidLifetime = 0;
  1264. AnonNTE->PreferredLifetime = 0;
  1265. }
  1266. }
  1267. PrevADE = &ADE->Next;
  1268. }
  1269. }
  1270. //
  1271. // Now we can safely process the anycast ADEs.
  1272. //
  1273. while ((ADE = AnycastList) != NULL) {
  1274. AnycastList = ADE->Next;
  1275. DeleteAAE(IF, (AnycastAddressEntry *)ADE);
  1276. }
  1277. }
  1278. //* FindADE - find an ADE entry for the given interface.
  1279. //
  1280. // If the address is assigned to the interface,
  1281. // returns the address of the link pointing to the ADE.
  1282. // Otherwise returns a pointer to the link (currently NULL)
  1283. // where a new ADE should be added to extend the list.
  1284. //
  1285. // The caller must lock the IF before calling this function.
  1286. //
  1287. AddressEntry **
  1288. FindADE(
  1289. Interface *IF,
  1290. const IPv6Addr *Addr)
  1291. {
  1292. AddressEntry **pADE, *ADE;
  1293. //
  1294. // Check if address is assigned to the interface using the
  1295. // interface's ADE list.
  1296. //
  1297. // REVIEW: Change the ADE list to a more efficient data structure?
  1298. //
  1299. for (pADE = &IF->ADE; (ADE = *pADE) != NULL; pADE = &ADE->Next) {
  1300. if (IP6_ADDR_EQUAL(Addr, &ADE->Address))
  1301. break;
  1302. }
  1303. return pADE;
  1304. }
  1305. //* FindAddressOnInterface
  1306. //
  1307. // Looks for an ADE on the interface.
  1308. // If a unicast ADE is found, returns the ADE (an NTE) and ADE_UNICAST.
  1309. // If a multicast/anycast ADE is found, returns ADE->NTEorIF and ADE->Type.
  1310. // If an ADE is not found, returns the interface and ADE_NONE.
  1311. // Whether the interface or an NTE is returned,
  1312. // the return value (if non-NULL) holds a reference.
  1313. //
  1314. // Returns NULL only if the interface is disabled.
  1315. //
  1316. // In normal usage, callers should hold a reference
  1317. // for the interface. (So if the interface is returned,
  1318. // it is returned with a second reference.) But in some
  1319. // paths (for example IPv6Receive/IPv6HeaderReceive),
  1320. // the caller knows the interface exists but does not
  1321. // hold a reference for it.
  1322. //
  1323. // Callable from DPC context, not from thread context.
  1324. //
  1325. NetTableEntryOrInterface *
  1326. FindAddressOnInterface(
  1327. Interface *IF,
  1328. const IPv6Addr *Addr,
  1329. ushort *AddrType)
  1330. {
  1331. AddressEntry *ADE;
  1332. NetTableEntryOrInterface *NTEorIF;
  1333. KeAcquireSpinLockAtDpcLevel(&IF->Lock);
  1334. if (IsDisabledIF(IF)) {
  1335. NTEorIF = NULL;
  1336. }
  1337. else if ((ADE = *FindADE(IF, Addr)) != NULL) {
  1338. if ((*AddrType = ADE->Type) == ADE_UNICAST) {
  1339. NTEorIF = CastFromNTE((NetTableEntry *)ADE);
  1340. goto ReturnNTE;
  1341. }
  1342. else {
  1343. NTEorIF = ADE->NTEorIF;
  1344. if (IsNTE(NTEorIF))
  1345. ReturnNTE:
  1346. AddRefNTE(CastToNTE(NTEorIF));
  1347. else
  1348. goto ReturnIF;
  1349. }
  1350. }
  1351. else {
  1352. *AddrType = ADE_NONE;
  1353. NTEorIF = CastFromIF(IF);
  1354. ReturnIF:
  1355. AddRefIF(CastToIF(NTEorIF));
  1356. }
  1357. KeReleaseSpinLockFromDpcLevel(&IF->Lock);
  1358. return NTEorIF;
  1359. }
  1360. //
  1361. // We keep track of the number of outstanding
  1362. // register-net-address work items.
  1363. // (Using InterlockedIncrement/InterlockedDecrement.)
  1364. // This way we can wait in the IPUnload
  1365. // until they are all done.
  1366. //
  1367. ULONG OutstandingRegisterNetAddressCount = 0;
  1368. //
  1369. // Note that this structure wouldn't be needed if IoQueueWorkItem
  1370. // had been designed to call the user's routine with the WorkItem
  1371. // as an additional argument along with the DeviceObject and Context.
  1372. // Sigh.
  1373. //
  1374. typedef struct RegisterNetAddressContext {
  1375. PIO_WORKITEM WorkItem;
  1376. NetTableEntry *NTE;
  1377. } RegisterNetAddressContext;
  1378. //* RegisterNetAddressWorker - De/Registers an address with TDI.
  1379. //
  1380. // Worker function for calling TdiRegisterNetAddress.
  1381. //
  1382. // Called to register or deregister an address with TDI when any one of
  1383. // the following two events occur...
  1384. //
  1385. // 1. The corresponding NTE's DADState changes between valid/invalid
  1386. // states while its interface's media state is connected.
  1387. //
  1388. // 2. The corresponding NTE's interface media state changes between
  1389. // connected/disconnected while its DADState is DAD_STATE_PREFERRED.
  1390. // For this case, DisconnectADEs queues a worker on the connect to
  1391. // disconnect transition whereas on the reverse transition the worker
  1392. // is queued at the completion the duplicate address detection.
  1393. //
  1394. // Since TdiRegisterNetAddress must be called when running at
  1395. // IRQL < DISPATCH_LEVEL, we use this function via a worker thread.
  1396. //
  1397. // Called with a reference held on the NTE, which we release on exit.
  1398. //
  1399. void
  1400. RegisterNetAddressWorker(
  1401. PDEVICE_OBJECT DevObj, // Unused. Wish they passed the WorkItem instead.
  1402. PVOID Context) // A RegisterNetAddressContext struct.
  1403. {
  1404. RegisterNetAddressContext *MyContext = Context;
  1405. NetTableEntry *NTE = MyContext->NTE;
  1406. Interface *IF = NTE->IF;
  1407. int ShouldBeRegistered;
  1408. KIRQL OldIrql;
  1409. NTSTATUS Status;
  1410. IoFreeWorkItem(MyContext->WorkItem);
  1411. ExFreePool(MyContext);
  1412. //
  1413. // The heavy-weight WorkerLock protects this code against
  1414. // multiple instantiations of itself without raising IRQL.
  1415. //
  1416. KeWaitForSingleObject(&IF->WorkerLock, Executive, KernelMode,
  1417. FALSE, NULL);
  1418. //
  1419. // Figure out what state we should be in.
  1420. // Note that IF->Lock protects DADState and IF->Flags,
  1421. // while IF->WorkerLock protects TdiRegistrationHandle.
  1422. //
  1423. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  1424. //
  1425. // An address should be registered with TDI iff it is in the
  1426. // preferred DAD state and its corresponding interface is
  1427. // connected.
  1428. //
  1429. ShouldBeRegistered = ((NTE->DADState == DAD_STATE_PREFERRED) &&
  1430. !(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED));
  1431. KeReleaseSpinLock(&IF->Lock, OldIrql);
  1432. if (ShouldBeRegistered) {
  1433. if (NTE->TdiRegistrationHandle == NULL) {
  1434. char Buffer[sizeof(TA_ADDRESS) + TDI_ADDRESS_LENGTH_IP6 - 1];
  1435. PTA_ADDRESS TAAddress = (PTA_ADDRESS) Buffer;
  1436. PTDI_ADDRESS_IP6 TDIAddress =
  1437. (PTDI_ADDRESS_IP6) &TAAddress->Address;
  1438. //
  1439. // Create TAAddress from NTE->Address;
  1440. //
  1441. TAAddress->AddressLength = TDI_ADDRESS_LENGTH_IP6;
  1442. TAAddress->AddressType = TDI_ADDRESS_TYPE_IP6;
  1443. TDIAddress->sin6_port = 0;
  1444. TDIAddress->sin6_flowinfo = 0;
  1445. *(IPv6Addr *)&TDIAddress->sin6_addr = NTE->Address;
  1446. TDIAddress->sin6_scope_id = DetermineScopeId(&NTE->Address, IF);
  1447. Status = TdiRegisterNetAddress(TAAddress, &IF->DeviceName, NULL,
  1448. &NTE->TdiRegistrationHandle);
  1449. if (Status != STATUS_SUCCESS) {
  1450. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1451. "RegisterNetAddressWorker: "
  1452. "TdiRegisterNetAddress(%d/%s): %x\n",
  1453. IF->Index, FormatV6Address(&NTE->Address), Status));
  1454. //
  1455. // Due to a bug in TdiRegisterNetAddress, we can't be
  1456. // guaranteed the handle will be NULL on error.
  1457. //
  1458. NTE->TdiRegistrationHandle = NULL;
  1459. //
  1460. // REVIEW: Should we requeue ourselves for another attempt?
  1461. //
  1462. }
  1463. }
  1464. }
  1465. else { // if (! ShouldBeRegistered)
  1466. if (NTE->TdiRegistrationHandle != NULL) {
  1467. Status = TdiDeregisterNetAddress(NTE->TdiRegistrationHandle);
  1468. if (Status == STATUS_SUCCESS) {
  1469. NTE->TdiRegistrationHandle = NULL;
  1470. }
  1471. else {
  1472. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1473. "RegisterNetAddressWorker: "
  1474. "TdiDeregisterNetAddress(%d/%s): %x\n",
  1475. IF->Index, FormatV6Address(&NTE->Address), Status));
  1476. //
  1477. // REVIEW: Should we requeue ourselves for another attempt?
  1478. //
  1479. }
  1480. }
  1481. }
  1482. KeReleaseMutex(&IF->WorkerLock, FALSE);
  1483. ReleaseNTE(NTE);
  1484. InterlockedDecrement(&OutstandingRegisterNetAddressCount);
  1485. }
  1486. //* DeferRegisterNetAddress
  1487. //
  1488. // Queue a work item that will execute RegisterNetAddressWorker.
  1489. //
  1490. // Callable from thread or DPC context.
  1491. //
  1492. void
  1493. DeferRegisterNetAddress(
  1494. NetTableEntry *NTE) // NTE that needs work.
  1495. {
  1496. RegisterNetAddressContext *Context;
  1497. PIO_WORKITEM WorkItem;
  1498. Context = ExAllocatePool(NonPagedPool, sizeof *Context);
  1499. if (Context == NULL) {
  1500. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1501. "DeferRegisterNetAddress: ExAllocatePool failed\n"));
  1502. return;
  1503. }
  1504. WorkItem = IoAllocateWorkItem(IPDeviceObject);
  1505. if (WorkItem == NULL) {
  1506. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1507. "DeferRegisterNetAddress: IoAllocateWorkItem failed\n"));
  1508. ExFreePool(Context);
  1509. return;
  1510. }
  1511. Context->WorkItem = WorkItem;
  1512. AddRefNTE(NTE);
  1513. Context->NTE = NTE;
  1514. InterlockedIncrement(&OutstandingRegisterNetAddressCount);
  1515. IoQueueWorkItem(WorkItem, RegisterNetAddressWorker,
  1516. CriticalWorkQueue, Context);
  1517. }
  1518. //* AddrConfStartDAD
  1519. //
  1520. // Starts duplicate address detection for the address,
  1521. // unless DAD is disabled.
  1522. //
  1523. // Called with the interface locked.
  1524. //
  1525. void
  1526. AddrConfStartDAD(Interface *IF, NetTableEntry *NTE)
  1527. {
  1528. int rc;
  1529. if ((IF->DupAddrDetectTransmits == 0) ||
  1530. !(IF->Flags & IF_FLAG_NEIGHBOR_DISCOVERS) ||
  1531. ((NTE->AddrConf == ADDR_CONF_ANONYMOUS) &&
  1532. (MaxAnonDADAttempts == 0))) {
  1533. //
  1534. // Duplicate Address Detection is disabled,
  1535. // so go straight to a valid state
  1536. // if we aren't already valid.
  1537. //
  1538. AddrConfNotDuplicate(IF, NTE);
  1539. }
  1540. else {
  1541. //
  1542. // Initialize for DAD.
  1543. // Send first solicit at next IPv6Timeout.
  1544. //
  1545. NTE->DADCount = (ushort)IF->DupAddrDetectTransmits;
  1546. NTE->DADTimer = 1;
  1547. }
  1548. }
  1549. //* CreateNTE - Creates an NTE on an interface.
  1550. //
  1551. // Returns one reference for the caller.
  1552. //
  1553. // Callable from thread or DPC context.
  1554. // Called with the interface locked.
  1555. //
  1556. // (Actually, we are at DPC level because we hold the interface lock.)
  1557. //
  1558. NetTableEntry *
  1559. CreateNTE(Interface *IF, const IPv6Addr *Address, uint AddrConf,
  1560. uint ValidLifetime, uint PreferredLifetime)
  1561. {
  1562. uint Size;
  1563. NetTableEntry *NTE;
  1564. int rc;
  1565. //
  1566. // The address must not already be assigned.
  1567. //
  1568. ASSERT(*FindADE(IF, Address) == NULL);
  1569. //
  1570. // Can't create a new NTE if the interface is shutting down.
  1571. //
  1572. if (IsDisabledIF(IF))
  1573. goto ErrorExit;
  1574. //
  1575. // Anonymous addresses need extra fields,
  1576. // which are initialized by our caller.
  1577. //
  1578. if (AddrConf == ADDR_CONF_ANONYMOUS)
  1579. Size = sizeof(AnonNetTableEntry);
  1580. else
  1581. Size = sizeof(NetTableEntry);
  1582. NTE = ExAllocatePool(NonPagedPool, Size);
  1583. if (NTE == NULL)
  1584. goto ErrorExit;
  1585. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  1586. "CreateNTE(IF %u/%p, Addr %s) -> NTE %p\n",
  1587. IF->Index, IF, FormatV6Address(Address), NTE));
  1588. //
  1589. // Initialize the NTE with one reference for our caller.
  1590. // (EnlivenNTE may add a second reference for the interface.)
  1591. //
  1592. RtlZeroMemory(NTE, Size);
  1593. NTE->Address = *Address;
  1594. NTE->Type = ADE_UNICAST;
  1595. NTE->Scope = UnicastAddressScope(Address);
  1596. AddNTEToInterface(IF, NTE);
  1597. NTE->RefCnt = 1;
  1598. NTE->AddrConf = (uchar)AddrConf;
  1599. NTE->ValidLifetime = ValidLifetime;
  1600. NTE->PreferredLifetime = PreferredLifetime;
  1601. NTE->DADState = DAD_STATE_INVALID;
  1602. //
  1603. // Create a disabled loopback route.
  1604. // We pre-allocate the loopback RTE and NCE now,
  1605. // and then enable them later when the address is valid.
  1606. //
  1607. if (!ControlLoopback(IF, Address, CONTROL_LOOPBACK_DISABLED))
  1608. goto ErrorExitCleanup;
  1609. //
  1610. // Add this NTE to the front of the NetTableList.
  1611. //
  1612. KeAcquireSpinLockAtDpcLevel(&NetTableListLock);
  1613. AddNTEToNetTableList(NTE);
  1614. KeReleaseSpinLockFromDpcLevel(&NetTableListLock);
  1615. //
  1616. // If the NTE should be alive, make it so.
  1617. //
  1618. if (NTE->ValidLifetime != 0)
  1619. EnlivenNTE(IF, NTE);
  1620. return NTE;
  1621. ErrorExitCleanup:
  1622. RemoveNTEFromInterface(IF, NTE);
  1623. ASSERT(NTE->RefCnt == 1);
  1624. ExFreePool(NTE);
  1625. ErrorExit:
  1626. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  1627. "CreateNTE(IF %u/%p, Addr %s) -> NTE %p failed\n",
  1628. IF->Index, IF, FormatV6Address(Address), NTE));
  1629. return NULL;
  1630. }
  1631. //* InterfaceIndex
  1632. //
  1633. // Allocates the next interface index.
  1634. //
  1635. uint
  1636. InterfaceIndex(void)
  1637. {
  1638. return (uint) InterlockedIncrement((PULONG) &NextIFIndex);
  1639. }
  1640. //* AddInterface
  1641. //
  1642. // Add a new interface to the global list.
  1643. //
  1644. void
  1645. AddInterface(Interface *IF)
  1646. {
  1647. KIRQL OldIrql;
  1648. KeAcquireSpinLock(&IFListLock, &OldIrql);
  1649. IF->Next = IFList;
  1650. IFList = IF;
  1651. IPSInfo.ipsi_numif++;
  1652. KeReleaseSpinLock(&IFListLock, OldIrql);
  1653. }
  1654. //* CreateGUIDFromName
  1655. //
  1656. // Given the string name of an interface, creates a corresponding guid.
  1657. // The guid is a hash of the string name.
  1658. //
  1659. void
  1660. CreateGUIDFromName(const char *Name, GUID *Guid)
  1661. {
  1662. MD5_CTX Context;
  1663. MD5Init(&Context);
  1664. MD5Update(&Context, (uchar *)Name, strlen(Name));
  1665. MD5Final(&Context);
  1666. memcpy(Guid, Context.digest, MD5DIGESTLEN);
  1667. }
  1668. //* CreateInterface
  1669. //
  1670. // Creates an IPv6 interface given some link-layer information.
  1671. //
  1672. // If successful, returns a reference for the interface.
  1673. //
  1674. // Callable from thread context, not DPC context.
  1675. //
  1676. // Return codes:
  1677. // STATUS_UNSUCCESSFUL
  1678. // STATUS_SUCCESS
  1679. //
  1680. NTSTATUS
  1681. CreateInterface(const GUID *Guid, const LLIPBindInfo *BindInfo,
  1682. void **Context)
  1683. {
  1684. UNICODE_STRING GuidName;
  1685. Interface *IF; // Interface being added.
  1686. KIRQL OldIrql;
  1687. uint IFSize;
  1688. uint IFExportNamePrefixLen;
  1689. NTSTATUS Status;
  1690. ASSERT(KeGetCurrentIrql() == 0);
  1691. ASSERT(BindInfo->lip_addrlen <= MAX_LINK_LAYER_ADDRESS_LENGTH);
  1692. //
  1693. // Prevent new interfaces from being created
  1694. // while the stack is unloading.
  1695. //
  1696. if (Unloading)
  1697. goto ErrorExit;
  1698. //
  1699. // Before doing the real work, take advantage of the link-layer
  1700. // address passed up here to re-seed our random number generator.
  1701. //
  1702. SeedRandom(BindInfo->lip_addr, BindInfo->lip_addrlen);
  1703. //
  1704. // Convert the guid to string form.
  1705. // It will be null-terminated.
  1706. //
  1707. Status = RtlStringFromGUID(Guid, &GuidName);
  1708. if (! NT_SUCCESS(Status))
  1709. goto ErrorExit;
  1710. ASSERT(GuidName.MaximumLength == GuidName.Length + sizeof(WCHAR));
  1711. ASSERT(((WCHAR *)GuidName.Buffer)[GuidName.Length/sizeof(WCHAR)] == UNICODE_NULL);
  1712. //
  1713. // Allocate memory to hold an interface.
  1714. // We also allocate extra space to hold the device name string.
  1715. //
  1716. IFExportNamePrefixLen = sizeof IPV6_EXPORT_STRING_PREFIX - sizeof(WCHAR);
  1717. IFSize = sizeof *IF + IFExportNamePrefixLen + GuidName.MaximumLength;
  1718. IF = ExAllocatePool(NonPagedPool, IFSize);
  1719. if (IF == NULL)
  1720. goto ErrorExitCleanupGuidName;
  1721. RtlZeroMemory(IF, sizeof *IF);
  1722. IF->IF = IF;
  1723. IF->Index = InterfaceIndex();
  1724. IF->Guid = *Guid;
  1725. //
  1726. // Start with one reference because this is an active interface.
  1727. // And one reference for our caller.
  1728. //
  1729. IF->RefCnt = 2;
  1730. //
  1731. // Create the null-terminated exported device name from the guid.
  1732. //
  1733. IF->DeviceName.Buffer = (PVOID) (IF + 1);
  1734. IF->DeviceName.MaximumLength = (USHORT) (IFSize - sizeof *IF);
  1735. IF->DeviceName.Length = IF->DeviceName.MaximumLength - sizeof(WCHAR);
  1736. RtlCopyMemory(IF->DeviceName.Buffer,
  1737. IPV6_EXPORT_STRING_PREFIX,
  1738. IFExportNamePrefixLen);
  1739. RtlCopyMemory((uchar *) IF->DeviceName.Buffer + IFExportNamePrefixLen,
  1740. GuidName.Buffer,
  1741. GuidName.MaximumLength);
  1742. KeInitializeSpinLock(&IF->Lock);
  1743. IF->Type = BindInfo->lip_type;
  1744. IF->Flags = (BindInfo->lip_flags & IF_FLAGS_BINDINFO);
  1745. if (BindInfo->lip_context == NULL)
  1746. IF->LinkContext = IF;
  1747. else
  1748. IF->LinkContext = BindInfo->lip_context;
  1749. IF->Transmit = BindInfo->lip_transmit;
  1750. IF->CreateToken = BindInfo->lip_token;
  1751. IF->ReadLLOpt = BindInfo->lip_rdllopt;
  1752. IF->WriteLLOpt = BindInfo->lip_wrllopt;
  1753. IF->ConvertAddr = BindInfo->lip_cvaddr;
  1754. IF->SetRouterLLAddress = BindInfo->lip_setrtrlladdr;
  1755. IF->SetMCastAddrList = BindInfo->lip_mclist;
  1756. IF->Close = BindInfo->lip_close;
  1757. IF->Cleanup = BindInfo->lip_cleanup;
  1758. IF->LinkAddressLength = BindInfo->lip_addrlen;
  1759. IF->LinkAddress = BindInfo->lip_addr;
  1760. //
  1761. // We round-up the link-layer header size to a multiple of 2.
  1762. // This aligns the IPv6 header appropriately for IPv6Addr.
  1763. // When NDIS is fixed so we don't need AdjustPacketBuffer,
  1764. // we should align the IPv6 header to a multiple of 8.
  1765. //
  1766. IF->LinkHeaderSize = ALIGN_UP(BindInfo->lip_hdrsize, ushort);
  1767. IF->TrueLinkMTU = BindInfo->lip_maxmtu;
  1768. IF->DefaultLinkMTU = BindInfo->lip_defmtu;
  1769. IF->LinkMTU = BindInfo->lip_defmtu;
  1770. IF->DefaultPreference = BindInfo->lip_pref;
  1771. IF->Preference = BindInfo->lip_pref;
  1772. IF->BaseReachableTime = REACHABLE_TIME;
  1773. IF->ReachableTime = CalcReachableTime(IF->BaseReachableTime);
  1774. IF->RetransTimer = RETRANS_TIMER;
  1775. IF->DefaultDupAddrDetectTransmits = BindInfo->lip_dadxmit;
  1776. IF->DupAddrDetectTransmits = BindInfo->lip_dadxmit;
  1777. IF->CurHopLimit = DefaultCurHopLimit;
  1778. //
  1779. // Neighbor discovery requires multicast capability
  1780. //
  1781. ASSERT((IF->Flags & IF_FLAG_MULTICAST) ||
  1782. !(IF->Flags & IF_FLAG_NEIGHBOR_DISCOVERS));
  1783. //
  1784. // Router discovery requires either multicast capability,
  1785. // or a SetRouterLLAddress handler.
  1786. //
  1787. ASSERT((IF->Flags & IF_FLAG_MULTICAST) ||
  1788. (IF->SetRouterLLAddress != NULL) ||
  1789. !(IF->Flags & IF_FLAG_ROUTER_DISCOVERS));
  1790. //
  1791. // All interfaces are considered to be on different links
  1792. // but in the same site, until configured otherwise.
  1793. //
  1794. InitZoneIndices(IF);
  1795. NeighborCacheInit(IF);
  1796. //
  1797. // The worker lock serializes some heavy-weight
  1798. // calls to upper & lower layers.
  1799. //
  1800. KeInitializeMutex(&IF->WorkerLock, 0);
  1801. //
  1802. // We need to get APCs while holding WorkerLock,
  1803. // so that we can get IO completions
  1804. // for our TDI calls on 6over4 interfaces.
  1805. // This is not a security problem because
  1806. // only kernel worker threads use WorkerLock
  1807. // so they can't be suspended by the user.
  1808. //
  1809. IF->WorkerLock.ApcDisable = 0;
  1810. //
  1811. // Initialize some random state for anonymous addresses.
  1812. //
  1813. *(uint UNALIGNED *)&IF->AnonState = Random();
  1814. //
  1815. // Register this interface's device name with TDI.
  1816. // We need to do this before assigning any unicast addresses to this IF,
  1817. // and also before grabbing the lock (thus setting IRQL to DISPATCH_LEVEL).
  1818. //
  1819. Status = TdiRegisterDeviceObject(&IF->DeviceName,
  1820. &IF->TdiRegistrationHandle);
  1821. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  1822. "CreateInterface(IF %u/%p): %ls -> %x\n",
  1823. IF->Index, IF,
  1824. IF->DeviceName.Buffer,
  1825. Status));
  1826. if (Status != STATUS_SUCCESS)
  1827. goto ErrorExitCleanupIF;
  1828. //
  1829. // After this point, we either return successfully
  1830. // or cleanup via ErrorExitDestroyIF.
  1831. //
  1832. RtlFreeUnicodeString(&GuidName);
  1833. //
  1834. // Return the new Interface to our caller now.
  1835. // This makes it available to the link-layer when
  1836. // we call CreateToken etc, before CreateInterface returns.
  1837. //
  1838. *Context = IF;
  1839. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  1840. if (IF->Flags & IF_FLAG_ROUTER_DISCOVERS) {
  1841. //
  1842. // Join the all-nodes multicast groups.
  1843. //
  1844. if (! JoinGroupAtAllScopes(IF, &AllNodesOnLinkAddr,
  1845. ADE_LINK_LOCAL))
  1846. goto ErrorExitDestroyIF;
  1847. if (IF->Flags & IF_FLAG_ADVERTISES) {
  1848. //
  1849. // Join the all-routers multicast groups.
  1850. //
  1851. if (! JoinGroupAtAllScopes(IF, &AllRoutersOnLinkAddr,
  1852. ADE_SITE_LOCAL))
  1853. goto ErrorExitDestroyIF;
  1854. //
  1855. // Start sending Router Advertisements.
  1856. //
  1857. IF->RATimer = 1;
  1858. IF->RACount = MAX_INITIAL_RTR_ADVERTISEMENTS;
  1859. }
  1860. else {
  1861. //
  1862. // Start sending Router Solicitations.
  1863. // The first RS will have the required random delay,
  1864. // because we randomize when IPv6Timeout first fires.
  1865. //
  1866. IF->RSTimer = 1;
  1867. }
  1868. }
  1869. //
  1870. // Initialize RALast to a value safely in the past,
  1871. // so that when/if this interface first sends an RA
  1872. // it is not inhibited due to rate-limiting.
  1873. //
  1874. IF->RALast = IPv6TickCount - MIN_DELAY_BETWEEN_RAS;
  1875. if (IF->Flags & IF_FLAG_FORWARDS)
  1876. InterlockedIncrement(&NumForwardingInterfaces);
  1877. if (IF->CreateToken != NULL) {
  1878. IPv6Addr Address;
  1879. NetTableEntry *NTE;
  1880. //
  1881. // Create a link-local address for this interface.
  1882. // Other addresses will be created later via stateless
  1883. // auto-configuration.
  1884. //
  1885. Address = LinkLocalPrefix;
  1886. (*IF->CreateToken)(IF->LinkContext, &Address);
  1887. NTE = CreateNTE(IF, &Address, ADDR_CONF_LINK,
  1888. INFINITE_LIFETIME, INFINITE_LIFETIME);
  1889. if (NTE == NULL)
  1890. goto ErrorExitDestroyIF;
  1891. //
  1892. // The LinkLocalNTE field does not hold a reference.
  1893. //
  1894. IF->LinkLocalNTE = NTE;
  1895. ReleaseNTE(NTE);
  1896. }
  1897. KeReleaseSpinLock(&IF->Lock, OldIrql);
  1898. //
  1899. // Configure the interface from the registry.
  1900. //
  1901. ConfigureInterface(IF);
  1902. //
  1903. // Add ourselves to the front of the global interface list.
  1904. // This is done last so the interface is fully initialized
  1905. // when it shows up on the list.
  1906. //
  1907. AddInterface(IF);
  1908. //
  1909. // If the interface is multicast enabled, create a multicast route.
  1910. //
  1911. if (IF->Flags & IF_FLAG_MULTICAST) {
  1912. RouteTableUpdate(NULL, // System update.
  1913. IF, NULL,
  1914. &MulticastPrefix, 8, 0,
  1915. INFINITE_LIFETIME, INFINITE_LIFETIME,
  1916. ROUTE_PREF_ON_LINK,
  1917. RTE_TYPE_SYSTEM,
  1918. FALSE, FALSE);
  1919. }
  1920. //
  1921. // Has the IPv6 timer been started yet?
  1922. // Don't start it until the new interface
  1923. // is ready for IPv6Timeout processing.
  1924. // Wait until we've gotten a real seed
  1925. // for the random number generator.
  1926. //
  1927. if ((IF->LinkAddressLength != 0) &&
  1928. !(IF->Flags & IF_FLAG_PSEUDO) &&
  1929. (InterlockedExchange((LONG *)&IPv6TimerStarted, TRUE) == FALSE)) {
  1930. LARGE_INTEGER Time;
  1931. uint InitialWakeUp;
  1932. //
  1933. // Start the timer with an initial relative expiration time and
  1934. // also a recurring period. The initial expiration time is
  1935. // negative (to indicate a relative time), and in 100ns units, so
  1936. // we first have to do some conversions. The initial expiration
  1937. // time is randomized to help prevent synchronization between
  1938. // different machines.
  1939. //
  1940. // This randomization uses IPv6_TIMEOUT instead of
  1941. // MAX_RTR_SOLICITATION_DELAY because the RS for a subsequent
  1942. // interface will be sent with a maximum delay of IPv6_TIMEOUT,
  1943. // depending on when the interface is created relative to IPv6Timeout.
  1944. //
  1945. InitialWakeUp = RandomNumber(0, IPv6_TIMEOUT * 10000);
  1946. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  1947. "IPv6: InitialWakeUp = %u\n", InitialWakeUp));
  1948. Time.QuadPart = - (LONGLONG) InitialWakeUp;
  1949. KeSetTimerEx(&IPv6Timer, Time, IPv6_TIMEOUT, &IPv6TimeoutDpc);
  1950. }
  1951. if (IsMCastSyncNeeded(IF))
  1952. DeferSynchronizeMulticastAddresses(IF);
  1953. return STATUS_SUCCESS;
  1954. ErrorExitDestroyIF:
  1955. //
  1956. // Prevent calls down to the link layer,
  1957. // since our return code notifies the link layer
  1958. // synchronously that it should clean up.
  1959. //
  1960. IF->Close = NULL;
  1961. IF->Cleanup = NULL;
  1962. IF->SetMCastAddrList = NULL;
  1963. KeReleaseSpinLock(&IF->Lock, OldIrql);
  1964. //
  1965. // Destroy the interface.
  1966. // This will cleanup address and routes.
  1967. // Then add the disabled interface to the list
  1968. // so InterfaceCleanup can find it after
  1969. // we release the last reference.
  1970. //
  1971. DestroyIF(IF);
  1972. AddInterface(IF);
  1973. ReleaseIF(IF);
  1974. goto ErrorExit;
  1975. ErrorExitCleanupIF:
  1976. //
  1977. // The interface has not been registered with TDI
  1978. // and there are no addresses, routes, etc.
  1979. // So we can just free it.
  1980. //
  1981. ASSERT(IF->RefCnt == 2);
  1982. ExFreePool(IF);
  1983. ErrorExitCleanupGuidName:
  1984. RtlFreeUnicodeString(&GuidName);
  1985. ErrorExit:
  1986. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  1987. "CreateInterface(IF %p) failed\n", IF));
  1988. return STATUS_UNSUCCESSFUL;
  1989. }
  1990. //
  1991. // We keep track of the number of outstanding
  1992. // deregister-interface work items.
  1993. // (Using InterlockedIncrement/InterlockedDecrement.)
  1994. // This way we can wait in the IPUnload
  1995. // until they are all done.
  1996. //
  1997. ULONG OutstandingDeregisterInterfaceCount = 0;
  1998. //
  1999. // Note that this structure wouldn't be needed if IoQueueWorkItem
  2000. // had been designed to call the user's routine with the WorkItem
  2001. // as an additional argument along with the DeviceObject and Context.
  2002. // Sigh.
  2003. //
  2004. typedef struct DeregisterInterfaceContext {
  2005. PIO_WORKITEM WorkItem;
  2006. Interface *IF;
  2007. } DeregisterInterfaceContext;
  2008. //* DeregisterInterfaceWorker - De/Registers an address with TDI.
  2009. //
  2010. // Worker function for calling TdiDeregisterDeviceObject.
  2011. // This is the last thing we do with the interface structure,
  2012. // so this routine also frees the interface.
  2013. // It has no references at this point.
  2014. //
  2015. void
  2016. DeregisterInterfaceWorker(
  2017. PDEVICE_OBJECT DevObj, // Unused. Wish they passed the WorkItem instead.
  2018. PVOID Context) // A DeregisterInterfaceContext struct.
  2019. {
  2020. DeregisterInterfaceContext *MyContext = Context;
  2021. Interface *IF = MyContext->IF;
  2022. NTSTATUS Status;
  2023. IoFreeWorkItem(MyContext->WorkItem);
  2024. ExFreePool(MyContext);
  2025. //
  2026. // Deregister the interface with TDI, if it was registered.
  2027. // The loopback interface is not registered.
  2028. //
  2029. if (IF->TdiRegistrationHandle != NULL) {
  2030. Status = TdiDeregisterDeviceObject(IF->TdiRegistrationHandle);
  2031. if (Status != STATUS_SUCCESS)
  2032. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2033. "DeregisterInterfaceContext: "
  2034. "TdiDeregisterDeviceObject: %x\n", Status));
  2035. }
  2036. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  2037. "DeregisterInterfaceWorker(IF %u/%p) -> freed\n", IF->Index, IF));
  2038. //
  2039. // Perform final cleanup of the link-layer data structures.
  2040. //
  2041. if (IF->Cleanup != NULL)
  2042. (*IF->Cleanup)(IF->LinkContext);
  2043. ExFreePool(IF);
  2044. //
  2045. // Note that we've finished our cleanup.
  2046. //
  2047. InterlockedDecrement(&OutstandingDeregisterInterfaceCount);
  2048. }
  2049. //* DeferDeregisterInterface
  2050. //
  2051. // Queue a work item that will execute DeregisterInterfaceWorker.
  2052. //
  2053. // Callable from thread or DPC context.
  2054. //
  2055. void
  2056. DeferDeregisterInterface(
  2057. Interface *IF)
  2058. {
  2059. DeregisterInterfaceContext *Context;
  2060. PIO_WORKITEM WorkItem;
  2061. Context = ExAllocatePool(NonPagedPool, sizeof *Context);
  2062. if (Context == NULL) {
  2063. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2064. "DeferDeregisterInterface: ExAllocatePool failed\n"));
  2065. return;
  2066. }
  2067. WorkItem = IoAllocateWorkItem(IPDeviceObject);
  2068. if (WorkItem == NULL) {
  2069. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2070. "DeferDeregisterInterface: IoAllocateWorkItem failed\n"));
  2071. ExFreePool(Context);
  2072. return;
  2073. }
  2074. Context->WorkItem = WorkItem;
  2075. Context->IF = IF;
  2076. InterlockedIncrement(&OutstandingDeregisterInterfaceCount);
  2077. IoQueueWorkItem(WorkItem, DeregisterInterfaceWorker,
  2078. CriticalWorkQueue, Context);
  2079. }
  2080. //* DestroyIF
  2081. //
  2082. // Shuts down an interface, making the interface effectively disappear.
  2083. // The interface will actually be freed when its last ref is gone.
  2084. //
  2085. // Callable from thread context, not DPC context.
  2086. // Called with NO locks held.
  2087. //
  2088. void
  2089. DestroyIF(Interface *IF)
  2090. {
  2091. AddressEntry *ADE;
  2092. int WasDisabled;
  2093. KIRQL OldIrql;
  2094. //
  2095. // First things first: disable the interface.
  2096. // If it's already disabled, we're done.
  2097. //
  2098. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  2099. ASSERT(OldIrql == 0);
  2100. KeAcquireSpinLockAtDpcLevel(&IFListLock);
  2101. WasDisabled = IF->Flags & IF_FLAG_DISABLED;
  2102. IF->Flags |= IF_FLAG_DISABLED;
  2103. KeReleaseSpinLockFromDpcLevel(&IFListLock);
  2104. if (WasDisabled) {
  2105. KeReleaseSpinLock(&IF->Lock, OldIrql);
  2106. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  2107. "DestroyIF(IF %u/%p) - already disabled?\n",
  2108. IF->Index, IF));
  2109. return;
  2110. }
  2111. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  2112. "DestroyIF(IF %u/%p) -> disabled\n",
  2113. IF->Index, IF));
  2114. //
  2115. // Stop generating Router Solicitations and Advertisements.
  2116. //
  2117. IF->RSTimer = IF->RATimer = 0;
  2118. //
  2119. // If the interface is currently forwarding,
  2120. // disable forwarding.
  2121. //
  2122. InterfaceStopForwarding(IF);
  2123. //
  2124. // Destroy all the ADEs. Because the interface is disabled,
  2125. // new ADEs will not subsequently be created.
  2126. //
  2127. while ((ADE = IF->ADE) != NULL) {
  2128. //
  2129. // First, remove this ADE from the interface.
  2130. //
  2131. IF->ADE = ADE->Next;
  2132. switch (ADE->Type) {
  2133. case ADE_UNICAST: {
  2134. NetTableEntry *NTE = (NetTableEntry *) ADE;
  2135. DestroyNTE(IF, NTE);
  2136. break;
  2137. }
  2138. case ADE_ANYCAST: {
  2139. AnycastAddressEntry *AAE = (AnycastAddressEntry *) ADE;
  2140. DeleteAAE(IF, AAE);
  2141. break;
  2142. }
  2143. case ADE_MULTICAST: {
  2144. MulticastAddressEntry *MAE = (MulticastAddressEntry *) ADE;
  2145. DeleteMAE(IF, MAE);
  2146. break;
  2147. }
  2148. }
  2149. }
  2150. KeReleaseSpinLock(&IF->Lock, OldIrql);
  2151. //
  2152. // Shutdown the link-layer.
  2153. //
  2154. if (IF->Close != NULL)
  2155. (*IF->Close)(IF->LinkContext);
  2156. //
  2157. // Clean up routing associated with the interface.
  2158. //
  2159. RouteTableRemove(IF);
  2160. //
  2161. // Clean up reassembly buffers associated with the interface.
  2162. //
  2163. ReassemblyRemove(IF);
  2164. //
  2165. // Clean up upper-layer state associated with the interface.
  2166. //
  2167. TCPRemoveIF(IF);
  2168. //
  2169. // Release the reference that the interface
  2170. // held for itself by virtue of being active.
  2171. //
  2172. ReleaseIF(IF);
  2173. //
  2174. // At this point, any NTEs still exist
  2175. // and hold references for the interface.
  2176. // The next calls to NetTableCleanup
  2177. // and InterfaceCleanup will finish the cleanup.
  2178. //
  2179. }
  2180. //* DestroyInterface
  2181. //
  2182. // Called from a link layer to destroy an interface.
  2183. //
  2184. // May be called when the interface has zero references
  2185. // and is already being destroyed.
  2186. //
  2187. void
  2188. DestroyInterface(void *Context)
  2189. {
  2190. Interface *IF = (Interface *) Context;
  2191. DestroyIF(IF);
  2192. }
  2193. //* ReleaseInterface
  2194. //
  2195. // Called from the link-layer to release its reference
  2196. // for the interface.
  2197. //
  2198. void
  2199. ReleaseInterface(void *Context)
  2200. {
  2201. Interface *IF = (Interface *) Context;
  2202. ReleaseIF(IF);
  2203. }
  2204. //* UpdateLinkMTU
  2205. //
  2206. // Update the link's MTU, either because of administrative configuration
  2207. // or autoconfiguration from a Router Advertisement.
  2208. //
  2209. // Callable from thread or DPC context.
  2210. // Called with NO locks held.
  2211. //
  2212. void
  2213. UpdateLinkMTU(Interface *IF, uint MTU)
  2214. {
  2215. KIRQL OldIrql;
  2216. ASSERT((IPv6_MINIMUM_MTU <= MTU) && (MTU <= IF->TrueLinkMTU));
  2217. //
  2218. // If the interface is advertising, then it should
  2219. // send a new RA promptly because the RAs contain the MTU option.
  2220. // This is what really needs the lock and the IsDisabledIF check.
  2221. //
  2222. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  2223. if ((IF->LinkMTU != MTU) && !IsDisabledIF(IF)) {
  2224. IF->LinkMTU = MTU;
  2225. if (IF->Flags & IF_FLAG_ADVERTISES) {
  2226. //
  2227. // Send a Router Advertisement very soon.
  2228. //
  2229. IF->RATimer = 1;
  2230. }
  2231. }
  2232. KeReleaseSpinLock(&IF->Lock, OldIrql);
  2233. }
  2234. //* FindInterfaceFromIndex
  2235. //
  2236. // Given the index of an interface, finds the interface.
  2237. // Returns a reference for the interface, or
  2238. // returns NULL if no valid interface is found.
  2239. //
  2240. // Callable from thread or DPC context.
  2241. //
  2242. Interface *
  2243. FindInterfaceFromIndex(uint Index)
  2244. {
  2245. Interface *IF;
  2246. KIRQL OldIrql;
  2247. KeAcquireSpinLock(&IFListLock, &OldIrql);
  2248. for (IF = IFList; IF != NULL; IF = IF->Next) {
  2249. if (IF->Index == Index) {
  2250. //
  2251. // Fail to find disabled interfaces.
  2252. //
  2253. if (IsDisabledIF(IF))
  2254. IF = NULL;
  2255. else
  2256. AddRefIF(IF);
  2257. break;
  2258. }
  2259. }
  2260. KeReleaseSpinLock(&IFListLock, OldIrql);
  2261. return IF;
  2262. }
  2263. //* FindInterfaceFromGuid
  2264. //
  2265. // Given the guid of an interface, finds the interface.
  2266. // Returns a reference for the interface, or
  2267. // returns NULL if no valid interface is found.
  2268. //
  2269. // Callable from thread or DPC context.
  2270. //
  2271. Interface *
  2272. FindInterfaceFromGuid(const GUID *Guid)
  2273. {
  2274. Interface *IF;
  2275. KIRQL OldIrql;
  2276. KeAcquireSpinLock(&IFListLock, &OldIrql);
  2277. for (IF = IFList; IF != NULL; IF = IF->Next) {
  2278. if (RtlCompareMemory(&IF->Guid, Guid, sizeof(GUID)) == sizeof(GUID)) {
  2279. //
  2280. // Fail to find disabled interfaces.
  2281. //
  2282. if (IsDisabledIF(IF))
  2283. IF = NULL;
  2284. else
  2285. AddRefIF(IF);
  2286. break;
  2287. }
  2288. }
  2289. KeReleaseSpinLock(&IFListLock, OldIrql);
  2290. return IF;
  2291. }
  2292. //* FindNextInterface
  2293. //
  2294. // Returns the next valid (not disabled) interface.
  2295. // If the argument is NULL, returns the first valid interface.
  2296. // Returns NULL if there is no next valid interface.
  2297. //
  2298. // Callable from thread or DPC context.
  2299. //
  2300. Interface *
  2301. FindNextInterface(Interface *IF)
  2302. {
  2303. KIRQL OldIrql;
  2304. KeAcquireSpinLock(&IFListLock, &OldIrql);
  2305. if (IF == NULL)
  2306. IF = IFList;
  2307. else
  2308. IF = IF->Next;
  2309. for (; IF != NULL; IF = IF->Next) {
  2310. if (! IsDisabledIF(IF)) {
  2311. AddRefIF(IF);
  2312. break;
  2313. }
  2314. }
  2315. KeReleaseSpinLock(&IFListLock, OldIrql);
  2316. return IF;
  2317. }
  2318. //* FindInterfaceFromZone
  2319. //
  2320. // Given a scope level and a zone index, finds an interface
  2321. // belonging to the specified zone. The interface
  2322. // must be different than the specified OrigIf.
  2323. //
  2324. // Called with the global ZoneUpdateLock lock held.
  2325. // (So we are at DPC level.)
  2326. //
  2327. Interface *
  2328. FindInterfaceFromZone(Interface *OrigIF, uint Scope, uint Index)
  2329. {
  2330. Interface *IF;
  2331. KeAcquireSpinLockAtDpcLevel(&IFListLock);
  2332. for (IF = IFList; IF != NULL; IF = IF->Next) {
  2333. if ((IF != OrigIF) &&
  2334. !IsDisabledIF(IF) &&
  2335. (IF->ZoneIndices[Scope] == Index)) {
  2336. AddRefIF(IF);
  2337. break;
  2338. }
  2339. }
  2340. KeReleaseSpinLockFromDpcLevel(&IFListLock);
  2341. return IF;
  2342. }
  2343. //* FindNewZoneIndex
  2344. //
  2345. // This is a helper function for CheckZoneIndices.
  2346. //
  2347. // Given a scope level, finds an unused zone index
  2348. // for use at that scope level.
  2349. // We return the value one more than the largest
  2350. // value currently in use.
  2351. //
  2352. // Called with the global ZoneUpdateLock lock held.
  2353. // Called from DPC context.
  2354. //
  2355. uint
  2356. FindNewZoneIndex(uint Scope)
  2357. {
  2358. Interface *IF;
  2359. uint ZoneIndex = 1;
  2360. KeAcquireSpinLockAtDpcLevel(&IFListLock);
  2361. for (IF = IFList; IF != NULL; IF = IF->Next) {
  2362. if (!IsDisabledIF(IF)) {
  2363. if (ZoneIndex <= IF->ZoneIndices[Scope])
  2364. ZoneIndex = IF->ZoneIndices[Scope] + 1;
  2365. }
  2366. }
  2367. KeReleaseSpinLockFromDpcLevel(&IFListLock);
  2368. return ZoneIndex;
  2369. }
  2370. //* InitZoneIndices
  2371. //
  2372. // Initializes the interface's zone indices to default values.
  2373. //
  2374. void
  2375. InitZoneIndices(Interface *IF)
  2376. {
  2377. ushort Scope;
  2378. IF->ZoneIndices[ADE_SMALLEST_SCOPE] = IF->Index;
  2379. IF->ZoneIndices[ADE_INTERFACE_LOCAL] = IF->Index;
  2380. IF->ZoneIndices[ADE_LINK_LOCAL] = IF->Index;
  2381. for (Scope = ADE_LINK_LOCAL + 1; Scope <= ADE_LARGEST_SCOPE; Scope++)
  2382. IF->ZoneIndices[Scope] = 1;
  2383. }
  2384. //* FindDefaultInterfaceForZone
  2385. //
  2386. // Given a scope level and a zone index, finds the default interface
  2387. // belonging to the specified zone. The default interface
  2388. // is the one that we assume destinations in the zone
  2389. // are on-link to, if there are no routes matching the destination.
  2390. //
  2391. // It is an error for the zone index to be zero, unless
  2392. // all our interfaces are in the same zone at that scope level.
  2393. // In which case zero (meaning unspecified) is actually not ambiguous.
  2394. //
  2395. // Return codes:
  2396. // IP_DEST_NO_ROUTE Unused at the moment, but can be used
  2397. // to mean that ScopeId is valid but we can not choose
  2398. // a default interface.
  2399. // IP_PARAMETER_PROBLEM ScopeId is invalid.
  2400. //
  2401. // ScopeIF is returned as NULL upon failure,
  2402. // and with a reference upon success.
  2403. //
  2404. // Upon success, ReturnConstrained indicates whether a zero ScopeId
  2405. // argument would have resulted in the same value for ScopeIF.
  2406. // RCE_FLAG_CONSTRAINED_SCOPEID Non-zero ScopeId was necessary.
  2407. // 0 Zero ScopeId would be the same.
  2408. //
  2409. // Called with the route cache lock held.
  2410. // (So we are at DPC level.)
  2411. //
  2412. IP_STATUS
  2413. FindDefaultInterfaceForZone(
  2414. uint Scope,
  2415. uint ScopeId,
  2416. Interface **ScopeIF,
  2417. ushort *ReturnConstrained)
  2418. {
  2419. Interface *FirstIF;
  2420. Interface *FoundIF;
  2421. Interface *IF;
  2422. IP_STATUS Status;
  2423. ushort Constrained;
  2424. //
  2425. // Start by assuming the ScopeId is invalid.
  2426. // We will return this status value
  2427. // if we find no interface with the specified ScopeId,
  2428. // or if ScopeId is zero and that is ambiguous.
  2429. //
  2430. Status = IP_PARAMETER_PROBLEM;
  2431. Constrained = 0;
  2432. FoundIF = NULL;
  2433. FirstIF = NULL;
  2434. KeAcquireSpinLockAtDpcLevel(&IFListLock);
  2435. for (IF = IFList; IF != NULL; IF = IF->Next) {
  2436. if (!IsDisabledIF(IF)) {
  2437. //
  2438. // Do we have interfaces in two zones at this scope level?
  2439. //
  2440. if (FirstIF == NULL) {
  2441. FirstIF = IF;
  2442. }
  2443. else if (IF->ZoneIndices[Scope] != FirstIF->ZoneIndices[Scope]) {
  2444. if (ScopeId == 0) {
  2445. //
  2446. // Stop now with an error.
  2447. //
  2448. ASSERT(FoundIF != NULL);
  2449. ReleaseIF(FoundIF);
  2450. FoundIF = NULL;
  2451. Status = IP_PARAMETER_PROBLEM;
  2452. break;
  2453. }
  2454. else {
  2455. //
  2456. // If ScopeId were zero, we would be returning an error
  2457. // instead of finding an interface. So the ScopeId value
  2458. // is constraining the result.
  2459. //
  2460. Constrained = RCE_FLAG_CONSTRAINED_SCOPEID;
  2461. }
  2462. }
  2463. //
  2464. // Can we potentially use this interface?
  2465. //
  2466. if ((ScopeId == 0) ||
  2467. (IF->ZoneIndices[Scope] == ScopeId)) {
  2468. if (FoundIF == NULL) {
  2469. Status = IP_SUCCESS;
  2470. FoundInterface:
  2471. AddRefIF(IF);
  2472. FoundIF = IF;
  2473. }
  2474. else {
  2475. //
  2476. // Is this new interface better than the previous one?
  2477. //
  2478. if (IF->Preference < FoundIF->Preference) {
  2479. ReleaseIF(FoundIF);
  2480. goto FoundInterface;
  2481. }
  2482. }
  2483. }
  2484. }
  2485. }
  2486. KeReleaseSpinLockFromDpcLevel(&IFListLock);
  2487. *ScopeIF = FoundIF;
  2488. *ReturnConstrained = Constrained;
  2489. return Status;
  2490. }
  2491. #pragma BEGIN_INIT
  2492. //* IPInit - Initialize ourselves.
  2493. //
  2494. // This routine is called during initialization from the OS-specific
  2495. // init code.
  2496. //
  2497. int // Returns: 0 if initialization failed, non-zero if it succeeds.
  2498. IPInit(void)
  2499. {
  2500. NDIS_STATUS Status;
  2501. LARGE_INTEGER Now;
  2502. ASSERT(ConvertSecondsToTicks(0) == 0);
  2503. ASSERT(ConvertSecondsToTicks(INFINITE_LIFETIME) == INFINITE_LIFETIME);
  2504. ASSERT(ConvertSecondsToTicks(1) == IPv6_TICKS_SECOND);
  2505. ASSERT(ConvertTicksToSeconds(0) == 0);
  2506. ASSERT(ConvertTicksToSeconds(IPv6_TICKS_SECOND) == 1);
  2507. ASSERT(ConvertTicksToSeconds(INFINITE_LIFETIME) == INFINITE_LIFETIME);
  2508. ASSERT(ConvertMillisToTicks(1000) == IPv6_TICKS_SECOND);
  2509. ASSERT(ConvertMillisToTicks(1) > 0);
  2510. KeInitializeSpinLock(&NetTableListLock);
  2511. KeInitializeSpinLock(&IFListLock);
  2512. KeInitializeSpinLock(&ZoneUpdateLock);
  2513. //
  2514. // Prepare our periodic timer and its associated DPC object.
  2515. //
  2516. // When the timer expires, the IPv6Timeout deferred procedure
  2517. // call (DPC) is queued. Everything we need to do at some
  2518. // specific frequency is driven off of this routine.
  2519. //
  2520. // We don't actually start the timer until an interface
  2521. // is created. We need random seed info from the interface.
  2522. // Plus there's no point in the overhead unless there are interfaces.
  2523. //
  2524. KeInitializeDpc(&IPv6TimeoutDpc, IPv6Timeout, NULL); // No parameter.
  2525. KeInitializeTimer(&IPv6Timer);
  2526. //
  2527. // Perform initial seed of our random number generator using
  2528. // low bits of a high-precision time-since-boot. Since this isn't
  2529. // the greatest seed (having just booted it won't vary much), we later
  2530. // use bits from our link-layer addresses as we discover them.
  2531. //
  2532. Now = KeQueryPerformanceCounter(NULL);
  2533. SeedRandom((uchar *)&Now, sizeof Now);
  2534. // Initialize the ProtocolSwitchTable.
  2535. ProtoTabInit();
  2536. //
  2537. // Create Packet and Buffer pools for IPv6.
  2538. //
  2539. switch (MmQuerySystemSize()) {
  2540. case MmSmallSystem:
  2541. PacketPoolSize = SMALL_POOL;
  2542. break;
  2543. case MmMediumSystem:
  2544. PacketPoolSize = MEDIUM_POOL;
  2545. break;
  2546. case MmLargeSystem:
  2547. default:
  2548. PacketPoolSize = LARGE_POOL;
  2549. break;
  2550. }
  2551. NdisAllocatePacketPool(&Status, &IPv6PacketPool,
  2552. PacketPoolSize, sizeof(Packet6Context));
  2553. if (Status != NDIS_STATUS_SUCCESS)
  2554. return FALSE;
  2555. //
  2556. // Currently, the size we pass to NdisAllocateBufferPool is ignored.
  2557. //
  2558. NdisAllocateBufferPool(&Status, &IPv6BufferPool, PacketPoolSize);
  2559. if (Status != NDIS_STATUS_SUCCESS)
  2560. return FALSE;
  2561. ReassemblyInit();
  2562. ICMPv6Init();
  2563. if (!IPSecInit())
  2564. return FALSE;
  2565. //
  2566. // Start the routing module
  2567. //
  2568. InitRouting();
  2569. InitSelect();
  2570. //
  2571. // The IPv6 timer is initialized in CreateInterface,
  2572. // when the first real interface is created.
  2573. // The calls below will start creating interfaces;
  2574. // our data structures should all be initialized now.
  2575. //
  2576. //
  2577. // First create the loopback interface,
  2578. // so it will be interface 1.
  2579. //
  2580. if (!LoopbackInit())
  2581. return FALSE; // Couldn't initialize loopback.
  2582. //
  2583. // Second create the tunnel interface,
  2584. // so it will be interface 2.
  2585. // This can also result in 6over4 interfaces.
  2586. //
  2587. if (!TunnelInit())
  2588. return FALSE; // Couldn't initialize tunneling.
  2589. //
  2590. // Finally initialize with ndis,
  2591. // so ethernet interfaces can be created.
  2592. //
  2593. if (!LanInit())
  2594. return FALSE; // Couldn't initialize with ndis.
  2595. return TRUE;
  2596. }
  2597. #pragma END_INIT
  2598. //* IPUnload
  2599. //
  2600. // Called to shutdown the IP module in preparation
  2601. // for unloading the protocol stack.
  2602. //
  2603. void
  2604. IPUnload(void)
  2605. {
  2606. Interface *IF;
  2607. KIRQL OldIrql;
  2608. TdiDeregisterProvider(IPv6ProviderHandle);
  2609. //
  2610. // Stop the periodic timer.
  2611. //
  2612. KeCancelTimer(&IPv6Timer);
  2613. //
  2614. // Call each interface's close function.
  2615. // Note that interfaces might disappear while
  2616. // the interface list is unlocked,
  2617. // but new interfaces will not be created
  2618. // and the list does not get reordered.
  2619. //
  2620. KeAcquireSpinLock(&IFListLock, &OldIrql);
  2621. for (IF = IFList; IF != NULL; IF = IF->Next) {
  2622. AddRefIF(IF);
  2623. KeReleaseSpinLock(&IFListLock, OldIrql);
  2624. DestroyIF(IF);
  2625. KeAcquireSpinLock(&IFListLock, &OldIrql);
  2626. ReleaseIF(IF);
  2627. }
  2628. KeReleaseSpinLock(&IFListLock, OldIrql);
  2629. //
  2630. // DestroyIF/DestroyNTE spawned RegisterNetAddressWorker threads.
  2631. // Wait for them all to finish executing.
  2632. // This needs to be done before NetTableCleanup.
  2633. //
  2634. while (OutstandingRegisterNetAddressCount != 0) {
  2635. LARGE_INTEGER Interval;
  2636. Interval.QuadPart = -1; // Shortest possible relative wait.
  2637. KeDelayExecutionThread(KernelMode, FALSE, &Interval);
  2638. }
  2639. //
  2640. // TunnelUnload needs to be after calling DestroyIF
  2641. // on all the interfaces and before InterfaceCleanup.
  2642. //
  2643. TunnelUnload();
  2644. NetTableCleanup();
  2645. InterfaceCleanup();
  2646. UnloadSelect();
  2647. UnloadRouting();
  2648. IPSecUnload();
  2649. ReassemblyUnload();
  2650. ASSERT(NumForwardingInterfaces == 0);
  2651. ASSERT(IPSInfo.ipsi_numif == 0);
  2652. //
  2653. // InterfaceCleanup spawned DeregisterInterfaceWorker threads.
  2654. // Wait for them all to finish executing.
  2655. // Unfortunately, there is no good builtin synchronization primitive
  2656. // for this task. However, in practice because of the relative
  2657. // priorities of the threads involved, we almost never actually
  2658. // wait here. So this solution is quite efficient.
  2659. //
  2660. while (OutstandingDeregisterInterfaceCount != 0) {
  2661. LARGE_INTEGER Interval;
  2662. Interval.QuadPart = -1; // Shortest possible relative wait.
  2663. KeDelayExecutionThread(KernelMode, FALSE, &Interval);
  2664. }
  2665. #if DBG
  2666. {
  2667. NetTableEntry *NTE;
  2668. for (NTE = NetTableList; NTE != NULL; NTE = NTE->NextOnNTL) {
  2669. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  2670. "Leaked NTE %p (IF %u/%p) Addr %s Refs %u\n",
  2671. NTE, NTE->IF->Index, NTE->IF,
  2672. FormatV6Address(&NTE->Address),
  2673. NTE->RefCnt));
  2674. }
  2675. for (IF = IFList; IF != NULL; IF = IF->Next) {
  2676. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  2677. "Leaked IF %u/%p Refs %u\n",
  2678. IF->Index, IF, IF->RefCnt));
  2679. }
  2680. }
  2681. #endif // DBG
  2682. //
  2683. // We must wait until all the interfaces are completely cleaned up
  2684. // by DeregisterInterfaceWorker before freeing the packet pools.
  2685. // This is because Lan interfaces hold onto a packet (ai_tdpacket)
  2686. // that is freed in LanCleanupAdapter. NdisFreePacketPool
  2687. // blows away any packets that are still allocated so we can't call
  2688. // IPv6FreePacket after NdisFreePacketPool/NdisFreeBufferPool.
  2689. //
  2690. NdisFreePacketPool(IPv6PacketPool);
  2691. NdisFreeBufferPool(IPv6BufferPool);
  2692. }
  2693. //* GetLinkLocalNTE
  2694. //
  2695. // Returns the interface's link-local NTE (without a reference), or
  2696. // returns NULL if the interface does not have a valid link-local address.
  2697. //
  2698. // Called with the interface locked.
  2699. //
  2700. NetTableEntry *
  2701. GetLinkLocalNTE(Interface *IF)
  2702. {
  2703. NetTableEntry *NTE;
  2704. NTE = IF->LinkLocalNTE;
  2705. if ((NTE == NULL) || !IsValidNTE(NTE)) {
  2706. //
  2707. // If we didn't find a valid NTE in the LinkLocalNTE field,
  2708. // search the ADE list and cache the first valid link-local NTE
  2709. // we find (if any).
  2710. //
  2711. for (NTE = (NetTableEntry *) IF->ADE;
  2712. NTE != NULL;
  2713. NTE = (NetTableEntry *) NTE->Next) {
  2714. if ((NTE->Type == ADE_UNICAST) &&
  2715. IsValidNTE(NTE) &&
  2716. IsLinkLocal(&NTE->Address)) {
  2717. //
  2718. // Cache this NTE for future reference.
  2719. //
  2720. IF->LinkLocalNTE = NTE;
  2721. break;
  2722. }
  2723. }
  2724. }
  2725. return NTE;
  2726. }
  2727. //* GetLinkLocalAddress
  2728. //
  2729. // Returns the interface's link-local address,
  2730. // if it is valid. Otherwise, returns
  2731. // the unspecified address.
  2732. //
  2733. // Callable from thread or DPC context.
  2734. //
  2735. // Returns FALSE if the link-local address is not valid.
  2736. //
  2737. int
  2738. GetLinkLocalAddress(
  2739. Interface *IF, // Interface for which to find an address.
  2740. IPv6Addr *Addr) // Where to return address found (or unspecified).
  2741. {
  2742. KIRQL OldIrql;
  2743. NetTableEntry *NTE;
  2744. int Status;
  2745. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  2746. NTE = GetLinkLocalNTE(IF);
  2747. if (Status = (NTE != NULL))
  2748. *Addr = NTE->Address;
  2749. else
  2750. *Addr = UnspecifiedAddr;
  2751. KeReleaseSpinLock(&IF->Lock, OldIrql);
  2752. return Status;
  2753. }
  2754. //* FindOrCreateNTE
  2755. //
  2756. // Find the specified unicast address.
  2757. // If it already exists, update it.
  2758. // If it doesn't exist, create it if the lifetime is non-zero.
  2759. //
  2760. // Returns TRUE for success.
  2761. //
  2762. // Called with NO locks held.
  2763. // Callable from thread or DPC context.
  2764. //
  2765. int
  2766. FindOrCreateNTE(
  2767. Interface *IF,
  2768. const IPv6Addr *Addr,
  2769. uint AddrConf,
  2770. uint ValidLifetime,
  2771. uint PreferredLifetime)
  2772. {
  2773. NetTableEntry *NTE;
  2774. KIRQL OldIrql;
  2775. int rc;
  2776. ASSERT(!IsMulticast(Addr) && !IsUnspecified(Addr) &&
  2777. (!IsLoopback(Addr) || (IF == LoopInterface)));
  2778. ASSERT(PreferredLifetime <= ValidLifetime);
  2779. ASSERT(AddrConf != ADDR_CONF_ANONYMOUS);
  2780. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  2781. NTE = (NetTableEntry *) *FindADE(IF, Addr);
  2782. if (NTE == NULL) {
  2783. //
  2784. // There is no such address, so create it.
  2785. //
  2786. NTE = CreateNTE(IF, Addr, AddrConf, ValidLifetime, PreferredLifetime);
  2787. if (NTE == NULL) {
  2788. rc = FALSE;
  2789. }
  2790. else {
  2791. ReleaseNTE(NTE);
  2792. rc = TRUE;
  2793. }
  2794. }
  2795. else if ((NTE->Type == ADE_UNICAST) &&
  2796. (NTE->AddrConf == AddrConf)) {
  2797. //
  2798. // Update the address lifetimes.
  2799. // If we set the lifetime to zero, AddrConfTimeout will remove it.
  2800. // NB: We do not allow NTE->AddrConf to change.
  2801. //
  2802. NTE->ValidLifetime = ValidLifetime;
  2803. NTE->PreferredLifetime = PreferredLifetime;
  2804. rc = TRUE;
  2805. }
  2806. else {
  2807. //
  2808. // We found the address, but we can't update it.
  2809. //
  2810. rc = FALSE;
  2811. }
  2812. if (IsMCastSyncNeeded(IF))
  2813. DeferSynchronizeMulticastAddresses(IF);
  2814. KeReleaseSpinLock(&IF->Lock, OldIrql);
  2815. return rc;
  2816. }
  2817. //* CreateAnonymousAddress
  2818. //
  2819. // Creates an anonymous address for the interface.
  2820. //
  2821. // Called with the interface locked.
  2822. //
  2823. void
  2824. CreateAnonymousAddress(Interface *IF, const IPv6Addr *Prefix, IPv6Addr *Addr)
  2825. {
  2826. uint Now = IPv6TickCount;
  2827. if (AnonRandomTime == 0) {
  2828. //
  2829. // We delay initializing AnonRandomTime until it is needed.
  2830. // This way the random number generator has been initialized.
  2831. //
  2832. AnonRandomTime = RandomNumber(0, MaxAnonRandomTime);
  2833. }
  2834. //
  2835. // First, update the state that we use if it is too old.
  2836. //
  2837. if ((IF->AnonStateAge == 0) ||
  2838. (UseAnonymousAddresses == USE_ANON_ALWAYS) ||
  2839. ((uint)(Now - IF->AnonStateAge) >=
  2840. (AnonPreferredLifetime - AnonRegenerateTime))) {
  2841. TryAgain:
  2842. IF->AnonStateAge = Now;
  2843. if (UseAnonymousAddresses == USE_ANON_COUNTER) {
  2844. //
  2845. // When testing, it's convenient to use interface identifiers
  2846. // that aren't actually random.
  2847. //
  2848. *(UINT UNALIGNED *)&IF->AnonState.s6_bytes[12] =
  2849. net_long(net_long(*(UINT UNALIGNED *)&IF->AnonState.s6_bytes[12]) + 1);
  2850. }
  2851. else {
  2852. MD5_CTX Context;
  2853. //
  2854. // The high half of IF->AnonState is our history value.
  2855. // The low half is the anonymous interface identifier.
  2856. //
  2857. // Append the history value to the usual interface identifier,
  2858. // and calculate the MD5 digest of the resulting quantity.
  2859. // Note MD5 digests and IPv6 addresses are the both 16 bytes,
  2860. // while our history value and the interface identifer are 8 bytes.
  2861. //
  2862. (*IF->CreateToken)(IF->LinkContext, &IF->AnonState);
  2863. MD5Init(&Context);
  2864. MD5Update(&Context, (uchar *)&IF->AnonState, sizeof IF->AnonState);
  2865. MD5Final(&Context);
  2866. memcpy((uchar *)&IF->AnonState, Context.digest, MD5DIGESTLEN);
  2867. }
  2868. //
  2869. // Clear the universal/local bit to indicate local significance.
  2870. //
  2871. IF->AnonState.s6_bytes[8] &= ~0x2;
  2872. }
  2873. RtlCopyMemory(&Addr->s6_bytes[0], Prefix, 8);
  2874. RtlCopyMemory(&Addr->s6_bytes[8], &IF->AnonState.s6_bytes[8], 8);
  2875. //
  2876. // Check that we haven't accidently generated
  2877. // a known anycast address format,
  2878. // or an existing address on the interface.
  2879. //
  2880. if (IsKnownAnycast(Addr) ||
  2881. (*FindADE(IF, Addr) != NULL))
  2882. goto TryAgain;
  2883. }
  2884. //* AddrConfUpdate - Perform address auto-configuration.
  2885. //
  2886. // Called when we receive a valid Router Advertisement
  2887. // with a Prefix Information option that has the A (autonomous) bit set.
  2888. //
  2889. // Our caller is responsible for any sanity-checking of the prefix.
  2890. //
  2891. // Our caller is responsible for checking that the preferred lifetime
  2892. // is not greater than the valid lifetime.
  2893. //
  2894. // Will also optionally return an NTE, with a reference for the caller.
  2895. // This is done when a public address is created.
  2896. //
  2897. // Called with NO locks held.
  2898. // Callable from DPC context, not from thread context.
  2899. //
  2900. void
  2901. AddrConfUpdate(
  2902. Interface *IF,
  2903. const IPv6Addr *Prefix,
  2904. uint ValidLifetime,
  2905. uint PreferredLifetime,
  2906. int Authenticated,
  2907. NetTableEntry **pNTE)
  2908. {
  2909. NetTableEntry *NTE;
  2910. int Create = TRUE;
  2911. ASSERT(PreferredLifetime <= ValidLifetime);
  2912. KeAcquireSpinLockAtDpcLevel(&IF->Lock);
  2913. //
  2914. // Scan the existing Net Table Entries.
  2915. // Note that some of the list elements
  2916. // are actually ADEs of other flavors.
  2917. //
  2918. for (NTE = (NetTableEntry *)IF->ADE;
  2919. ;
  2920. NTE = (NetTableEntry *)NTE->Next) {
  2921. if (NTE == NULL) {
  2922. //
  2923. // No existing entry for this prefix.
  2924. // Create an entry if the lifetime is non-zero.
  2925. //
  2926. if (Create && (ValidLifetime != 0)) {
  2927. IPv6Addr Addr;
  2928. //
  2929. // Auto-configure a new public address.
  2930. //
  2931. Addr = *Prefix;
  2932. (*IF->CreateToken)(IF->LinkContext, &Addr);
  2933. NTE = (NetTableEntry *) *FindADE(IF, &Addr);
  2934. if (NTE != NULL) {
  2935. if (NTE->Type == ADE_UNICAST) {
  2936. //
  2937. // Resurrect the address for our use.
  2938. //
  2939. ASSERT(NTE->DADState == DAD_STATE_INVALID);
  2940. NTE->ValidLifetime = ValidLifetime;
  2941. NTE->PreferredLifetime = PreferredLifetime;
  2942. //
  2943. // And return this NTE.
  2944. //
  2945. AddRefNTE(NTE);
  2946. }
  2947. else {
  2948. //
  2949. // We can not create the public address.
  2950. //
  2951. NTE = NULL;
  2952. break;
  2953. }
  2954. }
  2955. else {
  2956. //
  2957. // Create the public address, returning the new NTE.
  2958. //
  2959. NTE = CreateNTE(IF, &Addr, ADDR_CONF_PUBLIC,
  2960. ValidLifetime, PreferredLifetime);
  2961. }
  2962. //
  2963. // Auto-configure a new anonymous address,
  2964. // if appropriate. Note that anonymous addresses cannot
  2965. // be used on interfaces that do not support ND, since
  2966. // we have no way to resolve them to link-layer addresses.
  2967. //
  2968. if ((UseAnonymousAddresses != USE_ANON_NO) &&
  2969. !IsSiteLocal(Prefix) &&
  2970. (IF->Flags & IF_FLAG_NEIGHBOR_DISCOVERS) &&
  2971. (PreferredLifetime > AnonRegenerateTime) &&
  2972. (NTE != NULL)) {
  2973. IPv6Addr AnonAddr;
  2974. uint AnonValidLife;
  2975. uint AnonPreferredLife;
  2976. AnonNetTableEntry *AnonNTE;
  2977. CreateAnonymousAddress(IF, Prefix, &AnonAddr);
  2978. AnonValidLife = MIN(ValidLifetime,
  2979. MaxAnonValidLifetime);
  2980. AnonPreferredLife = MIN(PreferredLifetime,
  2981. AnonPreferredLifetime);
  2982. AnonNTE = (AnonNetTableEntry *)
  2983. CreateNTE(IF, &AnonAddr, ADDR_CONF_ANONYMOUS,
  2984. AnonValidLife, AnonPreferredLife);
  2985. if (AnonNTE != NULL) {
  2986. //
  2987. // Create the association between
  2988. // the anonymous & public address.
  2989. //
  2990. AnonNTE->Public = NTE;
  2991. //
  2992. // Initialize the special anonymous creation time.
  2993. // This limits the anonymous address's lifetimes.
  2994. //
  2995. AnonNTE->CreationTime = IPv6TickCount;
  2996. ReleaseNTE((NetTableEntry *)AnonNTE);
  2997. }
  2998. else {
  2999. //
  3000. // Failure - destroy the public address.
  3001. //
  3002. DestroyNTE(IF, NTE);
  3003. ReleaseNTE(NTE);
  3004. NTE = NULL;
  3005. }
  3006. }
  3007. }
  3008. break;
  3009. }
  3010. //
  3011. // Is this a unicast address matching the prefix?
  3012. //
  3013. if ((NTE->Type == ADE_UNICAST) &&
  3014. (NTE->DADState != DAD_STATE_INVALID) &&
  3015. HasPrefix(&NTE->Address, Prefix,
  3016. IPV6_ADDRESS_LENGTH - IPV6_ID_LENGTH)) {
  3017. //
  3018. // Reset the lifetimes of auto-configured addresses.
  3019. // NB: RFC 2462 says to reset DHCP addresses too,
  3020. // but I think that's wrong.
  3021. //
  3022. // Note that to prevent denial of service,
  3023. // we don't accept updates that lower the lifetime
  3024. // to small values.
  3025. //
  3026. // AddrConfTimeout (called from IPv6Timeout) handles
  3027. // the invalid & deprecated state transitions.
  3028. //
  3029. if (IsStatelessAutoConfNTE(NTE)) {
  3030. if ((ValidLifetime > PREFIX_LIFETIME_SAFETY) ||
  3031. (ValidLifetime > NTE->ValidLifetime) ||
  3032. Authenticated)
  3033. NTE->ValidLifetime = ValidLifetime;
  3034. else if (NTE->ValidLifetime <= PREFIX_LIFETIME_SAFETY)
  3035. ; // ignore
  3036. else
  3037. NTE->ValidLifetime = PREFIX_LIFETIME_SAFETY;
  3038. NTE->PreferredLifetime = PreferredLifetime;
  3039. //
  3040. // For anonymous addresses, ensure that the lifetimes
  3041. // are not extended indefinitely.
  3042. //
  3043. if (NTE->AddrConf == ADDR_CONF_ANONYMOUS) {
  3044. AnonNetTableEntry *AnonNTE = (AnonNetTableEntry *)NTE;
  3045. uint Now = IPv6TickCount;
  3046. //
  3047. // Must be careful of overflows in these comparisons.
  3048. // (Eg, AnonNTE->ValidLifetime might be INFINITE_LIFETIME.)
  3049. // N Now
  3050. // V AnonNTE->ValidLifetime
  3051. // MV MaxAnonValidLifetime
  3052. // C AnonNTE->CreationTime
  3053. // We want to check
  3054. // N + V > C + MV
  3055. // Transform this to
  3056. // N - C > MV - V
  3057. // Then underflow of MV - V must be checked but
  3058. // N - C is not a problem because the tick count wraps.
  3059. //
  3060. if ((AnonNTE->ValidLifetime > MaxAnonValidLifetime) ||
  3061. (Now - AnonNTE->CreationTime >
  3062. MaxAnonValidLifetime - AnonNTE->ValidLifetime)) {
  3063. //
  3064. // This anonymous address is showing its age.
  3065. // Must curtail its valid lifetime.
  3066. //
  3067. if (MaxAnonValidLifetime > Now - AnonNTE->CreationTime)
  3068. AnonNTE->ValidLifetime =
  3069. AnonNTE->CreationTime +
  3070. MaxAnonValidLifetime - Now;
  3071. else
  3072. AnonNTE->ValidLifetime = 0;
  3073. }
  3074. if ((AnonNTE->PreferredLifetime > AnonPreferredLifetime) ||
  3075. (Now - AnonNTE->CreationTime >
  3076. AnonPreferredLifetime - AnonNTE->PreferredLifetime)) {
  3077. //
  3078. // This anonymous address is showing its age.
  3079. // Must curtail its preferred lifetime.
  3080. //
  3081. if (AnonPreferredLifetime > Now - AnonNTE->CreationTime)
  3082. AnonNTE->PreferredLifetime =
  3083. AnonNTE->CreationTime +
  3084. AnonPreferredLifetime - Now;
  3085. else
  3086. AnonNTE->PreferredLifetime = 0;
  3087. }
  3088. }
  3089. //
  3090. // Maintain our invariant that the preferred lifetime
  3091. // is not larger than the valid lifetime.
  3092. //
  3093. if (NTE->ValidLifetime < NTE->PreferredLifetime)
  3094. NTE->PreferredLifetime = NTE->ValidLifetime;
  3095. }
  3096. if (NTE->ValidLifetime != 0) {
  3097. //
  3098. // We found an existing address that matches the prefix,
  3099. // so inhibit auto-configuration of a new address.
  3100. //
  3101. Create = FALSE;
  3102. }
  3103. }
  3104. }
  3105. if (IsMCastSyncNeeded(IF))
  3106. DeferSynchronizeMulticastAddresses(IF);
  3107. KeReleaseSpinLockFromDpcLevel(&IF->Lock);
  3108. if (pNTE != NULL)
  3109. *pNTE = NTE;
  3110. else if (NTE != NULL)
  3111. ReleaseNTE(NTE);
  3112. }
  3113. //* AddrConfDuplicate
  3114. //
  3115. // Duplicate Address Detection has found
  3116. // that the NTE conflicts with some other node.
  3117. //
  3118. // Called with the interface locked.
  3119. // Callable from thread or DPC context.
  3120. //
  3121. void
  3122. AddrConfDuplicate(Interface *IF, NetTableEntry *NTE)
  3123. {
  3124. int rc;
  3125. ASSERT(NTE->IF == IF);
  3126. if ((NTE->DADState != DAD_STATE_INVALID) &&
  3127. (NTE->DADState != DAD_STATE_DUPLICATE)) {
  3128. IF->DupAddrDetects++;
  3129. if (IsValidNTE(NTE)) {
  3130. if (NTE->DADState == DAD_STATE_PREFERRED) {
  3131. //
  3132. // Queue worker to tell TDI that this address is going away.
  3133. //
  3134. if (!(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED)) {
  3135. DeferRegisterNetAddress(NTE);
  3136. }
  3137. }
  3138. //
  3139. // This NTE is no longer available as a source address.
  3140. //
  3141. InvalidateRouteCache();
  3142. //
  3143. // Disable the loopback route for this address.
  3144. //
  3145. rc = ControlLoopback(IF, &NTE->Address, CONTROL_LOOPBACK_DISABLED);
  3146. ASSERT(rc);
  3147. }
  3148. NTE->DADState = DAD_STATE_DUPLICATE;
  3149. NTE->DADTimer = 0;
  3150. if (NTE->AddrConf == ADDR_CONF_ANONYMOUS) {
  3151. NetTableEntry *Public;
  3152. //
  3153. // Make this address invalid so it will go away.
  3154. // NB: We still have a ref for the NTE via our caller.
  3155. //
  3156. DestroyNTE(IF, NTE);
  3157. //
  3158. // Should we create a new anonymous address?
  3159. //
  3160. if ((UseAnonymousAddresses != USE_ANON_NO) &&
  3161. ((Public = ((AnonNetTableEntry *)NTE)->Public) != NULL) &&
  3162. (Public->PreferredLifetime > AnonRegenerateTime) &&
  3163. (IF->DupAddrDetects < MaxAnonDADAttempts)) {
  3164. IPv6Addr AnonAddr;
  3165. AnonNetTableEntry *NewNTE;
  3166. uint AnonValidLife;
  3167. uint AnonPreferredLife;
  3168. //
  3169. // Generate a new anonymous address,
  3170. // forcing the use of a new interface identifier.
  3171. //
  3172. IF->AnonStateAge = 0;
  3173. CreateAnonymousAddress(IF, &NTE->Address, &AnonAddr);
  3174. AnonValidLife = MIN(Public->ValidLifetime,
  3175. MaxAnonValidLifetime);
  3176. AnonPreferredLife = MIN(Public->PreferredLifetime,
  3177. AnonPreferredLifetime);
  3178. //
  3179. // Configure the new address.
  3180. //
  3181. NewNTE = (AnonNetTableEntry *)
  3182. CreateNTE(IF, &AnonAddr, ADDR_CONF_ANONYMOUS,
  3183. AnonValidLife, AnonPreferredLife);
  3184. if (NewNTE == NULL) {
  3185. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  3186. "AddrConfDuplicate: CreateNTE failed\n"));
  3187. }
  3188. else {
  3189. NewNTE->Public = Public;
  3190. NewNTE->CreationTime = IPv6TickCount;
  3191. ReleaseNTE((NetTableEntry *)NewNTE);
  3192. }
  3193. }
  3194. }
  3195. }
  3196. }
  3197. //* AddrConfNotDuplicate
  3198. //
  3199. // Duplicate Address Detection has NOT found
  3200. // a conflict with another node.
  3201. //
  3202. // Called with the interface locked.
  3203. // Callable from thread or DPC context.
  3204. //
  3205. void
  3206. AddrConfNotDuplicate(Interface *IF, NetTableEntry *NTE)
  3207. {
  3208. int rc;
  3209. //
  3210. // The address has passed Duplicate Address Detection.
  3211. // Transition to a valid state.
  3212. //
  3213. if (! IsValidNTE(NTE)) {
  3214. if (NTE->PreferredLifetime == 0)
  3215. NTE->DADState = DAD_STATE_DEPRECATED;
  3216. else
  3217. NTE->DADState = DAD_STATE_PREFERRED;
  3218. //
  3219. // This NTE is now available as a source address.
  3220. //
  3221. InvalidateRouteCache();
  3222. //
  3223. // Enable the loopback route for this address.
  3224. //
  3225. rc = ControlLoopback(IF, &NTE->Address, CONTROL_LOOPBACK_ENABLED);
  3226. ASSERT(rc);
  3227. }
  3228. //
  3229. // DAD is also triggered through an interface disconnect to connect
  3230. // transition in which case the address is not registered with TDI
  3231. // even if it is in the preferred state. Hence we queue a worker to
  3232. // tell TDI about this address outside the "if (!IsValidNTE)" clause.
  3233. //
  3234. if ((NTE->DADState == DAD_STATE_PREFERRED) &&
  3235. !(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED)) {
  3236. DeferRegisterNetAddress(NTE);
  3237. }
  3238. }
  3239. //* AddrConfResetAutoConfig
  3240. //
  3241. // Resets the interface's auto-configured address lifetimes.
  3242. //
  3243. // Called with the interface locked.
  3244. // Callable from thread or DPC context.
  3245. //
  3246. void
  3247. AddrConfResetAutoConfig(Interface *IF, uint MaxLifetime)
  3248. {
  3249. NetTableEntry *NTE;
  3250. for (NTE = (NetTableEntry *) IF->ADE;
  3251. NTE != NULL;
  3252. NTE = (NetTableEntry *) NTE->Next) {
  3253. //
  3254. // Is this an auto-configured unicast address?
  3255. //
  3256. if ((NTE->Type == ADE_UNICAST) &&
  3257. IsStatelessAutoConfNTE(NTE)) {
  3258. //
  3259. // Set the valid lifetime to a small value.
  3260. // If we don't get an RA soon, the address will expire.
  3261. //
  3262. if (NTE->ValidLifetime > MaxLifetime)
  3263. NTE->ValidLifetime = MaxLifetime;
  3264. if (NTE->PreferredLifetime > NTE->ValidLifetime)
  3265. NTE->PreferredLifetime = NTE->ValidLifetime;
  3266. }
  3267. }
  3268. }
  3269. //* ReconnectADEs
  3270. //
  3271. // Callable from thread or DPC context.
  3272. // Called with the interface locked.
  3273. //
  3274. // (Actually, we are at DPC level because we hold the interface lock.)
  3275. //
  3276. void
  3277. ReconnectADEs(Interface *IF)
  3278. {
  3279. AddressEntry *ADE;
  3280. for (ADE = IF->ADE; ADE != NULL; ADE = ADE->Next) {
  3281. switch (ADE->Type) {
  3282. case ADE_UNICAST: {
  3283. NetTableEntry *NTE = (NetTableEntry *) ADE;
  3284. if (NTE->DADState != DAD_STATE_INVALID) {
  3285. //
  3286. // Restart Duplicate Address Detection,
  3287. // if it is enabled for this interface.
  3288. //
  3289. AddrConfStartDAD(IF, NTE);
  3290. }
  3291. break;
  3292. }
  3293. case ADE_ANYCAST:
  3294. //
  3295. // Nothing to do for anycast addresses.
  3296. //
  3297. break;
  3298. case ADE_MULTICAST: {
  3299. MulticastAddressEntry *MAE = (MulticastAddressEntry *) ADE;
  3300. //
  3301. // Rejoin this multicast group,
  3302. // if it is reportable.
  3303. //
  3304. KeAcquireSpinLockAtDpcLevel(&QueryListLock);
  3305. if (MAE->MCastFlags & MAE_REPORTABLE) {
  3306. MAE->MCastCount = MLD_NUM_INITIAL_REPORTS;
  3307. if (MAE->MCastTimer == 0)
  3308. AddToQueryList(MAE);
  3309. MAE->MCastTimer = 1;
  3310. }
  3311. KeReleaseSpinLockFromDpcLevel(&QueryListLock);
  3312. break;
  3313. }
  3314. }
  3315. }
  3316. }
  3317. //* DisconnectADEs
  3318. //
  3319. // Callable from thread or DPC context.
  3320. // Called with the interface locked.
  3321. //
  3322. // (Actually, we are at DPC level because we hold the interface lock.)
  3323. //
  3324. void
  3325. DisconnectADEs(Interface *IF)
  3326. {
  3327. AddressEntry *ADE;
  3328. ASSERT(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED);
  3329. for (ADE = IF->ADE; ADE != NULL; ADE = ADE->Next) {
  3330. if (ADE->Type == ADE_UNICAST) {
  3331. NetTableEntry *NTE = (NetTableEntry *) ADE;
  3332. if (NTE->DADState == DAD_STATE_PREFERRED) {
  3333. //
  3334. // Queue worker to tell TDI that this address is going away.
  3335. //
  3336. DeferRegisterNetAddress(NTE);
  3337. }
  3338. }
  3339. //
  3340. // Nothing to do for anycast or multicast addresses.
  3341. //
  3342. }
  3343. }
  3344. //* DestroyNTE
  3345. //
  3346. // Make an NTE be invalid, resulting in its eventual destruction.
  3347. //
  3348. // In the DestroyIF case, the NTE has already been removed
  3349. // from the interface. In other situations, that doesn't happen
  3350. // until later, when NetTableCleanup runs.
  3351. //
  3352. // Callable from thread or DPC context.
  3353. // Called with the interface locked.
  3354. //
  3355. // (Actually, we are at DPC level because we hold the interface lock.)
  3356. //
  3357. void
  3358. DestroyNTE(Interface *IF, NetTableEntry *NTE)
  3359. {
  3360. int rc;
  3361. ASSERT(NTE->IF == IF);
  3362. if (NTE->DADState != DAD_STATE_INVALID) {
  3363. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  3364. "DestroyNTE(NTE %p, Addr %s) -> invalid\n",
  3365. NTE, FormatV6Address(&NTE->Address)));
  3366. if (IsValidNTE(NTE)) {
  3367. if (NTE->DADState == DAD_STATE_PREFERRED) {
  3368. //
  3369. // Queue worker to tell TDI that this address is going away.
  3370. //
  3371. if (!(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED)) {
  3372. DeferRegisterNetAddress(NTE);
  3373. }
  3374. }
  3375. //
  3376. // This NTE is no longer available as a source address.
  3377. //
  3378. InvalidateRouteCache();
  3379. //
  3380. // Disable the loopback route for this address.
  3381. //
  3382. rc = ControlLoopback(IF, &NTE->Address, CONTROL_LOOPBACK_DISABLED);
  3383. ASSERT(rc);
  3384. }
  3385. //
  3386. // Invalidate this address.
  3387. //
  3388. NTE->DADState = DAD_STATE_INVALID;
  3389. NTE->DADTimer = 0;
  3390. //
  3391. // We have to set its lifetime to zero,
  3392. // or else AddrConfTimeout will attempt
  3393. // to resurrect this address.
  3394. //
  3395. NTE->ValidLifetime = 0;
  3396. NTE->PreferredLifetime = 0;
  3397. //
  3398. // The corresponding solicited-node address is not needed.
  3399. //
  3400. FindAndReleaseSolicitedNodeMAE(IF, &NTE->Address);
  3401. if (NTE == IF->LinkLocalNTE) {
  3402. //
  3403. // Unmark it as the primary link-local NTE.
  3404. // GetLinkLocalAddress will update LinkLocalNTE lazily.
  3405. //
  3406. IF->LinkLocalNTE = NULL;
  3407. }
  3408. //
  3409. // Release the interface's reference for the NTE.
  3410. //
  3411. ReleaseNTE(NTE);
  3412. }
  3413. }
  3414. //* EnlivenNTE
  3415. //
  3416. // Make an NTE come alive, transitioning out of DAD_STATE_INVALID.
  3417. //
  3418. // Callable from thread or DPC context.
  3419. // Called with the interface locked.
  3420. //
  3421. void
  3422. EnlivenNTE(Interface *IF, NetTableEntry *NTE)
  3423. {
  3424. ASSERT(NTE->DADState == DAD_STATE_INVALID);
  3425. ASSERT(NTE->ValidLifetime != 0);
  3426. //
  3427. // The NTE needs a corresponding solicited-node MAE.
  3428. // If this fails, leave the address invalid and
  3429. // try again later.
  3430. //
  3431. if (FindOrCreateSolicitedNodeMAE(IF, &NTE->Address)) {
  3432. //
  3433. // The interface needs a reference for the NTE,
  3434. // because we are enlivening it.
  3435. //
  3436. AddRefNTE(NTE);
  3437. //
  3438. // Start the address in the tentative state.
  3439. //
  3440. NTE->DADState = DAD_STATE_TENTATIVE;
  3441. //
  3442. // Start duplicate address detection.
  3443. //
  3444. AddrConfStartDAD(IF, NTE);
  3445. }
  3446. }
  3447. //* AddrConfTimeout - Perform valid/preferred lifetime expiration.
  3448. //
  3449. // Called periodically from NetTableTimeout on every NTE.
  3450. // As usual, caller must hold a reference for the NTE.
  3451. //
  3452. // Called with NO locks held.
  3453. // Callable from DPC context, not from thread context.
  3454. //
  3455. void
  3456. AddrConfTimeout(NetTableEntry *NTE)
  3457. {
  3458. Interface *IF = NTE->IF;
  3459. NetTableEntry **PrevNTE;
  3460. int QueueWorker = FALSE;
  3461. NetTableEntry *Public;
  3462. ASSERT(NTE->Type == ADE_UNICAST);
  3463. KeAcquireSpinLockAtDpcLevel(&IF->Lock);
  3464. if (NTE->ValidLifetime == 0) {
  3465. //
  3466. // If the valid lifetime is zero, then the NTE should be invalid.
  3467. //
  3468. DestroyNTE(IF, NTE);
  3469. }
  3470. else {
  3471. //
  3472. // If the valid lifetime is non-zero, then the NTE should be alive.
  3473. //
  3474. if (NTE->DADState == DAD_STATE_INVALID)
  3475. EnlivenNTE(IF, NTE);
  3476. if (NTE->ValidLifetime != INFINITE_LIFETIME)
  3477. NTE->ValidLifetime--;
  3478. }
  3479. //
  3480. // Note that AnonRegenerateTime might be zero.
  3481. // In which case it's important to only do this
  3482. // when transitioning from preferred to deprecated,
  3483. // NOT every time the preferred lifetime is zero.
  3484. //
  3485. if ((NTE->AddrConf == ADDR_CONF_ANONYMOUS) &&
  3486. (NTE->DADState == DAD_STATE_PREFERRED) &&
  3487. (NTE->PreferredLifetime == AnonRegenerateTime) &&
  3488. (IF->Flags & IF_FLAG_NEIGHBOR_DISCOVERS) &&
  3489. (UseAnonymousAddresses != USE_ANON_NO) &&
  3490. ((Public = ((AnonNetTableEntry *)NTE)->Public) != NULL) &&
  3491. (Public->PreferredLifetime > AnonRegenerateTime)) {
  3492. IPv6Addr AnonAddr;
  3493. AnonNetTableEntry *NewNTE;
  3494. uint AnonValidLife;
  3495. uint AnonPreferredLife;
  3496. //
  3497. // We will soon deprecate this anonymous address,
  3498. // so create a new anonymous address.
  3499. //
  3500. CreateAnonymousAddress(IF, &NTE->Address, &AnonAddr);
  3501. AnonValidLife = MIN(Public->ValidLifetime,
  3502. MaxAnonValidLifetime);
  3503. AnonPreferredLife = MIN(Public->PreferredLifetime,
  3504. AnonPreferredLifetime);
  3505. //
  3506. // Configure the new address.
  3507. //
  3508. NewNTE = (AnonNetTableEntry *)
  3509. CreateNTE(IF, &AnonAddr, ADDR_CONF_ANONYMOUS,
  3510. AnonValidLife, AnonPreferredLife);
  3511. if (NewNTE == NULL) {
  3512. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  3513. "AddrConfTimeout: CreateNTE failed\n"));
  3514. }
  3515. else {
  3516. NewNTE->Public = Public;
  3517. NewNTE->CreationTime = IPv6TickCount;
  3518. ReleaseNTE((NetTableEntry *)NewNTE);
  3519. }
  3520. }
  3521. //
  3522. // If the preferred lifetime is zero, then the NTE should be deprecated.
  3523. //
  3524. if (NTE->PreferredLifetime == 0) {
  3525. if (NTE->DADState == DAD_STATE_PREFERRED) {
  3526. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  3527. "AddrConfTimeout(NTE %p, Addr %s) -> deprecated\n",
  3528. NTE, FormatV6Address(&NTE->Address)));
  3529. //
  3530. // Make this address be deprecated.
  3531. //
  3532. NTE->DADState = DAD_STATE_DEPRECATED;
  3533. if (!(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED)) {
  3534. QueueWorker = TRUE;
  3535. }
  3536. InvalidateRouteCache();
  3537. }
  3538. } else {
  3539. //
  3540. // If the address was deprecated, then it should be preferred.
  3541. // (AddrConfUpdate must have just increased the preferred lifetime.)
  3542. //
  3543. if (NTE->DADState == DAD_STATE_DEPRECATED) {
  3544. NTE->DADState = DAD_STATE_PREFERRED;
  3545. if (!(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED)) {
  3546. QueueWorker = TRUE;
  3547. }
  3548. InvalidateRouteCache();
  3549. }
  3550. if (NTE->PreferredLifetime != INFINITE_LIFETIME)
  3551. NTE->PreferredLifetime--;
  3552. }
  3553. if (IsMCastSyncNeeded(IF))
  3554. DeferSynchronizeMulticastAddresses(IF);
  3555. KeReleaseSpinLockFromDpcLevel(&IF->Lock);
  3556. if (QueueWorker)
  3557. DeferRegisterNetAddress(NTE);
  3558. }
  3559. //* NetTableCleanup
  3560. //
  3561. // Cleans up any NetTableEntries with zero references.
  3562. //
  3563. // Called with NO locks held.
  3564. // Callable from thread or DPC context.
  3565. //
  3566. void
  3567. NetTableCleanup(void)
  3568. {
  3569. NetTableEntry *DestroyList = NULL;
  3570. NetTableEntry *NTE, *NextNTE;
  3571. Interface *IF;
  3572. KIRQL OldIrql;
  3573. int rc;
  3574. KeAcquireSpinLock(&NetTableListLock, &OldIrql);
  3575. for (NTE = NetTableList; NTE != NULL; NTE = NextNTE) {
  3576. NextNTE = NTE->NextOnNTL;
  3577. if (NTE->RefCnt == 0) {
  3578. ASSERT(NTE->DADState == DAD_STATE_INVALID);
  3579. //
  3580. // We want to destroy this NTE.
  3581. // We have to release the list lock
  3582. // before we can acquire the interface lock,
  3583. // but we need references to hold the NTEs.
  3584. //
  3585. AddRefNTE(NTE);
  3586. if (NextNTE != NULL)
  3587. AddRefNTE(NextNTE);
  3588. KeReleaseSpinLock(&NetTableListLock, OldIrql);
  3589. IF = NTE->IF;
  3590. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  3591. KeAcquireSpinLockAtDpcLevel(&NetTableListLock);
  3592. //
  3593. // Now that we have the appropriate locks.
  3594. // Is no one else using this NTE?
  3595. //
  3596. ReleaseNTE(NTE);
  3597. if (NTE->RefCnt == 0) {
  3598. //
  3599. // OK, we will destroy this NTE.
  3600. // First remove from the list.
  3601. //
  3602. RemoveNTEFromNetTableList(NTE);
  3603. //
  3604. // It is now safe to release the list lock,
  3605. // because the NTE is removed from the list.
  3606. // We continue to hold the interface lock,
  3607. // so nobody can find this NTE via the interface.
  3608. //
  3609. KeReleaseSpinLockFromDpcLevel(&NetTableListLock);
  3610. //
  3611. // Remove ADEs that reference this address.
  3612. // Note that this also removes from the interface's list,
  3613. // but does not free, the NTE itself.
  3614. // NB: In the case of DestroyIF, the ADEs are already
  3615. // removed from the interface and DestroyADEs does nothing.
  3616. //
  3617. DestroyADEs(IF, NTE);
  3618. //
  3619. // Release the loopback route.
  3620. //
  3621. rc = ControlLoopback(IF, &NTE->Address,
  3622. CONTROL_LOOPBACK_DESTROY);
  3623. ASSERT(rc);
  3624. KeReleaseSpinLock(&IF->Lock, OldIrql);
  3625. //
  3626. // Put this NTE on the destroy list.
  3627. //
  3628. NTE->NextOnNTL = DestroyList;
  3629. DestroyList = NTE;
  3630. KeAcquireSpinLock(&NetTableListLock, &OldIrql);
  3631. }
  3632. else { // if (NTE->RefCnt != 0)
  3633. //
  3634. // We will not be destroying this NTE after all.
  3635. // Release the interface lock but keep the list lock.
  3636. //
  3637. KeReleaseSpinLockFromDpcLevel(&IF->Lock);
  3638. }
  3639. //
  3640. // At this point, we have the list lock again
  3641. // so we can release our reference for NextNTE.
  3642. //
  3643. if (NextNTE != NULL)
  3644. ReleaseNTE(NextNTE);
  3645. }
  3646. }
  3647. KeReleaseSpinLock(&NetTableListLock, OldIrql);
  3648. while (DestroyList != NULL) {
  3649. NTE = DestroyList;
  3650. DestroyList = NTE->NextOnNTL;
  3651. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  3652. "NetTableCleanup(NTE %p, Addr %s) -> destroyed\n",
  3653. NTE, FormatV6Address(&NTE->Address)));
  3654. ReleaseIF(NTE->IF);
  3655. ExFreePool(NTE);
  3656. }
  3657. }
  3658. //* NetTableTimeout
  3659. //
  3660. // Called periodically from IPv6Timeout.
  3661. //
  3662. // Called with NO locks held.
  3663. // Callable from DPC context, not from thread context.
  3664. //
  3665. void
  3666. NetTableTimeout(void)
  3667. {
  3668. NetTableEntry *NTE;
  3669. int SawZeroReferences = FALSE;
  3670. //
  3671. // Because new NTEs are only added at the head of the list,
  3672. // we can unlock the list during our traversal
  3673. // and know that the traversal will terminate properly.
  3674. //
  3675. KeAcquireSpinLockAtDpcLevel(&NetTableListLock);
  3676. for (NTE = NetTableList; NTE != NULL; NTE = NTE->NextOnNTL) {
  3677. AddRefNTE(NTE);
  3678. KeReleaseSpinLockFromDpcLevel(&NetTableListLock);
  3679. //
  3680. // Check for Duplicate Address Detection timeout.
  3681. // The timer check here is only an optimization,
  3682. // because it is made without holding the appropriate lock.
  3683. //
  3684. if (NTE->DADTimer != 0)
  3685. DADTimeout(NTE);
  3686. //
  3687. // Perform lifetime expiration.
  3688. //
  3689. AddrConfTimeout(NTE);
  3690. KeAcquireSpinLockAtDpcLevel(&NetTableListLock);
  3691. ReleaseNTE(NTE);
  3692. //
  3693. // We assume that loads of RefCnt are atomic.
  3694. //
  3695. if (NTE->RefCnt == 0)
  3696. SawZeroReferences = TRUE;
  3697. }
  3698. KeReleaseSpinLockFromDpcLevel(&NetTableListLock);
  3699. if (SawZeroReferences)
  3700. NetTableCleanup();
  3701. }
  3702. //* InterfaceCleanup
  3703. //
  3704. // Cleans up any Interfaces with zero references.
  3705. //
  3706. // Called with NO locks held.
  3707. // Callable from thread or DPC context.
  3708. //
  3709. void
  3710. InterfaceCleanup(void)
  3711. {
  3712. Interface *DestroyList = NULL;
  3713. Interface *IF, **PrevIF;
  3714. KIRQL OldIrql;
  3715. KeAcquireSpinLock(&IFListLock, &OldIrql);
  3716. PrevIF = &IFList;
  3717. while ((IF = *PrevIF) != NULL) {
  3718. if (IF->RefCnt == 0) {
  3719. ASSERT(IsDisabledIF(IF));
  3720. *PrevIF = IF->Next;
  3721. IF->Next = DestroyList;
  3722. DestroyList = IF;
  3723. IPSInfo.ipsi_numif--;
  3724. } else {
  3725. PrevIF = &IF->Next;
  3726. }
  3727. }
  3728. KeReleaseSpinLock(&IFListLock, OldIrql);
  3729. while (DestroyList != NULL) {
  3730. IF = DestroyList;
  3731. DestroyList = IF->Next;
  3732. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  3733. "InterfaceCleanup(IF %u/%p) -> destroyed\n",
  3734. IF->Index, IF));
  3735. //
  3736. // ADEs should already be destroyed.
  3737. // We just need to cleanup NCEs and free the interface.
  3738. //
  3739. ASSERT(IF->ADE == NULL);
  3740. NeighborCacheDestroy(IF);
  3741. if (IF->MCastAddresses != NULL)
  3742. ExFreePool(IF->MCastAddresses);
  3743. DeferDeregisterInterface(IF);
  3744. }
  3745. }
  3746. //* InterfaceTimeout
  3747. //
  3748. // Called periodically from IPv6Timeout.
  3749. //
  3750. // Called with NO locks held.
  3751. // Callable from DPC context, not from thread context.
  3752. //
  3753. void
  3754. InterfaceTimeout(void)
  3755. {
  3756. static uint RecalcReachableTimer = 0;
  3757. int RecalcReachable;
  3758. int ForceRAs;
  3759. Interface *IF;
  3760. int SawZeroReferences = FALSE;
  3761. //
  3762. // Recalculate ReachableTime every few hours,
  3763. // even if no Router Advertisements are received.
  3764. //
  3765. if (RecalcReachableTimer == 0) {
  3766. RecalcReachable = TRUE;
  3767. RecalcReachableTimer = RECALC_REACHABLE_INTERVAL;
  3768. } else {
  3769. RecalcReachable = FALSE;
  3770. RecalcReachableTimer--;
  3771. }
  3772. //
  3773. // Grab the value of ForceRouterAdvertisements.
  3774. //
  3775. ForceRAs = InterlockedExchange(&ForceRouterAdvertisements, FALSE);
  3776. //
  3777. // Because new interfaces are only added at the head of the list,
  3778. // we can unlock the list during our traversal
  3779. // and know that the traversal will terminate properly.
  3780. //
  3781. KeAcquireSpinLockAtDpcLevel(&IFListLock);
  3782. for (IF = IFList; IF != NULL; IF = IF->Next) {
  3783. //
  3784. // We should not do any processing on an interface
  3785. // that has zero references. As an even stronger condition,
  3786. // we avoid doing any timeout processing if the interface
  3787. // is being destroyed. Of course, the interface might be
  3788. // destroyed after we drop the interface list lock.
  3789. //
  3790. if (! IsDisabledIF(IF)) {
  3791. AddRefIF(IF);
  3792. KeReleaseSpinLockFromDpcLevel(&IFListLock);
  3793. //
  3794. // Handle per-neighbor timeouts.
  3795. //
  3796. NeighborCacheTimeout(IF);
  3797. //
  3798. // Handle router solicitations.
  3799. // The timer check here is only an optimization,
  3800. // because it is made without holding the appropriate lock.
  3801. //
  3802. if (IF->RSTimer != 0)
  3803. RouterSolicitTimeout(IF);
  3804. //
  3805. // Handle router advertisements.
  3806. // The timer check here is only an optimization,
  3807. // because it is made without holding the appropriate lock.
  3808. //
  3809. if (IF->RATimer != 0)
  3810. RouterAdvertTimeout(IF, ForceRAs);
  3811. //
  3812. // Recalculate the reachable time.
  3813. //
  3814. if (RecalcReachable) {
  3815. KeAcquireSpinLockAtDpcLevel(&IF->Lock);
  3816. IF->ReachableTime = CalcReachableTime(IF->BaseReachableTime);
  3817. KeReleaseSpinLockFromDpcLevel(&IF->Lock);
  3818. }
  3819. KeAcquireSpinLockAtDpcLevel(&IFListLock);
  3820. ReleaseIF(IF);
  3821. }
  3822. //
  3823. // We assume that loads of RefCnt are atomic.
  3824. //
  3825. if (IF->RefCnt == 0)
  3826. SawZeroReferences = TRUE;
  3827. }
  3828. KeReleaseSpinLockFromDpcLevel(&IFListLock);
  3829. if (SawZeroReferences)
  3830. InterfaceCleanup();
  3831. }
  3832. //* InterfaceStartAdvertising
  3833. //
  3834. // If the interface is not currently advertising,
  3835. // makes it start advertising.
  3836. //
  3837. // Called with the interface locked.
  3838. // Caller must check whether the interface is disabled.
  3839. //
  3840. NTSTATUS
  3841. InterfaceStartAdvertising(Interface *IF)
  3842. {
  3843. ASSERT(! IsDisabledIF(IF));
  3844. ASSERT(IF->Flags & IF_FLAG_ROUTER_DISCOVERS);
  3845. if (!(IF->Flags & IF_FLAG_ADVERTISES)) {
  3846. //
  3847. // Join the all-routers multicast groups.
  3848. //
  3849. if (! JoinGroupAtAllScopes(IF, &AllRoutersOnLinkAddr,
  3850. ADE_SITE_LOCAL))
  3851. return STATUS_INSUFFICIENT_RESOURCES;
  3852. //
  3853. // A non-advertising interface is now advertising.
  3854. //
  3855. IF->Flags |= IF_FLAG_ADVERTISES;
  3856. //
  3857. // The reconnecting state is not useful
  3858. // for advertising interfaces because
  3859. // the interface will not receive RAs.
  3860. //
  3861. IF->Flags &= ~IF_FLAG_MEDIA_RECONNECTED;
  3862. //
  3863. // Remove addresses & routes that were auto-configured
  3864. // from Router Advertisements. Advertising interfaces
  3865. // must be manually configured. Better to remove it
  3866. // now than let it time-out at some random time.
  3867. //
  3868. AddrConfResetAutoConfig(IF, 0);
  3869. RouteTableResetAutoConfig(IF, 0);
  3870. InterfaceResetAutoConfig(IF);
  3871. //
  3872. // Start sending Router Advertisements.
  3873. //
  3874. IF->RATimer = 1; // Send first RA very quickly.
  3875. IF->RACount = MAX_INITIAL_RTR_ADVERTISEMENTS;
  3876. //
  3877. // Stop sending Router Solicitations.
  3878. //
  3879. IF->RSTimer = 0;
  3880. }
  3881. return STATUS_SUCCESS;
  3882. }
  3883. //* InterfaceStopAdvertising
  3884. //
  3885. // If the interface is currently advertising,
  3886. // stops the advertising behavior.
  3887. //
  3888. // Called with the interface locked.
  3889. // Caller must check whether the interface is disabled.
  3890. //
  3891. void
  3892. InterfaceStopAdvertising(Interface *IF)
  3893. {
  3894. ASSERT(! IsDisabledIF(IF));
  3895. if (IF->Flags & IF_FLAG_ADVERTISES) {
  3896. //
  3897. // Leave the all-routers multicast group.
  3898. //
  3899. LeaveGroupAtAllScopes(IF, &AllRoutersOnLinkAddr,
  3900. ADE_SITE_LOCAL);
  3901. //
  3902. // Stop sending Router Advertisements.
  3903. //
  3904. IF->Flags &= ~IF_FLAG_ADVERTISES;
  3905. IF->RATimer = 0;
  3906. //
  3907. // Remove addresses that were auto-configured
  3908. // from our own Router Advertisements.
  3909. // We will pick up new address lifetimes
  3910. // from other router's Advertisements.
  3911. // If some other router is not advertising
  3912. // the prefixes that this router was advertising,
  3913. // better to remove the addresses now than
  3914. // let them time-out at some random time.
  3915. //
  3916. AddrConfResetAutoConfig(IF, 0);
  3917. //
  3918. // There shouldn't be any auto-configured routes,
  3919. // but RouteTableResetAutoConfig also handles site prefixes.
  3920. //
  3921. RouteTableResetAutoConfig(IF, 0);
  3922. //
  3923. // Restore interface parameters.
  3924. //
  3925. InterfaceResetAutoConfig(IF);
  3926. //
  3927. // Send Router Solicitations again.
  3928. //
  3929. IF->RSCount = 0;
  3930. IF->RSTimer = 1;
  3931. }
  3932. }
  3933. //* InterfaceStartForwarding
  3934. //
  3935. // If the interface is not currently forwarding,
  3936. // makes it start forwarding.
  3937. //
  3938. // Called with the interface locked.
  3939. //
  3940. void
  3941. InterfaceStartForwarding(Interface *IF)
  3942. {
  3943. if (!(IF->Flags & IF_FLAG_FORWARDS)) {
  3944. //
  3945. // Any change in forwarding behavior requires InvalidRouteCache
  3946. // because FindNextHop uses IF_FLAG_FORWARDS. Also force the next RA
  3947. // for all advertising interfaces to be sent quickly,
  3948. // because their content might depend on forwarding behavior.
  3949. //
  3950. IF->Flags |= IF_FLAG_FORWARDS;
  3951. InterlockedIncrement(&NumForwardingInterfaces);
  3952. InvalidateRouteCache();
  3953. ForceRouterAdvertisements = TRUE;
  3954. }
  3955. }
  3956. //* InterfaceStopForwarding
  3957. //
  3958. // If the interface is currently forwarding,
  3959. // stops the forwarding behavior.
  3960. //
  3961. // Called with the interface locked.
  3962. //
  3963. void
  3964. InterfaceStopForwarding(Interface *IF)
  3965. {
  3966. if (IF->Flags & IF_FLAG_FORWARDS) {
  3967. //
  3968. // Any change in forwarding behavior requires InvalidRouteCache
  3969. // because FindNextHop uses IF_FLAG_FORWARDS. Also force the next RA
  3970. // for all advertising interfaces to be sent quickly,
  3971. // because their content might depend on forwarding behavior.
  3972. //
  3973. IF->Flags &= ~IF_FLAG_FORWARDS;
  3974. InterlockedDecrement(&NumForwardingInterfaces);
  3975. InvalidateRouteCache();
  3976. ForceRouterAdvertisements = TRUE;
  3977. }
  3978. }
  3979. //* AddrConfResetManualConfig
  3980. //
  3981. // Removes manually-configured addresses from the interface.
  3982. //
  3983. // Called with the interface already locked.
  3984. //
  3985. void
  3986. AddrConfResetManualConfig(Interface *IF)
  3987. {
  3988. AddressEntry *AnycastList = NULL;
  3989. AddressEntry *ADE, **PrevADE;
  3990. //
  3991. // We have to be careful about how we destroy addresses,
  3992. // because FindAndReleaseSolicitedNodeMAE will mess up our traversal.
  3993. //
  3994. PrevADE = &IF->ADE;
  3995. while ((ADE = *PrevADE) != NULL) {
  3996. //
  3997. // Is this a manually configured address?
  3998. //
  3999. switch (ADE->Type) {
  4000. case ADE_UNICAST: {
  4001. NetTableEntry *NTE = (NetTableEntry *) ADE;
  4002. if (NTE->AddrConf == ADDR_CONF_MANUAL) {
  4003. //
  4004. // Let NetTableTimeout destroy the address.
  4005. //
  4006. NTE->ValidLifetime = 0;
  4007. NTE->PreferredLifetime = 0;
  4008. }
  4009. break;
  4010. }
  4011. case ADE_ANYCAST:
  4012. //
  4013. // Most anycast addresses are manually configured.
  4014. // Subnet anycast addresses are the only exception.
  4015. // They are also the only anycast addresses
  4016. // which point to an NTE instead of the interface.
  4017. //
  4018. if (ADE->IF == IF) {
  4019. //
  4020. // Remove the ADE from the interface list.
  4021. //
  4022. *PrevADE = ADE->Next;
  4023. //
  4024. // Put the ADE on our temporary list.
  4025. //
  4026. ADE->Next = AnycastList;
  4027. AnycastList = ADE;
  4028. continue;
  4029. }
  4030. break;
  4031. }
  4032. PrevADE = &ADE->Next;
  4033. }
  4034. //
  4035. // Now we can safely process the anycast ADEs.
  4036. //
  4037. while ((ADE = AnycastList) != NULL) {
  4038. AnycastList = ADE->Next;
  4039. DeleteAAE(IF, (AnycastAddressEntry *)ADE);
  4040. }
  4041. }
  4042. //* InterfaceResetAutoConfig
  4043. //
  4044. // Resets interface parameters that are auto-configured
  4045. // from Router Advertisements.
  4046. //
  4047. // Called with the interface already locked.
  4048. //
  4049. void
  4050. InterfaceResetAutoConfig(Interface *IF)
  4051. {
  4052. IF->LinkMTU = IF->DefaultLinkMTU;
  4053. if (IF->BaseReachableTime != REACHABLE_TIME) {
  4054. IF->BaseReachableTime = REACHABLE_TIME;
  4055. IF->ReachableTime = CalcReachableTime(IF->BaseReachableTime);
  4056. }
  4057. IF->RetransTimer = RETRANS_TIMER;
  4058. IF->CurHopLimit = DefaultCurHopLimit;
  4059. }
  4060. //* InterfaceResetManualConfig
  4061. //
  4062. // Resets the manual configuration of the interface.
  4063. // Does not remove manual routes on the interface.
  4064. //
  4065. // Called with ZoneUpdateLock held.
  4066. //
  4067. void
  4068. InterfaceResetManualConfig(Interface *IF)
  4069. {
  4070. KeAcquireSpinLockAtDpcLevel(&IF->Lock);
  4071. if (! IsDisabledIF(IF)) {
  4072. //
  4073. // Reset manually-configured interface parameters.
  4074. //
  4075. IF->LinkMTU = IF->DefaultLinkMTU;
  4076. IF->Preference = IF->DefaultPreference;
  4077. if (IF->BaseReachableTime != REACHABLE_TIME) {
  4078. IF->BaseReachableTime = REACHABLE_TIME;
  4079. IF->ReachableTime = CalcReachableTime(IF->BaseReachableTime);
  4080. }
  4081. IF->RetransTimer = RETRANS_TIMER;
  4082. IF->DupAddrDetectTransmits = IF->DefaultDupAddrDetectTransmits;
  4083. IF->CurHopLimit = DefaultCurHopLimit;
  4084. //
  4085. // ZoneUpdateLock is held by our caller.
  4086. //
  4087. InitZoneIndices(IF);
  4088. //
  4089. // Remove manually-configured addresses.
  4090. //
  4091. AddrConfResetManualConfig(IF);
  4092. //
  4093. // Stop advertising and forwarding,
  4094. // if either of those behaviors are enabled.
  4095. //
  4096. InterfaceStopAdvertising(IF);
  4097. InterfaceStopForwarding(IF);
  4098. }
  4099. KeReleaseSpinLockFromDpcLevel(&IF->Lock);
  4100. }
  4101. //* InterfaceReset
  4102. //
  4103. // Resets manual configuration for all interfaces.
  4104. // Tunnel interfaces are destroyed.
  4105. // Other interfaces have their attributes reset to default values.
  4106. // Manually-configured addresses are removed.
  4107. //
  4108. // The end result should be the same as if the machine
  4109. // had just booted without any persistent configuration.
  4110. //
  4111. // Called with no locks held.
  4112. //
  4113. void
  4114. InterfaceReset(void)
  4115. {
  4116. Interface *IF;
  4117. KIRQL OldIrql;
  4118. //
  4119. // Because new interfaces are only added at the head of the list,
  4120. // we can unlock the list during our traversals
  4121. // and know that the traversal will terminate properly.
  4122. //
  4123. //
  4124. // First destroy any manually configured tunnel interfaces.
  4125. //
  4126. KeAcquireSpinLock(&IFListLock, &OldIrql);
  4127. for (IF = IFList; IF != NULL; IF = IF->Next) {
  4128. //
  4129. // We should not do any processing (even just AddRefIF) on an interface
  4130. // that has zero references. As an even stronger condition,
  4131. // we avoid doing any processing if the interface
  4132. // is being destroyed. Of course, the interface might be
  4133. // destroyed after we drop the interface list lock.
  4134. //
  4135. if (! IsDisabledIF(IF)) {
  4136. AddRefIF(IF);
  4137. KeReleaseSpinLock(&IFListLock, OldIrql);
  4138. if ((IF->Type == IF_TYPE_TUNNEL_6OVER4) ||
  4139. (IF->Type == IF_TYPE_TUNNEL_V6V4)) {
  4140. //
  4141. // Destroy the tunnel interface.
  4142. //
  4143. DestroyIF(IF);
  4144. }
  4145. KeAcquireSpinLock(&IFListLock, &OldIrql);
  4146. ReleaseIF(IF);
  4147. }
  4148. }
  4149. KeReleaseSpinLock(&IFListLock, OldIrql);
  4150. //
  4151. // Now reset the remaining interfaces,
  4152. // while holding ZoneUpdateLock so
  4153. // InterfaceResetManualConfig can reset
  4154. // the zone indices consistently across the interfaces.
  4155. //
  4156. KeAcquireSpinLock(&ZoneUpdateLock, &OldIrql);
  4157. KeAcquireSpinLockAtDpcLevel(&IFListLock);
  4158. for (IF = IFList; IF != NULL; IF = IF->Next) {
  4159. if (! IsDisabledIF(IF)) {
  4160. AddRefIF(IF);
  4161. KeReleaseSpinLockFromDpcLevel(&IFListLock);
  4162. //
  4163. // Reset the interface.
  4164. //
  4165. InterfaceResetManualConfig(IF);
  4166. KeAcquireSpinLockAtDpcLevel(&IFListLock);
  4167. ReleaseIF(IF);
  4168. }
  4169. }
  4170. KeReleaseSpinLockFromDpcLevel(&IFListLock);
  4171. KeReleaseSpinLock(&ZoneUpdateLock, OldIrql);
  4172. }
  4173. //* UpdateInterface
  4174. //
  4175. // Allows the forwarding & advertising attributes
  4176. // of an interface to be changed.
  4177. //
  4178. // Called with no locks held.
  4179. //
  4180. // Return codes:
  4181. // STATUS_INVALID_PARAMETER_1 Bad Interface.
  4182. // STATUS_INSUFFICIENT_RESOURCES
  4183. // STATUS_SUCCESS
  4184. //
  4185. NTSTATUS
  4186. UpdateInterface(
  4187. Interface *IF,
  4188. int Advertises,
  4189. int Forwards)
  4190. {
  4191. KIRQL OldIrql;
  4192. NTSTATUS Status = STATUS_SUCCESS;
  4193. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  4194. if (IsDisabledIF(IF)) {
  4195. //
  4196. // Do not update an interface that is being destroyed.
  4197. //
  4198. Status = STATUS_INVALID_PARAMETER_1;
  4199. }
  4200. else if (Advertises == -1) {
  4201. //
  4202. // Do not change the Advertises attribute.
  4203. //
  4204. }
  4205. else if (!(IF->Flags & IF_FLAG_ROUTER_DISCOVERS)) {
  4206. //
  4207. // The Advertises attribute can only be controlled
  4208. // on interfaces that support Neighbor Discovery.
  4209. //
  4210. Status = STATUS_INVALID_PARAMETER_1;
  4211. }
  4212. else {
  4213. //
  4214. // Control the advertising behavior of the interface.
  4215. //
  4216. if (Advertises) {
  4217. //
  4218. // Become an advertising interfacing,
  4219. // if it is not already.
  4220. //
  4221. Status = InterfaceStartAdvertising(IF);
  4222. }
  4223. else {
  4224. //
  4225. // Stop being an advertising interface,
  4226. // if it is currently advertising.
  4227. //
  4228. InterfaceStopAdvertising(IF);
  4229. }
  4230. }
  4231. //
  4232. // Control the forwarding behavior, if we haven't had an error.
  4233. //
  4234. if ((Status == STATUS_SUCCESS) && (Forwards != -1)) {
  4235. if (Forwards) {
  4236. //
  4237. // If the interface is not currently forwarding,
  4238. // enable forwarding.
  4239. //
  4240. InterfaceStartForwarding(IF);
  4241. }
  4242. else {
  4243. //
  4244. // If the interface is currently forwarding,
  4245. // disable forwarding.
  4246. //
  4247. InterfaceStopForwarding(IF);
  4248. }
  4249. }
  4250. if (IsMCastSyncNeeded(IF))
  4251. DeferSynchronizeMulticastAddresses(IF);
  4252. KeReleaseSpinLock(&IF->Lock, OldIrql);
  4253. return Status;
  4254. }
  4255. //* ReconnectInterface
  4256. //
  4257. // Reconnect the interface. Called when a media connect notification
  4258. // is received (SetInterfaceLinkStatus) or when processing a renew
  4259. // request by IOCTL_IPV6_UPDATE_INTERFACE (IoctlUpdateInterface).
  4260. //
  4261. // Called with the interface already locked.
  4262. //
  4263. void
  4264. ReconnectInterface(
  4265. Interface *IF)
  4266. {
  4267. ASSERT(!IsDisabledIF(IF) && !(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED));
  4268. //
  4269. // Purge potentially obsolete link-layer information.
  4270. // Things might have changed while we were unplugged.
  4271. //
  4272. NeighborCacheFlush(IF, NULL);
  4273. //
  4274. // Rejoin multicast groups and restart Duplicate Address Detection.
  4275. //
  4276. // Preferred unicast addresses are registered with TDI when
  4277. // duplicate address detection completes (or is disabled).
  4278. //
  4279. ReconnectADEs(IF);
  4280. if (IF->Flags & IF_FLAG_ROUTER_DISCOVERS) {
  4281. if (IF->Flags & IF_FLAG_ADVERTISES) {
  4282. //
  4283. // Send a Router Advertisement very soon.
  4284. //
  4285. IF->RATimer = 1;
  4286. }
  4287. else {
  4288. //
  4289. // Start sending Router Solicitations.
  4290. //
  4291. IF->RSCount = 0;
  4292. IF->RSTimer = 1;
  4293. //
  4294. // Remember that this interface was just reconnected,
  4295. // so when we receive a Router Advertisement
  4296. // we can take special action.
  4297. //
  4298. IF->Flags |= IF_FLAG_MEDIA_RECONNECTED;
  4299. }
  4300. }
  4301. //
  4302. // We might have moved to a new link.
  4303. // Force the generation of a new anonymous interface identifier.
  4304. // This only really makes a difference if we generate
  4305. // new addresses on this link - if it's the same link then
  4306. // we continue to use our old addresses, both public & anonymous.
  4307. //
  4308. IF->AnonStateAge = 0;
  4309. }
  4310. //* DisconnectInterface
  4311. //
  4312. // Disconnect the interface. Called when a media disconnect
  4313. // notification is received (SetInterfaceLinkStatus) for a connected
  4314. // interface.
  4315. //
  4316. // Called with the interface already locked.
  4317. //
  4318. void
  4319. DisconnectInterface(
  4320. Interface *IF)
  4321. {
  4322. ASSERT(!IsDisabledIF(IF) && (IF->Flags & IF_FLAG_MEDIA_DISCONNECTED));
  4323. //
  4324. // Deregister any preferred unicast addresses from TDI.
  4325. //
  4326. DisconnectADEs(IF);
  4327. }
  4328. //* SetInterfaceLinkStatus
  4329. //
  4330. // Change the interface's link status. In particular,
  4331. // set whether the media is connected or disconnected.
  4332. //
  4333. // May be called when the interface has zero references
  4334. // and is already being destroyed.
  4335. //
  4336. void
  4337. SetInterfaceLinkStatus(
  4338. void *Context,
  4339. int MediaConnected) // TRUE or FALSE.
  4340. {
  4341. Interface *IF = (Interface *) Context;
  4342. KIRQL OldIrql;
  4343. //
  4344. // Note that media-connect/disconnect events
  4345. // can be "lost". We are not informed if the
  4346. // cable is unplugged/replugged while we are
  4347. // shutdown, hibernating, or on standby.
  4348. //
  4349. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  4350. "SetInterfaceLinkStatus(IF %p) -> %s\n",
  4351. IF, MediaConnected ? "connected" : "disconnected"));
  4352. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  4353. if (! IsDisabledIF(IF)) {
  4354. if (MediaConnected) {
  4355. if (IF->Flags & IF_FLAG_MEDIA_DISCONNECTED) {
  4356. //
  4357. // The cable was plugged back in.
  4358. //
  4359. IF->Flags &= ~IF_FLAG_MEDIA_DISCONNECTED;
  4360. //
  4361. // Changes in IF_FLAG_MEDIA_DISCONNECTED must
  4362. // invalidate the route cache.
  4363. //
  4364. InvalidateRouteCache();
  4365. }
  4366. //
  4367. // A connect event implies a change in the interface state
  4368. // regardless of whether the interface is already connected.
  4369. // Hence we process it outside the 'if' clause.
  4370. //
  4371. ReconnectInterface(IF);
  4372. }
  4373. else {
  4374. if (!(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED)) {
  4375. //
  4376. // The cable was unplugged.
  4377. //
  4378. IF->Flags = (IF->Flags | IF_FLAG_MEDIA_DISCONNECTED) &~
  4379. IF_FLAG_MEDIA_RECONNECTED;
  4380. //
  4381. // Changes in IF_FLAG_MEDIA_DISCONNECTED must
  4382. // invalidate the route cache.
  4383. //
  4384. InvalidateRouteCache();
  4385. //
  4386. // A disconnect event implies a change in the interface
  4387. // state only if the interface is already connected.
  4388. // Hence we process it inside the 'if' clause.
  4389. //
  4390. DisconnectInterface(IF);
  4391. }
  4392. }
  4393. }
  4394. KeReleaseSpinLock(&IF->Lock, OldIrql);
  4395. }