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.

1403 lines
28 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. timeouts.c - Timeout handlers.
  5. Abstract:
  6. All timeout handlers for the ATMARP client.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. arvindm 08-01-96 Created
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. #define _FILENUMBER 'EMIT'
  15. VOID
  16. AtmArpServerConnectTimeout(
  17. IN PATMARP_TIMER pTimer,
  18. IN PVOID Context
  19. )
  20. /*++
  21. Routine Description:
  22. This timeout indicates that enough time has passed since a previous
  23. failed attempt at connecting to the ARP server. Try again now.
  24. Arguments:
  25. pTimer - Pointer to timer that went off
  26. Context - Actually a pointer to our ATMARP interface structure
  27. Return Value:
  28. None
  29. --*/
  30. {
  31. PATMARP_INTERFACE pInterface;
  32. ULONG rc; // Ref Count
  33. pInterface = (PATMARP_INTERFACE)Context;
  34. AA_STRUCT_ASSERT(pInterface, aai);
  35. AA_ACQUIRE_IF_LOCK(pInterface);
  36. rc = AtmArpDereferenceInterface(pInterface); // Timer ref
  37. //
  38. // Continue only if the Interface is still alive
  39. //
  40. if (rc > 0)
  41. {
  42. if (pInterface->AdminState == IF_STATUS_UP)
  43. {
  44. AADEBUGP(AAD_INFO, ("Server Connect timeout on IF 0x%x\n", pInterface));
  45. //
  46. // Restart registration
  47. //
  48. AtmArpStartRegistration(pInterface);
  49. //
  50. // IF lock is released by the above routine.
  51. }
  52. else
  53. {
  54. AA_RELEASE_IF_LOCK(pInterface);
  55. }
  56. }
  57. // else the Interface is gone!
  58. return;
  59. }
  60. VOID
  61. AtmArpRegistrationTimeout(
  62. IN PATMARP_TIMER pTimer,
  63. IN PVOID Context
  64. )
  65. /*++
  66. Routine Description:
  67. This is called if we timed out waiting for registration to a server
  68. to complete. If we have retries left for this server, we send another
  69. ARP Request to register ourselves. Otherwise, we close all VCs to this
  70. server, move to the next server in the server list, and wait for a while
  71. before initiating registration to this new server.
  72. Arguments:
  73. pTimer - Pointer to timer that went off
  74. Context - Actually a pointer to our ATMARP interface structure
  75. Return Value:
  76. None
  77. --*/
  78. {
  79. PATMARP_INTERFACE pInterface;
  80. ULONG rc; // Ref Count
  81. pInterface = (PATMARP_INTERFACE)Context;
  82. AA_STRUCT_ASSERT(pInterface, aai);
  83. AADEBUGP(AAD_INFO, ("Registration timeout: pIf 0x%x, IF Flags 0x%x\n",
  84. pInterface, pInterface->Flags));
  85. AA_ACQUIRE_IF_LOCK(pInterface);
  86. rc = AtmArpDereferenceInterface(pInterface); // Timer ref
  87. //
  88. // Continue only if the Interface is still alive
  89. //
  90. if (rc > 0)
  91. {
  92. AtmArpRetryServerRegistration(pInterface);
  93. //
  94. // The IF lock is released within the above.
  95. //
  96. }
  97. //
  98. // else the Interface is gone.
  99. //
  100. return;
  101. }
  102. VOID
  103. AtmArpServerRefreshTimeout(
  104. IN PATMARP_TIMER pTimer,
  105. IN PVOID Context
  106. )
  107. /*++
  108. Routine Description:
  109. This routine is periodically invoked so that we can refresh our
  110. IP address+ATM address info with the ARP server. We do so by registering
  111. the first of our local IP addresses. We mark all the other IP addresses
  112. configured on this interface as "not registered", so that, when the first
  113. one completes, we register all the rest.
  114. Arguments:
  115. pTimer - Pointer to timer that went off
  116. Context - Actually a pointer to our ATMARP interface structure
  117. Return Value:
  118. None
  119. --*/
  120. {
  121. PATMARP_INTERFACE pInterface;
  122. PIP_ADDRESS_ENTRY pIPAddressEntry;
  123. ULONG rc; // Ref Count
  124. pInterface = (PATMARP_INTERFACE)Context;
  125. AA_STRUCT_ASSERT(pInterface, aai);
  126. AADEBUGP(AAD_INFO, ("Server Refresh timeout: IF 0x%x\n", pInterface));
  127. //
  128. // We also use this opportunity to clean out orphan entries in the
  129. // Arp Table.
  130. //
  131. AtmArpCleanupArpTable(pInterface);
  132. AA_ACQUIRE_IF_LOCK(pInterface);
  133. rc = AtmArpDereferenceInterface(pInterface); // Timer ref
  134. //
  135. // Continue only if the Interface is still alive
  136. //
  137. if (rc > 0)
  138. {
  139. if (pInterface->AdminState == IF_STATUS_UP)
  140. {
  141. //
  142. // Mark all local addresses as not registered.
  143. //
  144. pIPAddressEntry = &(pInterface->LocalIPAddress);
  145. while (pIPAddressEntry != (PIP_ADDRESS_ENTRY)NULL)
  146. {
  147. pIPAddressEntry->IsRegistered = FALSE;
  148. pIPAddressEntry = pIPAddressEntry->pNext;
  149. }
  150. //
  151. // Start registering the first one.
  152. //
  153. pInterface->RetriesLeft = pInterface->MaxRegistrationAttempts - 1;
  154. AA_SET_FLAG(
  155. pInterface->Flags,
  156. AA_IF_SERVER_STATE_MASK,
  157. AA_IF_SERVER_NO_CONTACT);
  158. AtmArpStartRegistration(pInterface);
  159. //
  160. // The IF lock is released in the above routine.
  161. //
  162. }
  163. else
  164. {
  165. AA_RELEASE_IF_LOCK(pInterface);
  166. }
  167. }
  168. //
  169. // else the Interface is gone!
  170. //
  171. return;
  172. }
  173. VOID
  174. AtmArpAddressResolutionTimeout(
  175. IN PATMARP_TIMER pTimer,
  176. IN PVOID Context
  177. )
  178. /*++
  179. Routine Description:
  180. This is called when we time out waiting for a response to an ARP Request
  181. we had sent ages ago in order to resolve/refresh an IP entry.
  182. First, check if the IP address got resolved anyway (e.g. an InARP Reply
  183. on a PVC). If so, we don't have to do anything. Otherwise, check if we
  184. have tried enough times. If we have retries left, send another ARP
  185. Request.
  186. If we have run out of retries, delete the IP entry, and any VCs going to it.
  187. Arguments:
  188. pTimer - Pointer to timer that went off
  189. Context - Actually a pointer to our ATMARP IP Entry structure
  190. Return Value:
  191. None
  192. --*/
  193. {
  194. PATMARP_IP_ENTRY pIpEntry; // IP Entry being ARP'ed for.
  195. ULONG Flags; // On IP Entry
  196. PATMARP_VC pVc; // VC to this IP destination
  197. PATMARP_INTERFACE pInterface;
  198. ULONG rc; // Ref Count on IP Entry
  199. IP_ADDRESS DstIPAddress; // Address being resolved
  200. IP_ADDRESS UNALIGNED * pSrcIPAddress; // Our IP address
  201. #ifdef IPMCAST
  202. BOOLEAN IsMARSProblem;
  203. #endif
  204. #ifdef IPMCAST
  205. IsMARSProblem = FALSE;
  206. #endif
  207. pIpEntry = (PATMARP_IP_ENTRY)Context;
  208. AA_STRUCT_ASSERT(pIpEntry, aip);
  209. AA_ACQUIRE_IE_LOCK(pIpEntry);
  210. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  211. Flags = pIpEntry->Flags;
  212. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer reference
  213. //
  214. // Continue only if the IP Entry still exists
  215. //
  216. if (rc > 0)
  217. {
  218. AADEBUGP(AAD_INFO,
  219. ("Addr Resolution timeout: pIpEntry 0x%x, Flags 0x%x, IP Addr: %d.%d.%d.%d\n",
  220. pIpEntry,
  221. pIpEntry->Flags,
  222. ((PUCHAR)&(pIpEntry->IPAddress))[0],
  223. ((PUCHAR)&(pIpEntry->IPAddress))[1],
  224. ((PUCHAR)&(pIpEntry->IPAddress))[2],
  225. ((PUCHAR)&(pIpEntry->IPAddress))[3]
  226. ));
  227. //
  228. // Check if the entry got resolved somehow.
  229. //
  230. if (!AA_IS_FLAG_SET(
  231. Flags,
  232. AA_IP_ENTRY_STATE_MASK,
  233. AA_IP_ENTRY_RESOLVED))
  234. {
  235. //
  236. // We are still trying to resolve this. See if we have
  237. // retries left.
  238. //
  239. pInterface = pIpEntry->pInterface;
  240. if (pIpEntry->RetriesLeft != 0)
  241. {
  242. pIpEntry->RetriesLeft--;
  243. //
  244. // Try again: start addr resolution timer, send ARP Request.
  245. //
  246. pSrcIPAddress = &(pInterface->LocalIPAddress.IPAddress);
  247. DstIPAddress = pIpEntry->IPAddress;
  248. AtmArpStartTimer(
  249. pInterface,
  250. &(pIpEntry->Timer),
  251. AtmArpAddressResolutionTimeout,
  252. pInterface->AddressResolutionTimeout,
  253. (PVOID)pIpEntry
  254. );
  255. AA_REF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer reference
  256. AA_RELEASE_IE_LOCK(pIpEntry);
  257. #ifdef IPMCAST
  258. if (AA_IS_FLAG_SET(Flags,
  259. AA_IP_ENTRY_ADDR_TYPE_MASK,
  260. AA_IP_ENTRY_ADDR_TYPE_UCAST))
  261. {
  262. AtmArpSendARPRequest(
  263. pInterface,
  264. pSrcIPAddress,
  265. &DstIPAddress
  266. );
  267. }
  268. else
  269. {
  270. AtmArpMcSendRequest(
  271. pInterface,
  272. &DstIPAddress
  273. );
  274. }
  275. #else
  276. AtmArpSendARPRequest(
  277. pInterface,
  278. pSrcIPAddress,
  279. &DstIPAddress
  280. );
  281. #endif // IPMCAST
  282. }
  283. else
  284. {
  285. //
  286. // We are out of retries. Check if we were REvalidating
  287. // an entry that was aged out. If so, try revalidating
  288. // using InARP on a VC attached to it -- if no such VC
  289. // exists, delete the IP Entry.
  290. //
  291. if ((pIpEntry->pAtmEntry != NULL_PATMARP_ATM_ENTRY) &&
  292. #ifdef IPMCAST
  293. (AA_IS_FLAG_SET(Flags,
  294. AA_IP_ENTRY_ADDR_TYPE_MASK,
  295. AA_IP_ENTRY_ADDR_TYPE_UCAST)) &&
  296. #endif // IPMCAST
  297. (pIpEntry->pAtmEntry->pVcList != NULL_PATMARP_VC))
  298. {
  299. pVc = pIpEntry->pAtmEntry->pVcList;
  300. //
  301. // Try revalidating now via InARP.
  302. //
  303. AA_SET_FLAG(
  304. pIpEntry->Flags,
  305. AA_IP_ENTRY_STATE_MASK,
  306. AA_IP_ENTRY_INARPING
  307. );
  308. AtmArpStartTimer(
  309. pInterface,
  310. &(pIpEntry->Timer),
  311. AtmArpIPEntryInARPWaitTimeout,
  312. pInterface->InARPWaitTimeout,
  313. (PVOID)pIpEntry
  314. );
  315. AA_REF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer reference
  316. AA_RELEASE_IE_LOCK(pIpEntry);
  317. #ifdef VC_REFS_ON_SENDS
  318. AA_ACQUIRE_VC_LOCK(pVc);
  319. #endif // VC_REFS_ON_SENDS
  320. AtmArpSendInARPRequest(pVc);
  321. }
  322. else
  323. {
  324. AtmArpAbortIPEntry(pIpEntry);
  325. //
  326. // The IP Entry lock is released in the above routine.
  327. //
  328. #ifdef IPMCAST
  329. IsMARSProblem = AA_IS_FLAG_SET(Flags,
  330. AA_IP_ENTRY_ADDR_TYPE_MASK,
  331. AA_IP_ENTRY_ADDR_TYPE_NUCAST);
  332. #endif // IPMCAST
  333. }
  334. }
  335. }
  336. else
  337. {
  338. //
  339. // The IP Entry must have got resolved.
  340. // Nothing more to be done.
  341. //
  342. AA_RELEASE_IE_LOCK(pIpEntry);
  343. }
  344. }
  345. // else the IP Entry is gone
  346. #ifdef IPMCAST
  347. if (IsMARSProblem)
  348. {
  349. AtmArpMcHandleMARSFailure(pInterface, FALSE);
  350. }
  351. #endif // IPMCAST
  352. return;
  353. }
  354. VOID
  355. AtmArpIPEntryInARPWaitTimeout(
  356. IN PATMARP_TIMER pTimer,
  357. IN PVOID Context
  358. )
  359. /*++
  360. Routine Description:
  361. This timeout happens if we don't receive an InARP Reply in response
  362. to an InARP Request sent in order to revalidate an IP Entry. Delete
  363. the entry.
  364. Arguments:
  365. pTimer - Pointer to timer that went off
  366. Context - Actually a pointer to our ATMARP IP Entry structure
  367. Return Value:
  368. None
  369. --*/
  370. {
  371. PATMARP_IP_ENTRY pIpEntry;
  372. ULONG rc; // Ref Count on IP Entry
  373. pIpEntry = (PATMARP_IP_ENTRY)Context;
  374. AA_STRUCT_ASSERT(pIpEntry, aip);
  375. AA_ACQUIRE_IE_LOCK(pIpEntry);
  376. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  377. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TIMER);
  378. if (rc > 0)
  379. {
  380. AtmArpAbortIPEntry(pIpEntry);
  381. //
  382. // The IP Entry lock is released in the above routine.
  383. //
  384. }
  385. //
  386. // else the entry is gone.
  387. //
  388. }
  389. VOID
  390. AtmArpPVCInARPWaitTimeout(
  391. IN PATMARP_TIMER pTimer,
  392. IN PVOID Context
  393. )
  394. /*++
  395. Routine Description:
  396. This timeout happens if we don't receive a reply to an InARP Request
  397. we had sent in order to resolve a PVC. We send another InARP Request,
  398. and restart this timer, but to fire after a longer delay.
  399. Arguments:
  400. pTimer - Pointer to timer that went off
  401. Context - Actually a pointer to our ATMARP VC structure
  402. Return Value:
  403. None
  404. --*/
  405. {
  406. PATMARP_VC pVc;
  407. PATMARP_INTERFACE pInterface;
  408. ULONG rc; // Ref Count on VC
  409. pVc = (PATMARP_VC)Context;
  410. AA_STRUCT_ASSERT(pVc, avc);
  411. AA_ACQUIRE_VC_LOCK(pVc);
  412. rc = AtmArpDereferenceVc(pVc); // Timer ref
  413. if (rc > 0)
  414. {
  415. AA_ASSERT(AA_IS_FLAG_SET(
  416. pVc->Flags,
  417. AA_VC_ARP_STATE_MASK,
  418. AA_VC_INARP_IN_PROGRESS));
  419. pInterface = pVc->pInterface;
  420. AtmArpStartTimer(
  421. pInterface,
  422. &(pVc->Timer),
  423. AtmArpPVCInARPWaitTimeout,
  424. (2 * pInterface->InARPWaitTimeout),
  425. (PVOID)pVc
  426. );
  427. AtmArpReferenceVc(pVc); // Timer ref
  428. #ifndef VC_REFS_ON_SENDS
  429. AA_RELEASE_VC_LOCK(pVc);
  430. #endif // VC_REFS_ON_SENDS
  431. //
  432. // Send another InARP Request on the PVC
  433. //
  434. AtmArpSendInARPRequest(pVc);
  435. }
  436. //
  437. // else the VC is gone
  438. //
  439. }
  440. VOID
  441. AtmArpIPEntryAgingTimeout(
  442. IN PATMARP_TIMER pTimer,
  443. IN PVOID Context
  444. )
  445. /*++
  446. Routine Description:
  447. This routine is called if some time has passed (~15 minutes) since an
  448. IP entry was last resolved/refreshed.
  449. If there is no VC attached to this IP entry, we delete it. Otherwise,
  450. revalidate the entry:
  451. - Mark this entry so that packets are temporarily queued rather
  452. than sent.
  453. - If "the VC attached to this entry" is a PVC, send an InARP Request
  454. to validate the entry, otherwise, send an ARP Request to the server
  455. to validate.
  456. Arguments:
  457. pTimer - Pointer to timer that went off
  458. Context - Actually a pointer to our ATMARP IP Entry structure
  459. Return Value:
  460. None
  461. --*/
  462. {
  463. PATMARP_IP_ENTRY pIpEntry; // IP Entry that has aged out
  464. ULONG rc; // Ref count on IP Entry
  465. PATMARP_VC pVc; // VC going to this IP Entry
  466. ULONG VcFlags; // Flags on above VC
  467. PATMARP_INTERFACE pInterface;
  468. IP_ADDRESS DstIPAddress; // IP Address on this Entry
  469. pIpEntry = (PATMARP_IP_ENTRY)Context;
  470. AA_STRUCT_ASSERT(pIpEntry, aip);
  471. VcFlags = 0;
  472. AA_ACQUIRE_IE_LOCK(pIpEntry);
  473. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  474. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer ref
  475. //
  476. // Continue only if the entry hasn't gone away.
  477. //
  478. if (rc != 0)
  479. {
  480. //
  481. // Continue only if the Interface is not going down
  482. //
  483. pInterface = pIpEntry->pInterface;
  484. if (pInterface->AdminState == IF_STATUS_UP)
  485. {
  486. PATMARP_ATM_ENTRY pAtmEntry;
  487. pAtmEntry = pIpEntry->pAtmEntry;
  488. if (pAtmEntry != NULL_PATMARP_ATM_ENTRY)
  489. {
  490. AA_ACQUIRE_AE_LOCK_DPC(pAtmEntry);
  491. pVc = pAtmEntry->pVcList;
  492. if (pVc != NULL_PATMARP_VC)
  493. {
  494. VcFlags = pVc->Flags;
  495. }
  496. AA_RELEASE_AE_LOCK_DPC(pAtmEntry);
  497. }
  498. else
  499. {
  500. pVc = NULL_PATMARP_VC;
  501. }
  502. AADEBUGP(AAD_INFO,
  503. ("Aged out IP Entry 0x%x, Flags 0x%x, IP Addr: %d.%d.%d.%d, VC: 0x%x\n",
  504. pIpEntry,
  505. pIpEntry->Flags,
  506. ((PUCHAR)(&(pIpEntry->IPAddress)))[0],
  507. ((PUCHAR)(&(pIpEntry->IPAddress)))[1],
  508. ((PUCHAR)(&(pIpEntry->IPAddress)))[2],
  509. ((PUCHAR)(&(pIpEntry->IPAddress)))[3],
  510. pVc
  511. ) );
  512. #ifdef IPMCAST
  513. if ((pVc != NULL_PATMARP_VC) &&
  514. (AA_IS_FLAG_SET(pIpEntry->Flags,
  515. AA_IP_ENTRY_ADDR_TYPE_MASK,
  516. AA_IP_ENTRY_ADDR_TYPE_UCAST)))
  517. #else
  518. if (pVc != NULL_PATMARP_VC)
  519. #endif // IPMCAST
  520. {
  521. //
  522. // There is atleast one VC going to this IP Address.
  523. // So we try to revalidate this IP entry: use InARP
  524. // if the VC is a PVC, otherwise use ARP.
  525. //
  526. //
  527. // First mark this entry so that we don't send packets
  528. // to this destination till it is revalidated.
  529. //
  530. pIpEntry->Flags |= AA_IP_ENTRY_AGED_OUT;
  531. if (AA_IS_FLAG_SET(VcFlags, AA_VC_TYPE_MASK, AA_VC_TYPE_PVC))
  532. {
  533. //
  534. // PVC; send InARP Request: actually, we fire off a timer
  535. // at whose expiry we send the InARP Request.
  536. //
  537. AtmArpStartTimer(
  538. pInterface,
  539. &(pIpEntry->Timer),
  540. AtmArpIPEntryInARPWaitTimeout,
  541. pInterface->InARPWaitTimeout,
  542. (PVOID)pIpEntry
  543. );
  544. AA_SET_FLAG(pIpEntry->Flags, AA_IP_ENTRY_STATE_MASK, AA_IP_ENTRY_INARPING);
  545. AA_REF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer ref
  546. AA_RELEASE_IE_LOCK(pIpEntry);
  547. #ifdef VC_REFS_ON_SENDS
  548. AA_ACQUIRE_VC_LOCK(pVc);
  549. #endif // VC_REFS_ON_SENDS
  550. AtmArpSendInARPRequest(pVc);
  551. }
  552. else
  553. {
  554. //
  555. // SVC; send ARP Request
  556. //
  557. AtmArpStartTimer(
  558. pInterface,
  559. &(pIpEntry->Timer),
  560. AtmArpAddressResolutionTimeout,
  561. pInterface->AddressResolutionTimeout,
  562. (PVOID)pIpEntry
  563. );
  564. pIpEntry->RetriesLeft = 0;
  565. AA_REF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer ref
  566. AA_SET_FLAG(pIpEntry->Flags, AA_IP_ENTRY_STATE_MASK, AA_IP_ENTRY_ARPING);
  567. DstIPAddress = pIpEntry->IPAddress;
  568. AA_RELEASE_IE_LOCK(pIpEntry);
  569. AtmArpSendARPRequest(
  570. pInterface,
  571. &(pInterface->LocalIPAddress.IPAddress),
  572. &DstIPAddress
  573. );
  574. }
  575. }
  576. else
  577. {
  578. //
  579. // No VCs attached to this IP Entry; Delete it.
  580. //
  581. AtmArpAbortIPEntry(pIpEntry);
  582. //
  583. // The IP Entry lock is released in the above routine.
  584. //
  585. }
  586. }
  587. else
  588. {
  589. //
  590. // The Interface is going down.
  591. //
  592. AA_RELEASE_IE_LOCK(pIpEntry);
  593. }
  594. }
  595. //
  596. // else the IP Entry is gone
  597. //
  598. return;
  599. }
  600. VOID
  601. AtmArpVcAgingTimeout(
  602. IN PATMARP_TIMER pTimer,
  603. IN PVOID Context
  604. )
  605. /*++
  606. Routine Description:
  607. This routine is called if there hasn't been traffic on a VC for
  608. some time. We should be running this timer on a VC only if it is
  609. an SVC.
  610. Close the VC.
  611. Arguments:
  612. pTimer - Pointer to timer that went off
  613. Context - Actually a pointer to our ATMARP VC
  614. Return Value:
  615. None
  616. --*/
  617. {
  618. PATMARP_VC pVc; // VC that has aged out
  619. ULONG rc; // Ref Count on the VC
  620. PATMARP_INTERFACE pInterface;
  621. pVc = (PATMARP_VC)Context;
  622. AA_STRUCT_ASSERT(pVc, avc);
  623. AA_ASSERT(AA_IS_FLAG_SET(pVc->Flags, AA_VC_TYPE_MASK, AA_VC_TYPE_SVC));
  624. AADEBUGP(AAD_INFO, ("Aged out VC %x, Flags %x, ATMEntry %x\n",
  625. pVc, pVc->Flags, pVc->pAtmEntry));
  626. #if DBG
  627. if (pVc->pAtmEntry)
  628. {
  629. AADEBUGPATMADDR(AAD_INFO, "To ATM Addr:", &pVc->pAtmEntry->ATMAddress);
  630. }
  631. #endif
  632. AA_ACQUIRE_VC_LOCK(pVc);
  633. rc = AtmArpDereferenceVc(pVc); // Timer ref
  634. //
  635. // Continue only if the VC hasn't gone away in the meantime.
  636. //
  637. if (rc > 0)
  638. {
  639. //
  640. // Continue only if the Interface isn't going down.
  641. //
  642. pInterface = pVc->pInterface;
  643. if (pInterface->AdminState == IF_STATUS_UP)
  644. {
  645. AADEBUGP(AAD_INFO,
  646. ("Aged out VC 0x%x, RefCount %d, Flags 0x%x, pAtmEntry 0x%x\n",
  647. pVc, pVc->RefCount, pVc->Flags, pVc->pAtmEntry));
  648. AtmArpCloseCall(pVc);
  649. }
  650. else
  651. {
  652. //
  653. // The interface is going down.
  654. //
  655. AA_RELEASE_VC_LOCK(pVc);
  656. }
  657. }
  658. //
  659. // else the VC is gone
  660. //
  661. return;
  662. }
  663. VOID
  664. AtmArpNakDelayTimeout(
  665. IN PATMARP_TIMER pTimer,
  666. IN PVOID Context
  667. )
  668. /*++
  669. Routine Description:
  670. This routine is called if sufficient time has elapsed since we last
  671. received a NAK for an IP address. This means that we can try again
  672. (if necessary) to resolve this IP address.
  673. Arguments:
  674. pTimer - Pointer to timer that went off
  675. Context - Actually a pointer to our ATMARP IP Entry structure
  676. Return Value:
  677. None
  678. --*/
  679. {
  680. PATMARP_IP_ENTRY pIpEntry;
  681. PATMARP_INTERFACE pInterface;
  682. ULONG rc;
  683. pIpEntry = (PATMARP_IP_ENTRY)Context;
  684. AA_STRUCT_ASSERT(pIpEntry, aip);
  685. AA_ASSERT(AA_IS_FLAG_SET(pIpEntry->Flags,
  686. AA_IP_ENTRY_STATE_MASK,
  687. AA_IP_ENTRY_SEEN_NAK));
  688. AADEBUGP(AAD_INFO, ("NakDelay timeout: pIpEntry 0x%x, IP Addr: %d.%d.%d.%d\n",
  689. pIpEntry,
  690. ((PUCHAR)(&(pIpEntry->IPAddress)))[0],
  691. ((PUCHAR)(&(pIpEntry->IPAddress)))[1],
  692. ((PUCHAR)(&(pIpEntry->IPAddress)))[2],
  693. ((PUCHAR)(&(pIpEntry->IPAddress)))[3]
  694. ));
  695. pInterface = pIpEntry->pInterface;
  696. AA_STRUCT_ASSERT(pInterface, aai);
  697. AA_ACQUIRE_IE_LOCK(pIpEntry);
  698. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  699. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TIMER);
  700. if (rc > 0)
  701. {
  702. AA_SET_FLAG(pIpEntry->Flags,
  703. AA_IP_ENTRY_STATE_MASK,
  704. AA_IP_ENTRY_IDLE2);
  705. AtmArpStartTimer(
  706. pInterface,
  707. &(pIpEntry->Timer),
  708. AtmArpIPEntryAgingTimeout,
  709. pInterface->ARPEntryAgingTimeout,
  710. (PVOID)pIpEntry
  711. );
  712. AA_REF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer ref
  713. AA_RELEASE_IE_LOCK(pIpEntry);
  714. }
  715. //
  716. // else the IP Entry is gone.
  717. //
  718. return;
  719. }
  720. #ifdef IPMCAST
  721. VOID
  722. AtmArpMcMARSRegistrationTimeout(
  723. IN PATMARP_TIMER pTimer,
  724. IN PVOID Context
  725. )
  726. /*++
  727. Routine Description:
  728. We haven't received acknowledgement of registering with the MARS.
  729. If we have retries left for this, try registering again. Otherwise,
  730. process this as a MARS failure.
  731. Arguments:
  732. pTimer - Pointer to timer that went off
  733. Context - Actually a pointer to our ATMARP Interface structure
  734. Return Value:
  735. None
  736. --*/
  737. {
  738. PATMARP_INTERFACE pInterface;
  739. ULONG rc;
  740. pInterface = (PATMARP_INTERFACE)Context;
  741. AA_STRUCT_ASSERT(pInterface, aai);
  742. AADEBUGP(AAD_INFO, ("MARS Registration timeout: pIf 0x%x, IF Flags 0x%x\n",
  743. pInterface, pInterface->Flags));
  744. AA_ACQUIRE_IF_LOCK(pInterface);
  745. rc = AtmArpDereferenceInterface(pInterface); // Timer ref
  746. //
  747. // Continue only if the Interface is still alive
  748. //
  749. if (rc != 0)
  750. {
  751. if (pInterface->AdminState == IF_STATUS_UP)
  752. {
  753. if (pInterface->McRetriesLeft != 0)
  754. {
  755. pInterface->McRetriesLeft--;
  756. AAMC_SET_IF_STATE(pInterface, AAMC_IF_STATE_NOT_REGISTERED);
  757. AtmArpMcStartRegistration(pInterface);
  758. //
  759. // IF Lock is released within the above.
  760. //
  761. }
  762. else
  763. {
  764. //
  765. // Out of retries: problems with this MARS
  766. //
  767. AA_RELEASE_IF_LOCK(pInterface);
  768. AtmArpMcHandleMARSFailure(pInterface, TRUE);
  769. }
  770. }
  771. else
  772. {
  773. AA_RELEASE_IF_LOCK(pInterface);
  774. }
  775. }
  776. }
  777. VOID
  778. AtmArpMcMARSReconnectTimeout(
  779. IN PATMARP_TIMER pTimer,
  780. IN PVOID Context
  781. )
  782. /*++
  783. Routine Description:
  784. This is the end of a delay before we retry registering with MARS.
  785. Arguments:
  786. pTimer - Pointer to timer that went off
  787. Context - Actually a pointer to our Interface structure
  788. Return Value:
  789. None
  790. --*/
  791. {
  792. PATMARP_INTERFACE pInterface;
  793. ULONG rc;
  794. pInterface = (PATMARP_INTERFACE)Context;
  795. AA_STRUCT_ASSERT(pInterface, aai);
  796. AA_ACQUIRE_IF_LOCK(pInterface);
  797. rc = AtmArpDereferenceInterface(pInterface); // MARS Reconnect timer deref
  798. if (rc != 0)
  799. {
  800. if (pInterface->AdminState == IF_STATUS_UP)
  801. {
  802. AAMCDEBUGP(AAD_INFO, ("MARS Reconnect timeout: pIf 0x%x, Flags 0x%x\n",
  803. pInterface, pInterface->Flags));
  804. AAMC_SET_IF_STATE(pInterface, AAMC_IF_STATE_NOT_REGISTERED);
  805. AA_SET_FLAG(pInterface->Flags,
  806. AAMC_IF_MARS_FAILURE_MASK,
  807. AAMC_IF_MARS_FAILURE_NONE);
  808. AtmArpMcStartRegistration(pInterface);
  809. //
  810. // IF Lock is released within the above.
  811. //
  812. }
  813. else
  814. {
  815. AA_RELEASE_IF_LOCK(pInterface);
  816. }
  817. }
  818. //
  819. // else the IF is gone.
  820. //
  821. }
  822. VOID
  823. AtmArpMcMARSKeepAliveTimeout(
  824. IN PATMARP_TIMER pTimer,
  825. IN PVOID Context
  826. )
  827. /*++
  828. Routine Description:
  829. This is called if "MARSKeepAliveTimeout" seconds have passed since
  830. we last received a MARS_REDIRECT message.
  831. Arguments:
  832. pTimer - Pointer to timer that went off
  833. Context - Actually a pointer to our Interface structure
  834. Return Value:
  835. None
  836. --*/
  837. {
  838. PATMARP_INTERFACE pInterface;
  839. ULONG rc;
  840. pInterface = (PATMARP_INTERFACE)Context;
  841. AA_STRUCT_ASSERT(pInterface, aai);
  842. AA_ACQUIRE_IF_LOCK(pInterface);
  843. rc = AtmArpDereferenceInterface(pInterface); // MARS Keepalive timer deref
  844. if (rc != 0)
  845. {
  846. if (pInterface->AdminState == IF_STATUS_UP)
  847. {
  848. AAMCDEBUGP(AAD_INFO, ("MARS Keepalive timeout: pIf 0x%x, Flags 0x%x\n",
  849. pInterface, pInterface->Flags));
  850. AA_RELEASE_IF_LOCK(pInterface);
  851. AtmArpMcHandleMARSFailure(pInterface, FALSE);
  852. }
  853. else
  854. {
  855. AA_RELEASE_IF_LOCK(pInterface);
  856. }
  857. }
  858. }
  859. VOID
  860. AtmArpMcJoinOrLeaveTimeout(
  861. IN PATMARP_TIMER pTimer,
  862. IN PVOID Context
  863. )
  864. /*++
  865. Routine Description:
  866. We timed out waiting for an acknowledgement for a MARS_JOIN/MARS_LEAVE.
  867. If we have retries left for this JOIN/LEAVE, resend the JOIN. Otherwise,
  868. declare a MARS failure.
  869. Arguments:
  870. pTimer - Pointer to timer that went off
  871. Context - Actually a pointer to our JOIN Entry structure
  872. Return Value:
  873. None
  874. --*/
  875. {
  876. PATMARP_IPMC_JOIN_ENTRY pJoinEntry;
  877. PATMARP_INTERFACE pInterface;
  878. PIP_ADDRESS pIpAddress;
  879. IP_MASK IpMask;
  880. USHORT OpType;
  881. pJoinEntry = (PATMARP_IPMC_JOIN_ENTRY)Context;
  882. AA_STRUCT_ASSERT(pJoinEntry, aamj);
  883. pInterface = pJoinEntry->pInterface;
  884. AAMCDEBUGP(AAD_VERY_LOUD,
  885. ("McJoinTimeout: pJoinEntry 0x%x, RetriesLeft %d, IP Addr: %d.%d.%d.%d\n",
  886. pJoinEntry,
  887. pJoinEntry->RetriesLeft,
  888. ((PUCHAR)&(pJoinEntry->IPAddress))[0],
  889. ((PUCHAR)&(pJoinEntry->IPAddress))[1],
  890. ((PUCHAR)&(pJoinEntry->IPAddress))[2],
  891. ((PUCHAR)&(pJoinEntry->IPAddress))[3]));
  892. AA_ACQUIRE_IF_LOCK(pInterface);
  893. if (pInterface->AdminState == IF_STATUS_UP)
  894. {
  895. pJoinEntry->RetriesLeft--;
  896. if (pJoinEntry->RetriesLeft != 0)
  897. {
  898. pIpAddress = &(pJoinEntry->IPAddress);
  899. IpMask = pJoinEntry->Mask;
  900. if (AA_IS_FLAG_SET(pJoinEntry->Flags,
  901. AA_IPMC_JE_STATE_MASK,
  902. AA_IPMC_JE_STATE_LEAVING))
  903. {
  904. OpType = AA_MARS_OP_TYPE_LEAVE;
  905. }
  906. else
  907. {
  908. OpType = AA_MARS_OP_TYPE_JOIN;
  909. //
  910. // State could've been "pending"
  911. //
  912. AA_SET_FLAG(pJoinEntry->Flags,
  913. AA_IPMC_JE_STATE_MASK,
  914. AA_IPMC_JE_STATE_JOINING);
  915. }
  916. //
  917. // Restart the "Wait For Join completion" timer.
  918. //
  919. AtmArpStartTimer(
  920. pInterface,
  921. &(pJoinEntry->Timer),
  922. AtmArpMcJoinOrLeaveTimeout,
  923. pInterface->JoinTimeout,
  924. (PVOID)pJoinEntry
  925. );
  926. //
  927. // Resend the Join or Leave
  928. //
  929. AAMCDEBUGP(AAD_INFO,
  930. ("Resending Join/Leave: pIf 0x%x, pJoinEntry 0x%x, Addr: %d.%d.%d.%d\n",
  931. pInterface,
  932. pJoinEntry,
  933. ((PUCHAR)pIpAddress)[0],
  934. ((PUCHAR)pIpAddress)[1],
  935. ((PUCHAR)pIpAddress)[2],
  936. ((PUCHAR)pIpAddress)[3]));
  937. AtmArpMcSendJoinOrLeave(
  938. pInterface,
  939. OpType,
  940. pIpAddress,
  941. IpMask
  942. );
  943. //
  944. // IF Lock is released within the above.
  945. //
  946. }
  947. else
  948. {
  949. //
  950. // Out of retries: problems with this MARS.
  951. //
  952. AA_RELEASE_IF_LOCK(pInterface);
  953. AtmArpMcHandleMARSFailure(pInterface, FALSE);
  954. }
  955. }
  956. else
  957. {
  958. AA_RELEASE_IF_LOCK(pInterface);
  959. }
  960. }
  961. VOID
  962. AtmArpMcRevalidationDelayTimeout(
  963. IN PATMARP_TIMER pTimer,
  964. IN PVOID Context
  965. )
  966. /*++
  967. Routine Description:
  968. It's time to mark an IP Entry representing a Multicast group as
  969. needing revalidation.
  970. Arguments:
  971. pTimer - Pointer to timer that went off
  972. Context - Actually a pointer to our IP Entry structure
  973. Return Value:
  974. None
  975. --*/
  976. {
  977. PATMARP_IP_ENTRY pIpEntry;
  978. PATMARP_INTERFACE pInterface;
  979. ULONG rc;
  980. PNDIS_PACKET PacketList;
  981. pIpEntry = (PATMARP_IP_ENTRY)Context;
  982. AA_STRUCT_ASSERT(pIpEntry, aip);
  983. PacketList = NULL;
  984. AA_ACQUIRE_IE_LOCK(pIpEntry);
  985. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  986. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer ref
  987. //
  988. // Continue only if the entry hasn't gone away.
  989. //
  990. if (rc != 0)
  991. {
  992. //
  993. // Remove any packets queued on this IP Entry.
  994. //
  995. PacketList = pIpEntry->PacketList;
  996. pIpEntry->PacketList = (PNDIS_PACKET)NULL;
  997. //
  998. // Continue only if the state is OK.
  999. //
  1000. pInterface = pIpEntry->pInterface;
  1001. if (pInterface->AdminState == IF_STATUS_UP)
  1002. {
  1003. AAMCDEBUGP(AAD_LOUD,
  1004. ("Marking Revalidate: pIpEntry 0x%x/0x%x, pAtmEntry 0x%x, Addr: %d.%d.%d.%d\n",
  1005. pIpEntry,
  1006. pIpEntry->Flags,
  1007. pIpEntry->pAtmEntry,
  1008. ((PUCHAR)&(pIpEntry->IPAddress))[0],
  1009. ((PUCHAR)&(pIpEntry->IPAddress))[1],
  1010. ((PUCHAR)&(pIpEntry->IPAddress))[2],
  1011. ((PUCHAR)&(pIpEntry->IPAddress))[3]));
  1012. AA_SET_FLAG(pIpEntry->Flags,
  1013. AA_IP_ENTRY_MC_VALIDATE_MASK,
  1014. AA_IP_ENTRY_MC_REVALIDATE);
  1015. }
  1016. AA_RELEASE_IE_LOCK(pIpEntry);
  1017. }
  1018. //
  1019. // else the IP Entry is gone.
  1020. //
  1021. if (PacketList != NULL)
  1022. {
  1023. //
  1024. // Free all packets that were queued on the IP Entry.
  1025. //
  1026. AtmArpFreeSendPackets(
  1027. pInterface,
  1028. PacketList,
  1029. FALSE // No LLC/SNAP header on these
  1030. );
  1031. }
  1032. }
  1033. VOID
  1034. AtmArpMcPartyRetryDelayTimeout(
  1035. IN PATMARP_TIMER pTimer,
  1036. IN PVOID Context
  1037. )
  1038. /*++
  1039. Routine Description:
  1040. End of a delay after failing to connect or add-party a member of
  1041. a multicast group. Unmark this member, and attempt to add it.
  1042. Arguments:
  1043. pTimer - Pointer to timer that went off
  1044. Context - Actually a pointer to our MC ATM Entry structure
  1045. Return Value:
  1046. None
  1047. --*/
  1048. {
  1049. PATMARP_IPMC_ATM_ENTRY pMcAtmEntry;
  1050. PATMARP_IPMC_ATM_ENTRY * ppMcAtmEntry;
  1051. PATMARP_ATM_ENTRY pAtmEntry;
  1052. PATMARP_IP_ENTRY pIpEntry;
  1053. pMcAtmEntry = (PATMARP_IPMC_ATM_ENTRY)Context;
  1054. AA_STRUCT_ASSERT(pMcAtmEntry, ame);
  1055. pAtmEntry = pMcAtmEntry->pAtmEntry;
  1056. AA_STRUCT_ASSERT(pAtmEntry, aae);
  1057. AAMCDEBUGP(AAD_LOUD,
  1058. ("PartyRetryDelay timeout: pMcAtmEntry 0x%x, pAtmEntry 0x%x\n",
  1059. pMcAtmEntry, pAtmEntry));
  1060. AA_ACQUIRE_AE_LOCK(pAtmEntry);
  1061. AA_ASSERT(pAtmEntry->pIpEntryList != NULL_PATMARP_IP_ENTRY);
  1062. if (pAtmEntry->pInterface->AdminState == IF_STATUS_UP)
  1063. {
  1064. AA_SET_FLAG(pMcAtmEntry->Flags,
  1065. AA_IPMC_AE_CONN_STATE_MASK,
  1066. AA_IPMC_AE_CONN_DISCONNECTED);
  1067. //
  1068. // Move this MC ATM Entry to the top of the list it belongs to.
  1069. //
  1070. // Find the predecessor for this MC ATM Entry:
  1071. //
  1072. for (ppMcAtmEntry = &(pAtmEntry->pMcAtmInfo->pMcAtmEntryList);
  1073. *ppMcAtmEntry != pMcAtmEntry;
  1074. ppMcAtmEntry = &((*ppMcAtmEntry)->pNextMcAtmEntry))
  1075. {
  1076. AA_ASSERT(*ppMcAtmEntry != NULL_PATMARP_IPMC_ATM_ENTRY);
  1077. }
  1078. //
  1079. // Unlink the MC ATM Entry from its current position
  1080. //
  1081. *ppMcAtmEntry = pMcAtmEntry->pNextMcAtmEntry;
  1082. //
  1083. // And insert at the top of the list.
  1084. //
  1085. pMcAtmEntry->pNextMcAtmEntry = pAtmEntry->pMcAtmInfo->pMcAtmEntryList;
  1086. pAtmEntry->pMcAtmInfo->pMcAtmEntryList = pMcAtmEntry;
  1087. AtmArpMcUpdateConnection(pAtmEntry);
  1088. //
  1089. // AE Lock is released within the above.
  1090. //
  1091. }
  1092. else
  1093. {
  1094. AA_RELEASE_AE_LOCK(pAtmEntry);
  1095. }
  1096. }
  1097. #endif // IPMCAST